unit kasmarun;
interface
uses VenomGFX,Objects;

type BMP_header = packed record
{00}         magic:word;
{02}         sizebmp:longint;
{06}         reserved:longint;
{10}         offset_to_data:longint;
{14}         header_size:longint;
{18}         width:longint;
{22}         height:longint;
{26}         numplanes:word;
{28}         bits_per_pixel:word;
{30}         compressed:longint;
{34}         sizeimage:longint;
{38}         xres:longint;
{42}         yres:longint;
{46}         clrused:longint;
{50}         clrimportant:longint;
             end;

Function LoadBMPheader(s:string;var pal:pBGRApalette;var header:BMP_header;var h:PStream):byte;
Procedure LoadBMPlines(var h:PStream;pal:pBGRApalette;buf:pointer;var header:BMP_header;var w:virtualwindow;var precteno:longint);

implementation
Procedure LoadBMPlines(var h:PStream;pal:pBGRApalette;buf:pointer;var header:BMP_header;var w:virtualwindow;var precteno:longint);
var p,i,x,y:longint;
    cil:PByte;
begin
cil:=pointer(w.vwoffset);
inc(cil,w.bytebreite*(w.hoehe-1)); {levy dolni roh}
p:=header.width*header.bits_per_pixel div 8+header.xres;
precteno:=0;
if pal<>nil then  {8 bitove BMP s paletou}
   begin
   for i:=1 to w.hoehe do
       begin        {8 bitove BMP}
       h^.Read(buf^,p);              {ze souboru nactu radku}
       if h^.GetPos>=h^.GetSize then Exit;
       if h^.ErrorInfo<>0 then Exit;
       inc(precteno);
       x:=header.width;
       asm
           mov esi,buf
           mov ebx,pal
           mov edi,cil
       @cykl:
           movzx eax,byte [esi];
           inc esi
           shl eax,2
           movzx edx,byte [ebx+eax]
           inc eax
           movzx ecx,byte [ebx+eax]
           shl ecx,5
           or edx,ecx
           inc eax
           movzx ecx,byte [ebx+eax]
           shl ecx,11
           or edx,ecx
           mov [edi],dx;
           add edi,2
           dec x
           jnz @cykl
       end;
       dec(cil,w.bytebreite);  {BMP jsou totiz ukladane zespodu nahoru}
       end;
   end
   else
   begin

   for i:=1 to w.hoehe do
    begin           {24 bitove BMP}
    h^.Read(buf^,p);
    if h^.ErrorInfo<>0 then Exit;
    inc(precteno);
    x:=header.width;
        asm
        mov ecx,x
        mov esi,buf
        mov edi,cil
    @cykl:
        mov al,[esi]
        shr al,3
        movzx bx,al
        inc esi
        movzx ax, byte [esi]
        shr ax,2
        shl ax,5
        add bx,ax
        inc esi
        movzx ax, byte [esi]
        shr ax,3
        shl ax,11
        add bx,ax
        inc esi
        mov [edi],bx
        add edi,2
        loop @cykl
        end;
    end;
    end;
end;

Function LoadBMPheader(s:string;var pal:pBGRApalette;var header:BMP_header;var h:PStream):byte;
var p,y,d:longint;
begin
h:=New(PBufStream,Init(s,stOpenRead,30000));
h^.read(header,sizeof(header));
if (header.magic<>$4d42) or (header.compressed<>0) or (not (header.bits_per_pixel in [8,24])) then
   Exit(1);

if header.bits_per_pixel=8 then
   begin
   New(pal);
   h^.read(pal^,256*4);
   for y:=0 to 255 do
       begin
       pal^[y].r:=pal^[y].r shr 3;
       pal^[y].g:=pal^[y].g shr 2;
       pal^[y].b:=pal^[y].b shr 3;
       end;
   d:=(header.width mod 4);
   if d<>0 then d:=4-d;
   header.xres:=d;    {pomocnou promennou D budu potrebovat v nacitaci radku}
   end
   else begin
   if header.bits_per_pixel<>24 then Exit(2);
   pal:=nil;
   d:=(header.width mod 4);
   header.xres:=d;
   end;
h^.seek(header.offset_to_data);
LoadBMPheader:=0;
end;


end.
