; Images 1.1.3 object file
; by Thomas Lack¢, http://togye.host.sk
IDEAL
MODEL LARGE,PASCAL
P486

DATASEG

  extrn Buf:dword,Pal:dword
  extrn RGB:proc,PutNextPixel:dword
  extrn OutputPixel:dword,ExtractNextPixel:dword

CODESEG

macro lodsb_es
  db 26h
  lodsb
endm

macro lodsw_es
  db 26h
  lodsw
endm

macro lodsd_es
  db 26h
  lodsd
endm

; ***** GENERAL *****
public NColors
public DrawMappedPixel8,DrawMappedPixel16,ExtractMappedPixel
public DrawRGBPixel8,DrawRGBPixel16,ExtractRGBPixel

proc NColors near B:byte ; function:Word
  xor  ax,ax
  mov  cl,[B]
  cmp  cl,0
  je   @@exit
  cmp  cl,8
  ja   @@exit
  inc  ax
  shl  ax,cl
@@exit:
  ret
endp

proc DrawMappedPixel8 ; AL ® color index
  push ax
  call [PutNextPixel]
  ret
endp

proc DrawMappedPixel16 ; AL ® color index
  les  di,[Pal]
  mov  ah,0
  add  di,ax
  add  di,ax
  add  di,ax
  push [word ptr es:di] [word ptr es:di+1] [word ptr es:di+2]
  call RGB
  push ax
  call [PutNextPixel]
  ret
endp

proc ExtractMappedPixel ; AL ® color index
  mov  ah,0
  push 0 ax
  call [ExtractNextPixel]
  ret
endp

proc DrawRGBPixel8 ; DL:AX ® RGB triplet
  and  ax,0E0E0h
  shr  dl,6
  or   al,dl
  shr  ah,3
  or   al,ah
  push ax
  call [PutNextPixel]
  ret
endp

proc DrawRGBPixel16 ; DL:AX ® RGB triplet
  push ax
  xchg ah,al
  push ax dx
  call RGB
  push ax
  call [PutNextPixel]
  ret
endp

proc ExtractRGBPixel ; DL:AX ® RGB triplet
  mov  dh,0
  push dx ax
  call [ExtractNextPixel]
  ret
endp

; ***** BMP *****
public Put1bitBmpLine,Put4bitBmpLine,Put8bitBmpLine,Put24bitBmpLine

proc Put1bit ; EAX ® data, CX ® number of 1-bit pixels
  shl  eax,1
  push cx eax
  setc al
  call [OutputPixel]
  pop  eax cx
  loop Put1bit
  ret
endp

proc Put1bitBmpLine Ofs,W
local q
  les  si,[Buf]
  add  si,[Ofs]
  mov  ax,[W]
  shr  ax,5
  jz   @@rest
  mov  [q],ax
@@nextbyte:
  lodsd_es
  bswap eax
  push es si
  mov  cx,32
  call Put1bit
  pop  si es
  dec  [q]
  jnz  @@nextbyte
@@rest:
  lodsd_es
  bswap eax
  mov  cx,[W]
  and  cx,31
  jz   @@exit
  call Put1bit
@@exit:
  ret
endp

proc Put4bit ; EAX ® data, CX ® number of 4-bit pixels
  push cx eax
  shr  eax,28
  and  al,15
  call [OutputPixel]
  pop  eax cx
  shl  eax,4
  loop Put4bit
  ret
endp

proc Put4bitBmpLine Ofs,W
local q
  les  si,[Buf]
  add  si,[Ofs]
  mov  ax,[W]
  shr  ax,3
  jz   @@rest
  mov  [q],ax
@@nextbyte:
  lodsd_es
  bswap eax
  push es si
  mov  cx,8
  call Put4bit
  pop  si es
  dec  [q]
  jnz  @@nextbyte
@@rest:
  lodsd_es
  bswap eax
  mov  cx,[W]
  and  cx,7
  jz   @@exit
  call Put4bit
@@exit:
  ret
endp

proc Put8bitBmpLine Ofs,W
  les  si,[Buf]
  add  si,[Ofs]
@@nextbyte:
  lodsb_es
  push es si
  call [OutputPixel]
  pop  si es
  dec  [W]
  jnz  @@nextbyte
  ret
endp

proc Put24bitBmpLine Ofs,W
  les  si,[Buf]
  add  si,[Ofs]
@@nextbyte:
  mov  dl,[es:si]
  inc  si
  mov  ah,[es:si]
  inc  si
  lodsb_es
  push es si
  call [OutputPixel]
  pop  si es
  dec  [W]
  jnz  @@nextbyte
  ret
endp

; ***** GIF *****
public AddCode,OutputLastByte,OutputCode

proc AddCode near Code,OC,EOIC,vLI:dword,vCS:dword,vCT:dword ; function:Boolean
  les  si,[vLI]
  inc  [word ptr es:si]
  mov  di,[es:si]
  shl  di,1
  add  di,[es:si]
  les  bx,[vCT]
  mov  ax,[OC]
  mov  [es:bx+di],ax
  mov  ax,[Code]
  call near First
  jc   @@error
  mov  [es:bx+di+2],al
  ; if LI<>1 shl CS-1 then Exit
  les  si,[vCS]
  mov  cl,[es:si]
  mov  ax,1
  shl  ax,cl
  dec  ax
  les  di,[vLI]
  cmp  [es:di],ax
  jne  @@exit
  ; if CS<12 then Inc(CS)
  cmp  cl,12
  jae  @@exit
  les  di,[vCS]
  inc  [word ptr es:di]
@@exit:
  mov  al,1 ;True
  ret
@@error:
  mov  al,0 ;False
  ret
endp

proc First near ; params: AddCode
           ; AX ® code, ES:BX ®¯ @CT, AL ¯ first char, CF ¯ error, rest.DI
  mov  cx,4095-256
@@code:
  cmp  ax,[EOIC]
  jna  @@reached
  mov  si,bx
  add  si,ax
  shl  ax,1
  add  si,ax
  lodsw_es
  loop @@code
  stc
  ret
@@reached:
  clc
  ret
endp

proc OutputLastByte near Code,vCT:dword
  les  si,[vCT]
  mov  ax,[Code]
  add  si,ax
  inc  ax
  shl  ax,1
  add  si,ax
  lodsb_es ; CT[Code].B
  call [OutputPixel]
  ret
endp

proc OutputCode near Code,EOIC,vCT:dword
  les  bx,[vCT]
  mov  ax,[Code]
  call near OutCode
  ret
endp

proc OutCode near ; params: OutputCode ; AX ® code, ES:BX ® [vCT]
  mov  si,ax
  shl  si,1
  add  si,ax
  cmp  ax,[EOIC]
  jna  @@put
  mov  ax,[es:bx+si]
  push si
  call OutCode
  pop  si
  les  bx,[vCT]
@@put:
  mov  al,[es:bx+si+2]
  call [OutputPixel]
  ret
endp

; ***** TIFF *****
public SameW,SameL

proc SameW ; x:word ; function:Word
  mov  bx,sp
  mov  ax,[ss:bx+4]
  ret
endp

proc SameL ; x:dword ; function:Longint
  mov  bx,sp
  mov  ax,[word ptr ss:bx+4]
  mov  dx,[word ptr ss:bx+6]
  ret
endp

; ***** PCX *****
public Put24bitPcxLine

proc Put24bitPcxLine S,W
  les  bx,[Buf]
  mov  si,[S]
  mov  di,si
  shl  di,1
@@nextbyte:
  push si di
  mov  al,[es:bx]
  mov  ah,[es:bx+si]
  mov  dl,[es:bx+di]
  inc  bx
  push es bx
  call [OutputPixel]
  pop  bx es di si
  dec  [W]
  jnz  @@nextbyte
  ret
endp

END