{
    PixelGraphicScaling содержит классы для создания алгоритмов масштабирования
    растровой графики.
    Этот исходный текст является частью Малик Эмулятора.

    Copyright © 2016–2017, 2019–2022 Малик Разработчик

    Малик Эмулятор – свободная программа: вы можете перераспространять её и/или
    изменять её на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Малик Эмулятор распространяется в надежде, что он может быть полезен,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <http://www.gnu.org/licenses/>.
}

unit PixelGraphicScaling;

{$MODE DELPHI}

interface

uses
    Lang;

{%region public }
const
    PIXEL_GRAPHIC_SCALING_ALGORITHM_GUID = '{74C86B60-AC5B-4E8D-8ACD-29A50B5C1513}';

type
    PixelGraphicScalingAlgorithm = interface(_Interface) [PIXEL_GRAPHIC_SCALING_ALGORITHM_GUID]
        procedure setSource(pixels: PIntArray; width, height, scanline: int);
        procedure scale2x(destination: PIntArray; scanline: int; turned: boolean);
        procedure scale3x(destination: PIntArray; scanline: int; turned: boolean);
        procedure scale4x(destination: PIntArray; scanline: int; turned: boolean);
        function getSourceWidth(): int;
        function getSourceHeight(): int;
    end;
{%endregion}

{%region routine }
    function transformTo32bit(pixel16bit: int): int; inline;
    procedure transformTo16bit(pixels32bit: PIntArray; width, height, scanline: int; const pixels16bit: short_Array1d);
{%endregion}

implementation

{%region private }
var
    RGB16TO32: int_Array1d;
{%endregion}

{%region routine }
    procedure init();
    var
        i: int;
    begin
        RGB16TO32 := int_Array1d_create($10000);
        for i := 0 to length(RGB16TO32) - 1 do begin
            RGB16TO32[i] := int($ff000000) or ((i and $f800) shl 8) or ((i and $07e0) shl 5) or ((i and $001f) shl 3);
        end;
    end;

    function make16bitPixel(pixel: int): short; inline;
    begin
        result := short(((pixel shr 8) and $f800) or ((pixel shr 5) and $07e0) or ((pixel shr 3) and $001f));
    end;

    function transformTo32bit(pixel16bit: int): int; inline;
    begin
        result := RGB16TO32[pixel16bit and $0000ffff];
    end;

    procedure transformTo16bit(pixels32bit: PIntArray; width, height, scanline: int; const pixels16bit: short_Array1d);
    var
        line: int;
        i: int;
        j: int;
        k: int;
        l: int;
    begin
        line := 0;
        k := 0;
        for j := 0 to height - 1 do begin
            l := line;
            for i := 0 to width - 1 do begin
                pixels16bit[k] := make16bitPixel(pixels32bit[l]);
                inc(k);
                inc(l);
            end;
            inc(line, scanline);
        end;
    end;
{%endregion}

initialization {%region}
    init();
{%endregion}

end.

