Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1078 → Rev 1079

/programs/develop/libraries/libs-dev/libimg/bmp/bmp.asm
102,8 → 102,7
jnz .error
; convert images with <= 8 bpp to 8bpp, other - to 32 bpp
.normal:
xor eax, eax
inc eax ; Image.bpp8
m2m eax, Image.bpp8
cmp [ebx + bmp.Header.info.BitCount], 8
jbe @f
mov al, Image.bpp32
119,8 → 118,7
pushd [ebx + bmp.Header.info.Width]
jmp .create
.old1:
xor eax, eax
inc eax ; Image.bpp8
m2m eax, Image.bpp8
cmp [ebx + bmp.Header.info.OldBitCount], 8
jbe @f
mov al, Image.bpp32
/programs/develop/libraries/libs-dev/libimg/gif/gif.asm
51,7 → 51,7
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
cmp [_length], 6
cmp [_length], sizeof.gif.Header
jb .nope
mov eax, [_data]
cmp dword[eax], 'GIF8'
82,37 → 82,100
;< eax = 0 (error) or pointer to image ;;
;;================================================================================================;;
locals
max_color dd ?
cur_color_table_size dd ?
transparent_color dd ?
background_color dd ?
prev_palette dd ?
aux_palette dd ?
img dd ?
prev_img_data dd ?
aux_img_data dd ?
aux_img_type dd ?
prev_num_colors dd ?
main_img dd ?
global_color_table dd ?
global_color_table_size dd ?
endl
 
push ebx
img.decode.gif.main_img equ main_img
img.decode.gif.prev_img_data equ prev_img_data
img.decode.gif.transparent_color equ transparent_color
img.decode.gif.background_color equ background_color
img.decode.gif._length equ _length
img.decode.gif.prev_num_colors equ prev_num_colors
img.decode.gif.prev_palette equ prev_palette
img.decode.gif.max_color equ max_color
img.decode.gif._data equ _data
img.decode.gif.aux_img_data equ aux_img_data
img.decode.gif.aux_img_type equ aux_img_type
img.decode.gif.aux_palette equ aux_palette
; offset of _length parameter for child functions with ebp-based frame
; child saved ebp, return address, 3 saved registers, 14 local variables
img.decode.gif._length_child equ _length + 4 + 4 + 4*3 + 4*14
img.decode.gif.max_color_child equ ebp + 4 + 4 + 4*3
img.decode.gif.cur_color_table_size_child equ ebp + 4 + 4 + 4*3 + 4
 
push ebx esi edi
xor eax, eax
mov [img], eax
mov [main_img], eax
mov [prev_img_data], eax
mov [aux_img_data], eax
mov [aux_img_type], eax
mov [prev_palette], eax
mov [aux_palette], eax
; when no previous image is available, use background fill with 1-entry palette
inc eax
mov [prev_num_colors], eax
lea eax, [background_color]
mov [prev_palette], eax
; guard against incorrect gif files, which use Restore-To-Background disposal method, but do not define bgr color
mov dword [eax], 0xFFFFFF
; guard against incorrect gif files without any color tables
; "If no color table is available at
; all, the decoder is free to use a system color table or a table of its own. In
; that case, the decoder may use a color table with as many colors as its
; hardware is able to support; it is recommended that such a table have black and
; white as its first two entries, so that monochrome images can be rendered
; adequately." (c) official gif documentation
mov [global_color_table], gif_default_palette
mov [global_color_table_size], 2
 
; img.is.gif is called by caller (img.decode)
; stdcall img.is.gif, [_data], [_length]
; or eax, eax
; jz .error
 
mov [global_color_table_size], 0
mov ebx, [_data]
sub [_length], sizeof.gif.Header
 
test [ebx + gif.Header.lsd.Packed], gif.LSD.Packed.GlobalColorTableFlag
jz @f
lea eax, [ebx + sizeof.gif.Header]
mov [global_color_table], eax
mov cl, [ebx + gif.Header.lsd.Packed]
add ebx, sizeof.gif.Header
; gif.LSD.Packed.GlobalColorTableFlag = 80h
; test cl, gif.LSD.Packed.GlobalColorTableFlag
; jz @f
test cl, cl
jns @f
mov [global_color_table], ebx
and cl, gif.LSD.Packed.SizeOfGlobalColorTableMask
shr cl, gif.LSD.Packed.SizeOfGlobalColorTableShift
mov eax, 2
; shr cl, gif.LSD.Packed.SizeOfGlobalColorTableShift ; here Shift = 0
push 2
pop eax
shl eax, cl
mov [global_color_table_size], eax
lea eax, [eax * 3]
sub [_length], eax
jbe .error ; there must be at least 1 additional byte after color table
movzx ecx, byte [ebx - sizeof.gif.Header + gif.Header.lsd.BackgroundColor]
lea ecx, [ecx*3]
mov ecx, [ebx + ecx] ; eax = xxBBGGRR, convert to Kolibri color
bswap ecx
shr ecx, 8
mov [background_color], ecx
add ebx, eax
@@: add ebx, sizeof.gif.Header
@@:
 
mov [img], 0
 
; @@: cmp byte[ebx + gif.Block.Introducer], gif.Block.Introducer.Extension
; jne .next_image
; cmp byte[ebx + gif.Extension.Label], gif.Extension.Label.Comment
128,26 → 191,45
jz .error
mov edx, [img]
mov [eax + Image.Previous], edx
push sizeof.gif.LogicalScreenDescriptor
pop ecx
test edx, edx
jz @f
mov [edx + Image.Next], eax
xor ecx, ecx
@@:
mov [img], eax
mov edx, eax
push eax
mov [eax + Image.Type], Image.bpp8
 
invoke mem.alloc, sizeof.gif.Image
add ecx, sizeof.gif.Image
invoke mem.alloc, ecx
pop edx
or eax, eax
jz .error
jz .error2
mov [edx + Image.Extended], eax
xor ecx, ecx
cmp [img], ecx
jnz @f
mov esi, [_data]
add esi, gif.Header.lsd
lea edi, [eax + sizeof.gif.Image]
mov cl, sizeof.gif.LogicalScreenDescriptor
rep movsb
mov [main_img], edx
@@:
mov [img], edx
 
stdcall ._.process_extensions
 
cmp byte[ebx + gif.Block.Introducer], gif.Block.Introducer.ImageDescriptor
cmp al, gif.Block.Introducer.ImageDescriptor
jne .error
sub [_length], sizeof.gif.ImageDescriptor
jc .error
movzx eax, [ebx + gif.ImageDescriptor.Width]
movzx ecx, [ebx + gif.ImageDescriptor.Height]
push edx
stdcall img._.resize_data, [img], eax, ecx
pop edx
or eax, eax
jz .error
 
164,13 → 246,20
lea esi, [ebx + sizeof.gif.ImageDescriptor]
mov cl, [ebx + gif.ImageDescriptor.Packed]
and cl, gif.ID.Packed.SizeOfLocalColorTableMask
shr cl, gif.ID.Packed.SizeOfLocalColorTableShift
mov eax, 2
; here Shift = 0
; shr cl, gif.ID.Packed.SizeOfLocalColorTableShift
push 2
pop eax
shl eax, cl
mov ecx, eax
lea eax, [eax*3]
add ebx, eax
sub [_length], eax
jbe .error ; because we load additional byte, check is 'jbe', not 'jc'
@@:
mov [cur_color_table_size], ecx
dec [cur_color_table_size]
@@:
lodsd
dec esi
bswap eax
179,24 → 268,105
loop @b
add ebx, sizeof.gif.ImageDescriptor
stdcall ._.process_image
 
.decoded:
or eax, eax
push ebx
mov edx, [img]
push edx
stdcall ._.superimpose
pop edx
push edx
stdcall ._.dispose
pop edx
mov edx, [edx + Image.Previous]
test edx, edx
jz .nofreeprev
mov ebx, [edx + Image.Extended]
cmp [ebx + gif.Image.gce.DelayTime], 0
jnz .nofreeprev
mov esi, [prev_palette]
cmp esi, [edx + Image.Palette]
jnz @f
mov ecx, [prev_num_colors]
stdcall ._.alloc_aux_palette
test eax, eax
jz .nofreeprev
mov [prev_palette], eax
@@:
mov esi, [prev_img_data]
cmp esi, [edx + Image.Data]
jnz .noprevdata
push 1
pop eax
cmp [edx + Image.Type], Image.bpp8
jz @f
stdcall img.destroy, [img]
jmp .error
mov al, 3
@@:
cmp [aux_img_type], eax
jb .resetaux
mov edi, [aux_img_data]
imul eax, [edx + Image.Width]
imul eax, [edx + Image.Height]
xchg eax, ecx
rep movsb
jmp .noprevdata
.resetaux:
mov [aux_img_type], eax
mov eax, [aux_img_data]
test eax, eax
jz @f
invoke mem.free, eax
@@:
xor eax, eax
xchg eax, [edx + Image.Data]
mov [aux_img_data], eax
.noprevdata:
cmp edx, [main_img]
jnz @f
mov eax, [edx + Image.Next]
mov [main_img], eax
mov esi, [eax + Image.Extended]
mov edi, [edx + Image.Extended]
mov [edx + Image.Extended], esi
mov [eax + Image.Extended], edi
push sizeof.gif.Image
pop ecx
rep movsb
@@:
stdcall img.destroy.layer, edx
.nofreeprev:
pop ebx
test ebx, ebx
jz .ret
jmp .next_image
@@: mov eax, [img]
ret
.error2:
mov [img], edx
 
.error:
mov eax, [img]
test eax, eax
jz .ret
cmp [main_img], eax
jnz @f
and [main_img], 0
@@:
stdcall img.destroy.layer, eax
.ret:
mov eax, [aux_img_data]
test eax, eax
jz @f
stdcall img.destroy, eax
invoke mem.free, eax
@@:
xor eax, eax
pop ebx
mov eax, [aux_palette]
test eax, eax
jz @f
invoke mem.free, eax
@@:
mov eax, [main_img]
cmp [eax + Image.Next], 0
jz @f
or [eax + Image.Flags], Image.IsAnimated
@@:
pop edi esi ebx
ret
endp
 
225,26 → 395,6
 
 
;;================================================================================================;;
proc img.decode.gif._.skip_data ;/////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
;;------------------------------------------------------------------------------------------------;;
;> ebx = pointer to data blocks array ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = pointer to data right after data blocks array ;;
;;================================================================================================;;
push ecx
xor ecx, ecx
@@: mov cl, [esi]
or cl, cl
jz @f
lea esi, [esi + ecx + 1]
jmp @b
@@: pop ecx
ret
endp
 
;;================================================================================================;;
proc img.decode.gif._.process_extensions ;////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
254,65 → 404,65
;;------------------------------------------------------------------------------------------------;;
;< --- TBD --- ;;
;;================================================================================================;;
push edx
mov esi, ebx
xor eax, eax
mov [edx + Image.Delay], eax
 
.next_block:
mov al, [esi + gif.Block.Introducer]
dec [img.decode.gif._length]
js .exit_err
lodsb ; load gif.Block.Introducer
cmp al, gif.Block.Introducer.Extension
je .ext_block
; cmp al, gif.Block.Introducer.ImageDescriptor
; je .exit
; cmp al, gif.Block.Introducer.EndOfFile
; je .exit
jmp .exit
jne .exit
 
.ext_block:
mov al, [esi + gif.Extension.Label]
cmp al, gif.Extension.Label.PlainText
je .plain_text_ext
dec [img.decode.gif._length]
js .exit_err
lodsb ; load gif.Extension.Label
cmp al, gif.Extension.Label.GraphicsControl
je .graphics_control_ext
cmp al, gif.Extension.Label.Comment
je .comment_ext
cmp al, gif.Extension.Label.Application
je .application_ext
jmp .exit
; cmp al, gif.Extension.Label.PlainText
; je .plain_text_ext
; cmp al, gif.Extension.Label.Comment
; je .comment_ext
; cmp al, gif.Extension.Label.Application
; je .application_ext
; skip all other extensions
.skip_ext:
dec [img.decode.gif._length]
js .exit_err
lodsb ; load BlockSize
.1:
test al, al
jz .next_block
sub [img.decode.gif._length], eax
jc .exit_err
add esi, eax
jmp .skip_ext
 
.plain_text_ext:
add esi, gif.PlainTextExtension.PlainTextData
stdcall img.decode.gif._.skip_data
jmp .next_ext_block
 
.graphics_control_ext:
dec [img.decode.gif._length]
js .exit_err
lodsb ; load BlockSize; must be sizeof.gif.GraphicsControlExtension
cmp al, sizeof.gif.GraphicsControlExtension
jnz .1
sub [img.decode.gif._length], eax
jc .exit_err
push edi
movzx edi, [esi + gif.GraphicsControlExtension.DelayTime]
mov [edx + Image.Delay], edi
mov edi, [edx + Image.Extended]
add edi, gif.Image.gce
mov ecx, sizeof.gif.GraphicsControlExtension
mov ecx, eax
rep movsb
pop edi
jmp .next_ext_block
jmp .skip_ext
 
.comment_ext:
add esi, gif.CommentExtension.CommentData
stdcall img.decode.gif._.skip_data
jmp .next_ext_block
.exit_err:
xor eax, eax
 
.application_ext:
add esi, gif.ApplicationExtension.ApplicationData
stdcall img.decode.gif._.skip_data
jmp .next_ext_block
 
.next_ext_block:
mov al, [esi + gif.Block.Introducer]
cmp al, gif.Block.Introducer.EndOfData
jne .exit
inc esi
jmp .next_block
 
.exit:
mov ebx, esi
pop edx
ret
endp
 
354,6 → 504,7
inc eax
mov [row_end], eax
and [pass], 0
and dword [img.decode.gif.max_color_child], 0
mov eax, [edx + Image.Extended]
test [eax + gif.Image.info.Packed], gif.ID.Packed.InterleaceFlag
jz @f
362,15 → 513,21
@@: mov esi, ebx
mov edi, [edx + Image.Data]
 
push edi
sub dword [img.decode.gif._length_child], 2
jc .error
movzx ecx, byte[esi]
inc esi
cmp cl, 12
jae .error
mov [codesize], ecx
inc [codesize]
mov edi, [workarea]
xor eax, eax
lodsb ; eax - block_count
sub [img.decode.gif._length_child], eax
jc .error
add eax, esi
push edi
mov edi, [workarea]
mov [block_ofs], eax
mov [bit_count], 8
mov eax, 1
400,19 → 557,22
.cycle:
movzx ebx, ax
call .get_symbol
cmp eax, [EOI]
je .end
cmp eax, edx
jae .notintable
ja .error
je .notintable
cmp eax, [CC]
je .reinit
cmp eax, [EOI]
je .end
call .output
.add:
cmp edx, 0x00001000
jae .cycle
mov ecx, [workarea]
mov [ecx + edx * 4], ebx
cmp edx, 0x00000FFF
jae .cycle
inc edx
cmp edx, 0x1000
je .noinc
bsr ebx, edx
cmp ebx, [compsize]
jne .noinc
436,15 → 596,26
cmp [workarea], 0
je @f
invoke mem.free, [workarea]
@@: xor eax, eax
ret
@@:
mov ebx, [block_ofs]
@@:
dec [img.decode.gif._length_child]
js @f
movzx eax, byte [ebx]
inc ebx
test eax, eax
jz .ret
sub [img.decode.gif._length_child], eax
jc @f
add ebx, eax
jmp @b
 
.error:
cmp [workarea], 0
je @f
invoke mem.free, [workarea]
@@: xor eax, eax
inc eax
@@: xor ebx, ebx
.ret:
ret
 
;;------------------------------------------------------------------------------------------------;;
455,32 → 626,35
xor eax, eax
 
.shift:
ror byte[esi], 1
rcr eax,1
dec [bit_count]
jnz .loop1
jns .loop1
inc esi
cmp esi, [block_ofs]
jb .noblock
push eax
xor eax, eax
sub [img.decode.gif._length_child], 1
jc .error_eof
lodsb
test eax, eax
jnz .nextbl
mov eax, [EOI]
sub esi, 2
add esp, 8
jmp .exit
.error_eof:
add esp, 12
jmp img.decode.gif._.process_image.error
 
.nextbl:
sub [img.decode.gif._length_child], eax
jc .error_eof
add eax, esi
mov [block_ofs], eax
pop eax
 
.noblock:
mov [bit_count], 8
mov [bit_count], 7
 
.loop1:
ror byte[esi], 1
rcr eax,1
loop .shift
pop ecx
rol eax, cl
506,8 → 680,16
 
.loop2:
pop ax
stosb
cmp al, byte [img.decode.gif.cur_color_table_size_child]
jbe @f ; guard against incorrect GIFs
mov al, 0
@@: cmp al, byte [img.decode.gif.max_color_child]
jbe @f
mov [img.decode.gif.max_color_child], al
@@: stosb
 
cmp edi, [img_end]
jz .done
cmp edi, [row_end]
jb .norowend
mov eax, [width]
546,10 → 728,849
pop edx eax esi
retn
 
.done:
lea esp, [esp+(ecx-1)*2]
pop edx eax esi eax
jmp img.decode.gif._.process_image.exit
 
endp
 
;;================================================================================================;;
proc img.decode.gif._.is_logical_screen ;/////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Determines whether GIF image occupies the whole logical screen ;;
;;------------------------------------------------------------------------------------------------;;
;> eax = extended image data ;;
;> ebx = main image ;;
;;------------------------------------------------------------------------------------------------;;
;< ZF set <=> image area equals logical screen ;;
;;================================================================================================;;
mov ebx, [ebx + Image.Extended]
cmp [eax + gif.Image.info.Left], 0
jnz @f
cmp [eax + gif.Image.info.Top], 0
jnz @f
mov cx, [eax + gif.Image.info.Width]
cmp cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
jnz @f
mov cx, [eax + gif.Image.info.Height]
cmp cx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
@@: retn
endp
 
main_img equ img.decode.gif.main_img
transparent_color equ img.decode.gif.transparent_color
background_color equ img.decode.gif.background_color
prev_num_colors equ img.decode.gif.prev_num_colors
prev_palette equ img.decode.gif.prev_palette
max_color equ img.decode.gif.max_color
prev_img_data equ img.decode.gif.prev_img_data
_data equ img.decode.gif._data
aux_img_data equ img.decode.gif.aux_img_data
aux_img_type equ img.decode.gif.aux_img_type
aux_palette equ img.decode.gif.aux_palette
 
;;================================================================================================;;
proc img.decode.gif._.superimpose ;///////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
;;------------------------------------------------------------------------------------------------;;
;> edx = image data ;;
;;------------------------------------------------------------------------------------------------;;
;< --- TBD --- ;;
;;================================================================================================;;
mov ebx, [main_img]
mov eax, [edx + Image.Extended]
or [transparent_color], -1 ; no transparent color
test byte [eax + gif.Image.gce.Packed], 1
jz @f
movzx ecx, byte [eax + gif.Image.gce.ColorIndex]
mov [transparent_color], ecx
cmp edx, ebx
jnz .has_transparency
shl ecx, 2
add ecx, [edx + Image.Palette]
mov dword [background_color], 0xFFFFFF ; white background
mov dword [ecx], 0xFFFFFF
; mov esi, [_data]
; test [esi+gif.Header.lsd.Packed], gif.LSD.Packed.GlobalColorTableFlag
; jz @f
; movzx ecx, [esi+gif.Header.lsd.BackgroundColor]
; push ecx
; shl ecx, 2
; add ecx, [edx + Image.Palette]
; mov dword [ecx], 0xFFFFFF
; pop ecx
; lea ecx, [ecx*3]
; add esi, ecx
; mov byte [esi+sizeof.gif.Header+0], 0xFF
; mov byte [esi+sizeof.gif.Header+1], 0xFF
; mov byte [esi+sizeof.gif.Header+2], 0xFF
@@:
call img.decode.gif._.is_logical_screen
jnz .has_transparency
; image is not transparent, so keep it as is
retn
 
.has_transparency:
; image has transparent areas, we must superimpose it on the previous
mov ecx, [prev_num_colors]
cmp ecx, 0x100
ja .superimpose_on_rgb
; create common palette
sub esp, 3FCh
push eax
mov edi, esp
push ecx
mov esi, [prev_palette]
rep movsd
pop ecx
mov esi, [edx + Image.Palette]
xor ebx, ebx
mov edi, esp
sub esp, 100h
.create_palette_loop:
push ecx
lodsd
cmp ebx, [transparent_color]
jz .nochange
cmp ebx, ecx
jae @f
cmp eax, [edi+ebx*4]
jz .nochange
@@:
push edi
repnz scasd
pop edi
jnz .increase_palette
sub ecx, [esp]
not ecx ; cl = index of new color in current palette
jmp .palette_common
.increase_palette:
mov ecx, [esp]
test ch, ch
jnz .output_to_rgb
inc dword [esp]
mov [edi+ecx*4], eax
jmp .palette_common
.nochange:
mov ecx, ebx
.palette_common:
mov [ebx+esp+4], cl
pop ecx
inc ebx
cmp ebx, [max_color]
jbe .create_palette_loop
mov [max_color], ecx
; if image occupies only part of logical screen, allocate memory for full logical screen
mov ebx, [main_img]
mov eax, [edx + Image.Extended]
mov esi, [edx + Image.Data]
call img.decode.gif._.is_logical_screen
jz @f
and [edx + Image.Data], 0
push edx
movzx eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
push eax
movzx eax, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
stdcall img._.resize_data, edx, eax
pop edx
test eax, eax
jz .palette_nomem
@@:
; copy final palette to Image.Palette
push esi esi
mov esi, edi
mov edi, [edx + Image.Palette]
mov ecx, [max_color]
dec [max_color]
rep movsd
mov esi, [prev_img_data]
mov edi, [edx + Image.Data]
; do superimpose, [esp] -> source data, esi -> prev image data
; (NULL if previous image is filled with background color), esp+8 -> correspondence between
; used palette and final palette, edi -> destination data
mov ebx, [edx + Image.Extended]
; first Top rows are copied from [prev_img_data] or filled with bgr
movzx ecx, [ebx + gif.Image.info.Top]
cmp ecx, [edx + Image.Height]
jb @f
mov ecx, [edx + Image.Height]
@@:
push ecx
imul ecx, [edx + Image.Width]
call .rep_movsb_or_stosb
pop ecx
; convert rows
sub ecx, [edx + Image.Height]
neg ecx
push ecx
cmp cx, [ebx + gif.Image.info.Height]
jbe @f
mov cx, [ebx + gif.Image.info.Height]
@@:
jecxz .norows
.convert_rows:
push ecx
movzx ecx, [ebx + gif.Image.info.Left]
cmp ecx, [edx + Image.Width]
jb @f
mov ecx, [edx + Image.Width]
@@:
push ecx
call .rep_movsb_or_stosb
pop ecx
sub ecx, [edx + Image.Width]
neg ecx
push ecx edx
mov edx, [esp+16] ; source data
cmp cx, [ebx + gif.Image.info.Width]
jbe @f
mov cx, [ebx + gif.Image.info.Width]
@@:
jecxz .norowsi
.rowsloop:
movzx eax, byte [edx]
inc edx
cmp eax, [transparent_color]
jz .rows_transparent
mov al, [eax+esp+24]
stosb
call .lodsb
jmp @f
.rows_transparent:
call .lodsb
stosb
@@:
loop .rowsloop
.norowsi:
pop edx ecx
sub cx, [ebx + gif.Image.info.Width]
jbe @f
call .rep_movsb_or_stosb
@@:
movzx eax, [ebx + gif.Image.info.Width]
add [esp+8], eax
pop ecx
loop .convert_rows
.norows:
pop ecx
sub cx, [ebx + gif.Image.info.Height]
jbe @f
imul ecx, [edx + Image.Width]
call .rep_movsb_or_stosb
@@:
; free old image data if we have allocated new copy
pop esi esi
cmp esi, [edx + Image.Data]
jz @f
invoke mem.free, esi
@@:
; cleanup stack and return
add esp, 500h
retn
.palette_nomem:
mov [edx + Image.Data], esi
jmp @b
 
.output_to_rgb:
pop ecx
add esp, 500h
; compose two palette-based images to one RGB image
xor esi, esi
xchg esi, [edx + Image.Data]
push esi
mov ebx, [_data]
push [edx + Image.Palette]
mov byte [edx + Image.Type], Image.bpp24
push edx
movzx eax, [ebx + gif.Header.lsd.ScreenHeight]
push eax
movzx eax, [ebx + gif.Header.lsd.ScreenWidth]
stdcall img._.resize_data, edx, eax
pop edx
test eax, eax
jz .convrgb_nomem
push esi
mov edi, [edx + Image.Data]
mov esi, [prev_img_data]
mov ebx, [edx + Image.Extended]
; first Top rows are copied from [prev_img_data] or filled with bgr
movzx ecx, [ebx + gif.Image.info.Top]
cmp ecx, [edx + Image.Height]
jb @f
mov ecx, [edx + Image.Height]
@@:
push ecx
imul ecx, [edx + Image.Width]
call .convrgb_prev
pop ecx
; convert rows
sub ecx, [edx + Image.Height]
neg ecx
push ecx
cmp cx, [ebx + gif.Image.info.Height]
jbe @f
mov cx, [ebx + gif.Image.info.Height]
@@:
jecxz .convrgb_norows
.convrgb_convert_rows:
push ecx
movzx ecx, [ebx + gif.Image.info.Left]
cmp ecx, [edx + Image.Width]
jb @f
mov ecx, [edx + Image.Width]
@@:
push ecx
call .convrgb_prev
pop ecx
sub ecx, [edx + Image.Width]
neg ecx
push ecx edx
mov edx, [esp+16] ; source data
cmp cx, [ebx + gif.Image.info.Width]
jbe @f
mov cx, [ebx + gif.Image.info.Width]
@@:
jecxz .convrgb_norowsi
.convrgb_rowsloop:
movzx eax, byte [edx]
inc edx
cmp eax, [transparent_color]
jz .convrgb_rows_transparent
shl eax, 2
add eax, [esp+20] ; source palette
mov eax, [eax]
stosw
shr eax, 16
stosb
call .convrgb_lodsb
jmp @f
.convrgb_rows_transparent:
call .convrgb_lodsb
stosw
shr eax, 16
stosb
@@:
loop .convrgb_rowsloop
.convrgb_norowsi:
pop edx ecx
sub cx, [ebx + gif.Image.info.Width]
jbe @f
call .convrgb_prev
@@:
movzx eax, [ebx + gif.Image.info.Width]
add [esp+8], eax
pop ecx
loop .convrgb_convert_rows
.convrgb_norows:
pop ecx
sub cx, [ebx + gif.Image.info.Height]
jbe @f
imul ecx, [edx + Image.Width]
call .convrgb_prev
@@:
; free old image data
pop esi esi ;esi
invoke mem.free;, esi
retn
.convrgb_nomem:
pop esi esi
retn
 
.superimpose_on_rgb:
; previous image is RGB, new image has transparent areas
xor esi, esi
xchg esi, [edx + Image.Data]
push esi
mov ebx, [_data]
push [edx + Image.Palette]
mov byte [edx + Image.Type], Image.bpp24
push edx
movzx eax, [ebx + gif.Header.lsd.ScreenHeight]
push eax
movzx eax, [ebx + gif.Header.lsd.ScreenWidth]
stdcall img._.resize_data, edx, eax
pop edx
test eax, eax
jz .rgb_nomem
push esi
mov edi, [edx + Image.Data]
mov esi, [prev_img_data]
mov ebx, [edx + Image.Extended]
; first Top rows are copied from [prev_img_data] or filled with bgr
movzx ecx, [ebx + gif.Image.info.Top]
cmp ecx, [edx + Image.Height]
jb @f
mov ecx, [edx + Image.Height]
@@:
push ecx
lea ecx, [ecx*3]
imul ecx, [edx + Image.Width]
rep movsb
pop ecx
; convert rows
sub ecx, [edx + Image.Height]
neg ecx
push ecx
cmp cx, [ebx + gif.Image.info.Height]
jbe @f
mov cx, [ebx + gif.Image.info.Height]
@@:
jecxz .rgb_norows
.rgb_convert_rows:
push ecx
movzx ecx, [ebx + gif.Image.info.Left]
cmp ecx, [edx + Image.Width]
jb @f
mov ecx, [edx + Image.Width]
@@:
push ecx
lea ecx, [ecx*3]
rep movsb
pop ecx
sub ecx, [edx + Image.Width]
neg ecx
push ecx edx
mov edx, [esp+16] ; source data
cmp cx, [ebx + gif.Image.info.Width]
jbe @f
mov cx, [ebx + gif.Image.info.Width]
@@:
jecxz .rgb_norowsi
.rgb_rowsloop:
movzx eax, byte [edx]
inc edx
cmp eax, [transparent_color]
jz .rgb_rows_transparent
shl eax, 2
add eax, [esp+20] ; source palette
mov eax, [eax]
stosw
shr eax, 16
stosb
add esi, 3
jmp @f
.rgb_rows_transparent:
movsb
movsb
movsb
@@:
loop .rgb_rowsloop
.rgb_norowsi:
pop edx ecx
sub cx, [ebx + gif.Image.info.Width]
jbe @f
lea ecx, [ecx*3]
rep movsb
@@:
movzx eax, [ebx + gif.Image.info.Width]
add [esp+8], eax
pop ecx
loop .rgb_convert_rows
.rgb_norows:
pop ecx
sub cx, [ebx + gif.Image.info.Height]
jbe @f
imul ecx, [edx + Image.Width]
lea ecx, [ecx*3]
rep movsb
@@:
; free old image data
pop esi esi ;esi
invoke mem.free;, esi
retn
.rgb_nomem:
pop esi esi
retn
 
.lodsb:
xor eax, eax
test esi, esi
jz @f
lodsb
@@: retn
 
.rep_movsb_or_stosb:
test esi, esi
jz .rmos1
rep movsb
jmp .rmos2
.rmos1: xor eax, eax ; background index in final palette is 0 in bgr mode
rep stosb
.rmos2: retn
 
.convrgb_prev:
jecxz .convrgb_noprev
test esi, esi
jz .convrgb_prev_bgr
@@:
xor eax, eax
lodsb
shl eax, 2
add eax, [prev_palette]
mov eax, [eax]
stosw
shr eax, 16
stosb
loop @b
retn
.convrgb_prev_bgr:
@@:
mov eax, [background_color]
stosw
shr eax, 16
stosb
loop @b
.convrgb_noprev:
retn
.convrgb_lodsb:
xor eax, eax
test esi, esi
jz @f
lodsb
shl eax, 2
add eax, [prev_palette]
mov eax, [eax]
retn
@@: mov eax, [background_color]
retn
 
endp
 
;;================================================================================================;;
proc img.decode.gif._.dispose ;///////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
;;------------------------------------------------------------------------------------------------;;
;> edx = image data ;;
;;------------------------------------------------------------------------------------------------;;
;< --- TBD --- ;;
;;================================================================================================;;
mov ebx, [edx + Image.Extended]
mov al, [ebx + gif.Image.gce.Packed]
shr al, 2
and al, 7
cmp al, 2
jz .background
cmp al, 3
jz .previous
; don't dispose - set prev_img and related vars to current image
mov eax, [edx + Image.Data]
mov [prev_img_data], eax
cmp [edx + Image.Type], Image.bpp8
jnz @f
mov eax, [max_color]
inc eax
mov [prev_num_colors], eax
mov eax, [edx + Image.Palette]
mov [prev_palette], eax
retn
@@:
or [prev_num_colors], -1
and [prev_palette], 0
.previous:
retn
.background:
cmp [prev_img_data], 0
jz .bgr_full
mov ebx, [main_img]
mov eax, [edx + Image.Extended]
call img.decode.gif._.is_logical_screen
jnz @f
.bgr_full:
xor eax, eax
mov [prev_img_data], eax
inc eax
mov [prev_num_colors], eax
lea eax, [background_color]
mov [prev_palette], eax
retn
@@:
cmp [prev_num_colors], 0x100
ja .rgb
mov eax, [background_color]
mov edi, [prev_palette]
mov ecx, [prev_num_colors]
repnz scasd
jz .palette_ok
cmp [prev_num_colors], 0x100
jz .convert_rgb
push 1
pop eax
stdcall img.decode.gif._.alloc_aux_img
test eax, eax
jz .previous
mov ecx, [prev_num_colors]
mov esi, [prev_palette]
call img.decode.gif._.alloc_aux_palette
test eax, eax
jz .previous
mov [prev_palette], eax
mov eax, [background_color]
stosd
mov eax, [prev_num_colors] ; eax = index of background color
inc [prev_num_colors]
jmp .bpp8_common
.palette_ok:
push 1
pop eax
stdcall img.decode.gif._.alloc_aux_img
test eax, eax
jz .previous
sub edi, [prev_palette]
shr edi, 2
lea eax, [edi-1] ; eax = index of background color
.bpp8_common:
push eax
mov ebx, [_data]
mov esi, [prev_img_data]
mov edi, [aux_img_data]
mov [prev_img_data], edi
cmp esi, edi
jz @f
movzx ecx, [ebx + gif.Header.lsd.ScreenWidth]
movzx eax, [ebx + gif.Header.lsd.ScreenHeight]
imul ecx, eax
push edi
rep movsb
pop edi
@@:
movzx esi, [ebx + gif.Header.lsd.ScreenHeight]
movzx eax, [ebx + gif.Header.lsd.ScreenWidth]
mov edx, [edx + Image.Extended]
movzx ecx, [edx + gif.Image.info.Top]
sub esi, ecx
jbe .bpp8_ret
imul ecx, eax
add edi, ecx
cmp si, [edx + gif.Image.info.Height]
jb @f
mov si, [edx + gif.Image.info.Height]
@@:
movzx ecx, [edx + gif.Image.info.Left]
sub eax, ecx
jbe .bpp8_ret
add edi, ecx
cmp ax, [edx + gif.Image.info.Width]
jb @f
mov ax, [edx + gif.Image.info.Width]
@@:
xchg eax, ecx
movzx edx, [ebx + gif.Header.lsd.ScreenWidth]
sub edx, ecx
pop eax
@@:
push ecx
rep stosb
pop ecx
add edi, edx
dec esi
jnz @b
push eax
.bpp8_ret:
pop eax
retn
.convert_rgb:
push 3
pop eax
stdcall img.decode.gif._.alloc_aux_img
test eax, eax
jz .previous
or [prev_num_colors], -1
mov ebx, [_data]
mov esi, [prev_img_data]
mov edi, [aux_img_data]
mov [prev_img_data], edi
movzx ecx, [ebx + gif.Header.lsd.ScreenWidth]
movzx eax, [ebx + gif.Header.lsd.ScreenHeight]
imul ecx, eax
push edx
xor edx, edx
xchg edx, [prev_palette]
add edi, ecx
add esi, ecx
add edi, ecx
add edi, ecx
@@:
dec esi
movzx eax, byte [esi]
mov eax, [eax*4+edx]
sub edi, 3
mov [edi], ax
shr eax, 16
mov [edi+2], al
loop @b
pop edx
movzx esi, [ebx + gif.Header.lsd.ScreenHeight]
movzx eax, [ebx + gif.Header.lsd.ScreenWidth]
mov edx, [edx + Image.Extended]
movzx ecx, [edx + gif.Image.info.Top]
sub esi, ecx
jbe .convert_rgb_ret
imul ecx, eax
lea ecx, [ecx*3]
add edi, ecx
cmp si, [edx + gif.Image.info.Height]
jb @f
mov si, [edx + gif.Image.info.Height]
@@:
movzx ecx, [edx + gif.Image.info.Left]
sub eax, ecx
jbe .convert_rgb_ret
lea ecx, [ecx*3]
add edi, ecx
cmp ax, [edx + gif.Image.info.Width]
jb @f
mov ax, [edx + gif.Image.info.Width]
@@:
xchg eax, ecx
movzx edx, [ebx + gif.Header.lsd.ScreenWidth]
sub edx, ecx
mov eax, [background_color]
lea edx, [edx*3]
.convert_rgb_loop:
push ecx
@@:
stosw
shr eax, 16
stosb
loop @b
pop ecx
add edi, edx
dec esi
jnz .convert_rgb_loop
.convert_rgb_ret:
retn
.rgb:
push 3
pop eax
stdcall img.decode.gif._.alloc_aux_img
test eax, eax
jz .previous
or [prev_num_colors], -1
and [prev_palette], 0
mov ebx, [_data]
mov esi, [prev_img_data]
mov edi, [aux_img_data]
mov [prev_img_data], edi
cmp esi, edi
jz @f
movzx ecx, [ebx + gif.Header.lsd.ScreenHeight]
push ecx
movzx eax, [ebx + gif.Header.lsd.ScreenWidth]
imul ecx, eax
lea ecx, [ecx*3]
push edi
rep movsb
pop edi
pop esi
mov edx, [edx + Image.Extended]
movzx ecx, [edx + gif.Image.info.Top]
sub esi, ecx
jbe .rgb_ret
imul ecx, eax
lea ecx, [ecx*3]
add edi, ecx
cmp si, [edx + gif.Image.info.Height]
jb @f
mov si, [edx + gif.Image.info.Height]
@@:
movzx ecx, [edx + gif.Image.info.Left]
sub eax, ecx
jbe .rgb_ret
lea ecx, [ecx*3]
add edi, ecx
cmp ax, [edx + gif.Image.info.Width]
jb @f
mov ax, [edx + gif.Image.info.Width]
@@:
xchg eax, ecx
movzx edx, [ebx + gif.Header.lsd.ScreenWidth]
sub edx, ecx
mov eax, [background_color]
lea edx, [edx*3]
.rgb_loop:
push ecx
@@:
stosw
shr eax, 16
stosb
loop @b
pop ecx
add edi, edx
dec esi
jnz .rgb_loop
.rgb_ret:
retn
 
endp
 
;;================================================================================================;;
proc img.decode.gif._.alloc_aux_img ;/////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Allocate auxiliary memory for previous image ;;
;;------------------------------------------------------------------------------------------------;;
;> eax = image type: 1 = bpp8, 3 = bpp24 ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = [aux_img_data] ;;
;;================================================================================================;;
cmp [aux_img_type], eax
jae @f
push edx eax
movzx ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenWidth]
mul ecx
movzx ecx, [ebx + sizeof.gif.Image + gif.LogicalScreenDescriptor.ScreenHeight]
mul ecx
invoke mem.realloc, [aux_img_data], eax
pop ecx edx
test eax, eax
jz @f
mov [aux_img_type], ecx
mov [aux_img_data], eax
@@: retn
 
endp
 
;;================================================================================================;;
proc img.decode.gif._.alloc_aux_palette ;/////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Allocate and fill aux_palette ;;
;;------------------------------------------------------------------------------------------------;;
;> esi -> palette, ecx = palette size ;;
;;------------------------------------------------------------------------------------------------;;
;< [aux_palette] set ;;
;;================================================================================================;;
mov eax, [aux_palette]
test eax, eax
jnz @f
push edx ecx
invoke mem.alloc, 0x400
pop ecx edx
test eax, eax
jz .ret
mov [aux_palette], eax
@@:
mov edi, eax
rep movsd
.ret:
retn
 
endp
 
restore main_img
restore transparent_color
restore background_color
restore prev_num_colors
restore prev_palette
restore max_color
restore prev_img_data
restore _data
restore aux_img_data
restore aux_img_type
restore aux_palette
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Below is private data you should never use directly from your code ;;
/programs/develop/libraries/libs-dev/libimg/gif/gif.inc
61,7 → 61,9
gif.Block.Introducer.EndOfFile = 0x3B
 
struct gif.ImageDescriptor ; GIF87a
b gif.Block ; Introducer = 2Ch (',')
; we read Introducer before parsing gif.ImageDescriptor,
; so it is convenient to not include it in struct
; b gif.Block ; Introducer = 2Ch (',')
Left dw ? ; X position of image on the display
Top dw ? ; Y position of image on the display
Width dw ? ; Width of the image in pixels
89,8 → 91,8
gif.Extension.Label.Application = 0xFF
 
struct gif.PlainTextExtension ; GIF89a
e gif.Extension ; Label = 01h
BlockSize db ? ; Size of Extension Block (always 0Ch)
; e gif.Extension ; Label = 01h
; BlockSize db ? ; Size of Extension Block (always 0Ch)
TextGridLeft dw ? ; X position of text grid in pixels
TextGridTop dw ? ; Y position of text grid in pixels
TextGridWidth dw ? ; Width of the text grid in pixels
104,8 → 106,10
ends
 
struct gif.GraphicsControlExtension ; GIF89a
e gif.Extension ; Label = F9h
BlockSize db ? ; Size of remaining fields (always 04h)
; e gif.Extension ; Label = F9h
; BlockSize db ? ; Size of remaining fields (always 04h)
; previous fields are not included in this structure for convenience
; (they are parsed before this)
Packed db ? ; Method of graphics disposal to use
DelayTime dw ? ; Hundredths of seconds to wait
ColorIndex db ? ; Transparent Color Index
130,8 → 134,9
;;------------------------------------------------------------------------------------------------;;
 
struct gif.Image
info gif.ImageDescriptor
gce gif.GraphicsControlExtension
info gif.ImageDescriptor
; lsd gif.LogicalScreenDescriptor ; saved only in first image
ends
 
gif.Null equ 0x1000
/programs/develop/libraries/libs-dev/libimg/jpeg/jpeg.asm
474,8 → 474,8
; image type: 8 bpp for grayscale JPEGs, 24 bpp for normal,
; 32 bpp for Adobe YCCK
push Image.bpp8
pop eax
cmp edi, 1
pop eax ; Image.bpp8 = 1
cmp edi, eax
jz @f
inc eax ; Image.bpp24 = 2
cmp edi, 3
1621,9 → 1621,9
stosd ; dd VFactor_i+1 - (height % VFactor_i)
pop ecx
xor eax, eax
cmp ebp, 1
cmc
rcr eax, 1
test ebp, ebp
setnp al
ror eax, 1
stosd ; dd DCPrediction
mov eax, ebp
stosd ; dd ComponentOffset
/programs/develop/libraries/libs-dev/libimg/libimg.asm
35,12 → 35,9
include 'gif/gif.asm'
include 'jpeg/jpeg.asm'
include 'png/png.asm'
include 'tga/tga.asm'
include 'z80/z80.asm'
 
mem.alloc dd ?
mem.free dd ?
mem.realloc dd ?
dll.load dd ?
 
;;================================================================================================;;
proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
60,6 → 57,14
 
call img.initialize.jpeg
 
xor eax, eax
cpuid
cmp ecx, 'ntel'
jnz @f
mov dword [img._.do_rgb.handlers + (Image.bpp15-1)*4], img._.do_rgb.bpp15.intel
mov dword [img._.do_rgb.handlers + (Image.bpp16-1)*4], img._.do_rgb.bpp16.intel
@@:
 
.ok: xor eax,eax
ret
endp
211,26 → 216,257
mov ecx, [esi + Image.Width]
imul ecx, [esi + Image.Height]
mov eax, [esi + Image.Type]
dec eax
jz .bpp8
dec eax
jz .bpp24
; 32 BPP -> 24 BPP
jmp dword [.handlers + (eax-1)*4]
 
align 16
.bpp8:
; 8 BPP -> 24 BPP
push ebx
mov ebx, [esi + Image.Palette]
mov esi, [esi + Image.Data]
@@:
movzx eax, byte [esi]
add esi, 1
mov eax, [ebx + eax*4]
mov [edi], eax
add edi, 3
sub ecx, 1
jnz @b
pop ebx
ret
 
; 15 BPP -> 24 BPP
.bpp15.intel:
push ebx ebp
sub ecx, 4
jb .bpp15.tail
align 16
.bpp15.intel.loop:
repeat 2
mov ebx, [esi]
mov al, [esi]
mov ah, [esi+1]
add esi, 4
and al, 0x1F
and ah, 0x1F shl 2
mov ebp, ebx
mov dl, al
mov dh, ah
shr al, 2
shr ah, 4
shl dl, 3
shl dh, 1
and ebp, 0x1F shl 5
add al, dl
add ah, dh
shr ebp, 2
mov [edi], al
mov [edi+2], ah
mov eax, ebx
mov ebx, ebp
shr eax, 16
shr ebx, 5
add ebx, ebp
mov ebp, eax
mov [edi+1], bl
and eax, (0x1F) or (0x1F shl 10)
and ebp, 0x1F shl 5
lea edx, [eax+eax]
shr al, 2
mov ebx, ebp
shr ah, 4
shl dl, 2
shr ebx, 2
shr ebp, 7
add al, dl
add ah, dh
mov [edi+3], al
add ebx, ebp
mov [edi+5], ah
mov [edi+4], bl
add edi, 6
end repeat
sub ecx, 4
jnb .bpp15.intel.loop
.bpp15.tail:
add ecx, 4
jz .bpp15.done
@@:
mov eax, [esi]
mov [edi], ax
shr eax, 16
mov [edi+2], al
add esi, 4
movzx eax, word [esi]
mov ebx, eax
add esi, 2
and eax, (0x1F) or (0x1F shl 10)
and ebx, 0x1F shl 5
lea edx, [eax+eax]
shr al, 2
mov ebp, ebx
shr ebx, 2
shr ah, 4
shl dl, 2
shr ebp, 7
add eax, edx
add ebx, ebp
mov [edi], al
mov [edi+1], bl
mov [edi+2], ah
add edi, 3
sub ecx, 1
jnz @b
.bpp15.done:
pop ebp ebx
ret
 
.bpp15.amd:
push ebx ebp
sub ecx, 4
jb .bpp15.tail
align 16
.bpp15.amd.loop:
repeat 4
if (% mod 2) = 1
mov eax, dword [esi]
mov ebx, dword [esi]
else
movzx eax, word [esi]
mov ebx, eax
end if
add esi, 2
and eax, (0x1F) or (0x1F shl 10)
and ebx, 0x1F shl 5
lea edx, [eax+eax]
shr al, 2
mov ebp, ebx
shr ebx, 2
shr ah, 4
shl dl, 2
shr ebp, 7
add eax, edx
add ebx, ebp
mov [edi], al
mov [edi+1], bl
mov [edi+2], ah
add edi, 3
end repeat
sub ecx, 4
jnb .bpp15.amd.loop
jmp .bpp15.tail
 
; 16 BPP -> 24 BPP
.bpp16.intel:
push ebx ebp
sub ecx, 4
jb .bpp16.tail
align 16
.bpp16.intel.loop:
repeat 2
mov ebx, [esi]
mov al, [esi]
mov ah, [esi+1]
add esi, 4
and al, 0x1F
and ah, 0x1F shl 3
mov ebp, ebx
mov dl, al
mov dh, ah
shr al, 2
shr ah, 5
shl dl, 3
and ebp, 0x3F shl 5
add al, dl
add ah, dh
shr ebp, 3
mov [edi], al
mov [edi+2], ah
mov eax, ebx
mov ebx, ebp
shr eax, 16
shr ebx, 6
add ebx, ebp
mov ebp, eax
mov [edi+1], bl
and eax, (0x1F) or (0x1F shl 11)
and ebp, 0x3F shl 5
mov edx, eax
shr al, 2
mov ebx, ebp
shr ah, 5
shl dl, 3
shr ebx, 3
shr ebp, 9
add al, dl
add ah, dh
mov [edi+3], al
add ebx, ebp
mov [edi+5], ah
mov [edi+4], bl
add edi, 6
end repeat
sub ecx, 4
jnb .bpp16.intel.loop
.bpp16.tail:
add ecx, 4
jz .bpp16.done
@@:
movzx eax, word [esi]
mov ebx, eax
add esi, 2
and eax, (0x1F) or (0x1F shl 11)
and ebx, 0x3F shl 5
mov edx, eax
shr al, 2
mov ebp, ebx
shr ebx, 3
shr ah, 5
shl dl, 3
shr ebp, 9
add eax, edx
add ebx, ebp
mov [edi], al
mov [edi+1], bl
mov [edi+2], ah
add edi, 3
sub ecx, 1
jnz @b
.bpp16.done:
pop ebp ebx
ret
 
.bpp16.amd:
push ebx ebp
sub ecx, 4
jb .bpp16.tail
align 16
.bpp16.amd.loop:
repeat 4
if (% mod 2) = 1
mov eax, dword [esi]
mov ebx, dword [esi]
else
movzx eax, word [esi]
mov ebx, eax
end if
add esi, 2
and eax, (0x1F) or (0x1F shl 11)
and ebx, 0x3F shl 5
mov edx, eax
shr al, 2
mov ebp, ebx
shr ebx, 3
shr ah, 5
shl dl, 3
shr ebp, 9
add eax, edx
add ebx, ebp
mov [edi], al
mov [edi+1], bl
mov [edi+2], ah
add edi, 3
end repeat
sub ecx, 4
jnb .bpp16.amd.loop
jmp .bpp16.tail
 
align 16
.bpp24:
; 24 BPP -> 24 BPP
lea ecx, [ecx*3 + 3]
239,23 → 475,24
rep movsd
ret
 
.bpp8:
; 8 BPP -> 24 BPP
push ebx
mov ebx, [esi + Image.Palette]
align 16
.bpp32:
; 32 BPP -> 24 BPP
mov esi, [esi + Image.Data]
 
@@:
movzx eax, byte [esi]
add esi, 1
mov eax, [ebx + eax*4]
mov eax, [esi]
mov [edi], ax
shr eax, 16
mov [edi+2], al
add esi, 4
add edi, 3
sub ecx, 1
jnz @b
pop ebx
 
@@:
ret
 
endp
 
;;================================================================================================;;
335,6 → 572,32
endp
 
;;================================================================================================;;
proc img.destroy.layer _img ;/////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
;;------------------------------------------------------------------------------------------------;;
;> --- TBD --- ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
mov eax, [_img]
mov edx, [eax + Image.Previous]
test edx, edx
jz @f
push [eax + Image.Next]
pop [edx + Image.Next]
@@:
mov edx, [eax + Image.Next]
test edx, edx
jz @f
push [eax + Image.Previous]
pop [edx + Image.Previous]
@@:
stdcall img._.delete, eax
ret
endp
 
;;================================================================================================;;
proc img.destroy _img ;///////////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
343,8 → 606,33
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
;TODO: link Next and Previous
stdcall img._.delete, [_img]
push 1
mov eax, [_img]
mov eax, [eax + Image.Previous]
.destroy_prev_loop:
test eax, eax
jz .destroy_prev_done
pushd [eax + Image.Previous]
stdcall img._.delete, eax
test eax, eax
jnz @f
mov byte [esp+4], 0
@@:
pop eax
jmp .destroy_prev_loop
.destroy_prev_done:
mov eax, [_img]
.destroy_next_loop:
pushd [eax + Image.Next]
stdcall img._.delete, eax
test eax, eax
jnz @f
mov byte [esp+4], 0
@@:
pop eax
test eax, eax
jnz .destroy_next_loop
pop eax
ret
endp
 
417,9 → 705,9
endp
 
;;================================================================================================;;
proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Flip image ;;
;? Flip image layer ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;> _flip_kind = one of FLIP_* constants ;;
493,12 → 781,9
mov esi, [ebx + Image.Data]
mov edi, [scanline_len]
add edi, esi
jmp dword [.handlers_horz + (eax-1)*4]
 
dec eax
jz .bpp8.2
dec eax
jz .bpp24.2
 
.bpp32_horz:
sub edi, 4
 
.next_line_horz:
521,7 → 806,29
jnz .next_line_horz
jmp .exit
 
.bpp8.2:
.bpp1x_horz:
sub edi, 2
.next_line_horz1x:
push ecx esi edi
 
mov ecx, [ebx + Image.Width]
@@: mov ax, [esi]
mov dx, [edi]
mov [edi], ax
mov [esi], dx
add esi, 2
sub edi, 2
sub ecx, 2
ja @b
 
pop edi esi ecx
add esi, [scanline_len]
add edi, [scanline_len]
dec ecx
jnz .next_line_horz1x
jmp .exit
 
.bpp8_horz:
dec edi
.next_line_horz8:
push ecx esi edi
544,13 → 851,12
jnz .next_line_horz8
jmp .exit
 
.bpp24.2:
.bpp24_horz:
sub edi, 3
.next_line_horz32:
.next_line_horz24:
push ecx esi edi
 
mov ecx, [ebx + Image.Width]
shr ecx, 1
@@:
mov al, [esi]
mov dl, [edi]
566,14 → 872,14
mov [esi+2], dl
add esi, 3
sub edi, 3
sub ecx, 1
jnz @b
sub ecx, 2
ja @b
 
pop edi esi ecx
add esi, [scanline_len]
add edi, [scanline_len]
dec ecx
jnz .next_line_horz32
jnz .next_line_horz24
 
.exit:
xor eax, eax
588,11 → 894,42
endp
 
;;================================================================================================;;
proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Rotate image ;;
;? Flip all layers of image ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;> _flip_kind = one of FLIP_* constants ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
push 1
mov ebx, [_img]
@@:
mov eax, [ebx + Image.Previous]
test eax, eax
jz .loop
mov ebx, eax
jmp @b
.loop:
stdcall img.flip.layer, ebx, [_flip_kind]
test eax, eax
jnz @f
mov byte [esp], 0
@@:
mov ebx, [ebx + Image.Next]
test ebx, ebx
jnz .loop
pop eax
ret
endp
 
;;================================================================================================;;
proc img.rotate.layer _img, _rotate_kind ;////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Rotate image layer ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;> _rotate_kind = one of ROTATE_* constants ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
646,7 → 983,57
jz .rotate_ccw8
cmp [ebx + Image.Type], Image.bpp24
jz .rotate_ccw24
cmp [ebx + Image.Type], Image.bpp32
jz .rotate_ccw32
 
.next_column_ccw_low1x:
dec ecx
js .exchange_dims
push ecx
 
mov edx, [scanline_len_old]
add [scanline_len_old], -2
 
mov ecx, [scanline_pixels_new]
mov esi, [ebx + Image.Data]
mov edi, [line_buffer]
@@: mov ax, [esi]
mov [edi], ax
add esi, edx
add edi, 2
sub ecx, 1
jnz @b
 
mov eax, [scanline_pixels_new]
mov edi, [ebx + Image.Data]
lea esi, [edi + 2]
mov edx, [scanline_len_old]
@@: mov ecx, edx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
add esi, 1
sub eax, 1
jnz @b
 
mov eax, [scanline_len_new]
sub [pixels_ptr], eax
mov ecx, [scanline_pixels_new]
mov esi, [line_buffer]
mov edi, [pixels_ptr]
mov edx, ecx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
 
pop ecx
jmp .next_column_ccw_low1x
 
.rotate_ccw32:
.next_column_ccw_low:
dec ecx
js .exchange_dims
809,7 → 1196,59
jz .rotate_cw8
cmp [ebx + Image.Type], Image.bpp24
jz .rotate_cw24
cmp [ebx + Image.Type], Image.bpp32
jz .rotate_cw32
 
.next_column_cw_low1x:
dec ecx
js .exchange_dims
push ecx
 
mov edx, [scanline_len_old]
add [scanline_len_old], -2
 
mov ecx, [scanline_pixels_new]
mov esi, [pixels_ptr]
add esi, -2
mov edi, [line_buffer]
@@: mov ax, [esi]
mov [edi], ax
sub esi, edx
add edi, 2
sub ecx, 1
jnz @b
 
mov eax, [scanline_pixels_new]
dec eax
mov edi, [ebx + Image.Data]
add edi, [scanline_len_old]
lea esi, [edi + 2]
mov edx, [scanline_len_old]
@@: mov ecx, edx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
add esi, 3
sub eax, 1
jnz @b
 
mov eax, [scanline_len_new]
sub [pixels_ptr], eax
mov ecx, eax
mov esi, [line_buffer]
mov edi, [pixels_ptr]
shr ecx, 2
rep movsd
mov ecx, eax
and ecx, 3
rep movsb
 
pop ecx
jmp .next_column_cw_low1x
 
.rotate_cw32:
.next_column_cw_low:
dec ecx
js .exchange_dims
976,8 → 1415,94
ret
endp
 
;;================================================================================================;;
proc img.rotate _img, _rotate_kind ;//////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Rotate all layers of image ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;> _rotate_kind = one of ROTATE_* constants ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
push 1
mov ebx, [_img]
@@:
mov eax, [ebx + Image.Previous]
test eax, eax
jz .loop
mov ebx, eax
jmp @b
.loop:
stdcall img.rotate.layer, ebx, [_rotate_kind]
test eax, eax
jnz @f
mov byte [esp], 0
@@:
mov ebx, [ebx + Image.Next]
test ebx, ebx
jnz .loop
pop eax
ret
endp
 
;;================================================================================================;;
proc img.draw _img, _x, _y, _width, _height, _xpos, _ypos ;///////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Draw image in the window ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;>_x = x-coordinate in the window ;;
;>_y = y-coordinate in the window ;;
;>_width = maximum width to draw ;;
;>_height = maximum height to draw ;;
;>_xpos = offset in image by x-axis ;;
;>_ypos = offset in image by y-axis ;;
;;------------------------------------------------------------------------------------------------;;
;< no return value ;;
;;================================================================================================;;
push ebx esi edi
mov ebx, [_img]
stdcall img._.validate, ebx
test eax, eax
jnz .done
mov ecx, [ebx + Image.Width]
sub ecx, [_xpos]
jbe .done
cmp ecx, [_width]
jb @f
mov ecx, [_width]
@@:
mov edx, [ebx + Image.Height]
sub edx, [_ypos]
jbe .done
cmp edx, [_height]
jb @f
mov edx, [_height]
@@:
mov eax, [ebx + Image.Width]
sub eax, ecx
call img._.get_scanline_len
shl ecx, 16
add ecx, edx
mov edx, [_x - 2]
mov dx, word [_y]
mov esi, [ebx + Image.Type]
mov esi, [type2bpp + (esi-1)*4]
mov edi, [ebx + Image.Palette]
mov ebx, [ebx + Image.Data]
push ebp
push 65
pop ebp
xchg eax, ebp
int 40h
pop ebp
.done:
pop edi esi ebx
ret
endp
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Below are private procs you should never call directly from your code ;;
1015,6 → 1540,7
xor ecx, ecx
mov [eax + Image.Data], ecx
mov [eax + Image.Type], ecx
mov [eax + Image.Flags], ecx
mov [eax + Image.Extended], ecx
mov [eax + Image.Previous], ecx
mov [eax + Image.Next], ecx
1118,7 → 1644,10
jz .bpp8.1
cmp [ebx + Image.Type], Image.bpp24
jz .bpp24.1
shl eax, 2
add eax, eax
cmp [ebx + Image.Type], Image.bpp32
jnz @f
add eax, eax
jmp @f
.bpp24.1:
lea eax, [eax*3]
1135,7 → 1664,7
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
 
 
align 4
img._.formats_table:
.bmp dd img.is.bmp, img.decode.bmp, img.encode.bmp
; .ico dd img.is.ico, img.decode.ico, img.encode.ico
1143,9 → 1672,27
.gif dd img.is.gif, img.decode.gif, img.encode.gif
.png dd img.is.png, img.decode.png, img.encode.png
.jpg dd img.is.jpg, img.decode.jpg, img.encode.jpg
.tga dd img.is.tga, img.decode.tga, img.encode.tga
.z80 dd img.is.z80, img.decode.z80, img.encode.z80 ;this must be the last entry as there are no
;signatures in z80 screens at all
dd 0
 
align 4
type2bpp dd 8, 24, 32, 15, 16
img._.do_rgb.handlers:
dd img._.do_rgb.bpp8
dd img._.do_rgb.bpp24
dd img._.do_rgb.bpp32
dd img._.do_rgb.bpp15.amd ; can be overwritten in lib_init
dd img._.do_rgb.bpp16.amd ; can be overwritten in lib_init
 
img.flip.layer.handlers_horz:
dd img.flip.layer.bpp8_horz
dd img.flip.layer.bpp24_horz
dd img.flip.layer.bpp32_horz
dd img.flip.layer.bpp1x_horz
dd img.flip.layer.bpp1x_horz
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
1160,7 → 1707,7
 
export \
lib_init , 'lib_init' , \
0x00010003 , 'version' , \
0x00010004 , 'version' , \
img.is_img , 'img.is_img' , \
img.info , 'img.info' , \
img.from_file , 'img.from_file' , \
1172,11 → 1719,15
img.encode , 'img.encode' , \
img.create , 'img.create' , \
img.destroy , 'img.destroy' , \
img.destroy.layer, 'img.destroy.layer', \
img.count , 'img.count' , \
img.lock_bits , 'img.lock_bits' , \
img.unlock_bits , 'img.unlock_bits' , \
img.flip , 'img.flip' , \
img.rotate , 'img.rotate'
img.flip.layer , 'img.flip.layer' , \
img.rotate , 'img.rotate' , \
img.rotate.layer, 'img.rotate.layer', \
img.draw , 'img.draw'
 
; import from deflate unpacker
; is initialized only when PNG loading is requested
1187,11 → 1738,21
import kfar_arc, \
deflate_unpack2, 'deflate_unpack2'
 
align 4
; mutex for unpacker loading
deflate_loader_mutex dd 0
 
; default palette for GIF - b&w
gif_default_palette:
db 0, 0, 0
db 0xFF, 0xFF, 0xFF
 
section '.data' data readable writable align 16
; uninitialized data - global constant tables
mem.alloc dd ?
mem.free dd ?
mem.realloc dd ?
dll.load dd ?
 
; data for YCbCr -> RGB translation
color_table_1 rd 256
/programs/develop/libraries/libs-dev/libimg/libimg.inc
34,12 → 34,21
Data dd ?
Palette dd ? ; used iff Type eq Image.bpp8
Extended dd ?
Flags dd ? ; bitfield
Delay dd ? ; used iff Image.IsAnimated is set in Flags
ends
 
; values for Image.Type
; must be consecutive to allow fast switch on Image.Type in support functions
Image.bpp8 = 1
Image.bpp24 = 2
Image.bpp32 = 3
Image.bpp15 = 4
Image.bpp16 = 5
 
; bits in Image.Flags
Image.IsAnimated = 1
 
FLIP_VERTICAL = 0x01
FLIP_HORIZONTAL = 0x02
FLIP_BOTH = FLIP_VERTICAL or FLIP_HORIZONTAL
/programs/develop/libraries/libs-dev/libimg/png/png.asm
515,6 → 515,8
mov [edi+2], al
mov al, [esi+3]
mov [edi+3], al
add esi, 4
add edi, 4
sub ecx, 4
jnz @b
sub edx, 1
737,8 → 739,10
sub ebx, ecx
jc .convert_done
@@:
mov ax, [esi]
add esi, 2
convert_16_to_8
add esi, 2
mov [edi], al
add edi, 1
sub ecx, 2
jnz @b
821,8 → 825,10
sub ebx, ecx
jc .convert_done
@@:
mov ax, [esi]
add esi, 4
convert_16_to_8
add esi, 4
mov [edi], al
add edi, 1
sub ecx, 4
jnz @b
/programs/develop/libraries/libs-dev/libimg/tga/tga.asm
0,0 → 1,250
;;================================================================================================;;
;;//// tga.asm //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;;
;;================================================================================================;;
;; ;;
;; This file is part of Common development libraries (Libs-Dev). ;;
;; ;;
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
;; of the License, or (at your option) any later version. ;;
;; ;;
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;;
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;
;; Lesser General Public License for more details. ;;
;; ;;
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;;
;; If not, see <http://www.gnu.org/licenses/>. ;;
;; ;;
;;================================================================================================;;
;; ;;
;; References: ;;
;; 1. Hiview 1.2 by Mohammad A. REZAEI ;;
;; ;;
;;================================================================================================;;
 
include 'tga.inc'
 
;;================================================================================================;;
proc img.is.tga _data, _length ;//////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Determine if raw data could be decoded (is in Targa format) ;;
;;------------------------------------------------------------------------------------------------;;
;> _data = raw data as read from file/stream ;;
;> _length = data length ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
cmp [_length], 18
jbe .nope
mov eax, [_data]
push ebx
mov ebx,[eax+1] ;bl=cmatype,bh=subtype
cmp bl,1 ;cmatype is in [0..1]
ja .nope
cmp bh,11 ;subtype is in [1..3] (non-rle) or in [9..11] (rle)
ja .nope
cmp bh,9
jae .cont1
cmp bh,3
ja .nope
.cont1: ;continue testing
mov ebx,[eax+16] ;bl=bpp, bh=flags //image descriptor
test ebx,111b ;bpp must be 8, 15, 16, 24 or 32
jnz .maybe15
shr bl,3
cmp bl,4
ja .nope
jmp .cont2
.maybe15:
cmp bl,15
jne .nope
.cont2: ;continue testing
test bh,tga.flags.interlace_type ;deinterlacing is not supported yet
jnz .nope
cmp byte[eax+7],24 ;test palette bpp - only 24 and 32 are supported
je .yep
cmp byte[eax+7],32 ;test palette bpp - only 24 and 32 are supported
je .yep
.nope:
xor eax, eax
pop ebx
ret
 
.yep:
xor eax, eax
inc eax
pop ebx
ret
endp
 
;;================================================================================================;;
proc img.decode.tga _data, _length ;//////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Decode data into image if it contains correctly formed raw data in Targa format ;;
;;------------------------------------------------------------------------------------------------;;
;> _data = raw data as read from file/stream ;;
;> _length = data length ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) or pointer to image ;;
;;================================================================================================;;
locals
IMGwidth dd ?
IMGheight dd ?
IMGbpp dd ?
DupPixelCount dd ?
TgaBlockCount dd ?
endl
pushad
cld ;paranoia
and [DupPixelCount],0 ;prepare variables
and [TgaBlockCount],0 ;prepare variables
mov eax,[_data]
movzx esi,byte[eax]
lea esi,[esi+eax+18] ;skip comment and header
mov ebx,[eax+12]
movzx ecx,bx ;ecx=width
shr ebx,16 ;ebx=height
mov [IMGwidth],ecx
mov [IMGheight],ebx
movzx edx,byte[eax+16]
cmp edx,16
jnz @f
dec edx ;16bpp tga images are really 15bpp ARGB
@@:
sub edx, 16 - Image.bpp16 ; 15 -> Image.bpp15, 16 -> Image.bpp16
mov [IMGbpp],edx
stdcall img.create,ecx,ebx,edx
mov [esp+28],eax ;save return value
test eax,eax ;failed to allocate?
jz .locret ;then exit
cmp edx,8
jne .palette_parsed
mov edi,[eax+Image.Palette]
mov ecx,[_data]
cmp byte[ecx+2],3 ;we also have grayscale subtype
jz .write_grayscale_palette ;that don't hold palette in file
cmp byte[ecx+2],11
jz .write_grayscale_palette
mov dh,[ecx+7] ;size of colormap entries in bits
movzx ecx,word[ecx+5] ;number of colormap entries
cmp dh,24
jz .skip_24bpp_palette ;test if colormap entries are 24bpp
rep movsd ;else they are 32 bpp
jmp .palette_parsed
.write_grayscale_palette:
push eax
mov ecx,0x100
xor eax,eax
@@:
stosd
add eax,0x010101
loop @b
pop eax
jmp .palette_parsed
.skip_24bpp_palette:
push eax
@@:
lodsd
dec esi
and eax,0xFFFFFF
; bswap eax
; shr eax,8
stosd
loop @b
pop eax
.palette_parsed:
mov edi,[eax+Image.Data]
imul ebx,[IMGwidth] ;ebx=width*height
 
mov edx,[IMGbpp]
add edx,7
shr edx,3 ;edx=bytes per pixel
mov dh,dl ;dh=dl=bytes per pixel
 
mov eax,[_data]
cmp byte[eax+2],9
jb .not_an_rle
.tga_read_rle_pixel:
cmp [DupPixelCount],0 ;Duplicate previously read pixel?
jg .duplicate_previously_read_pixel
dec [TgaBlockCount] ;Decrement pixels remaining in block
jns .read_non_rle_pixel
xor eax,eax
lodsb
test al,al ;Start of duplicate-pixel block?
jns .2
and al,0x7f
mov [DupPixelCount],eax ;Number of duplications after this one
and [TgaBlockCount],0 ;Then read new block header
jmp .read_non_rle_pixel
.2:
mov dword[TgaBlockCount],eax
.read_non_rle_pixel:
xor eax,eax
mov dl,dh
@@:
shl eax,8
lodsb
dec dl
jnz @b
cmp dh,3
jne .put_pixel
bswap eax
shr eax,8
jmp .put_pixel
.duplicate_previously_read_pixel:
dec [DupPixelCount]
.put_pixel:
mov dl,dh
push eax
@@:
stosb
shr eax,8
dec dl
jnz @b
pop eax
dec ebx
jnz .tga_read_rle_pixel
jmp .locret
.not_an_rle:
movzx edx,dl ;dh contains bpp too (for decoding needs)
imul edx,ebx
mov ecx,edx
rep movsb ;just copy the image
.locret:
popad
ret
endp
 
;;================================================================================================;;
proc img.encode.tga _img, _p_length ;/////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Encode image into raw data in Targa format ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) or pointer to encoded data ;;
;< _p_length = encoded data length ;;
;;================================================================================================;;
xor eax, eax
ret
endp
 
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Below are private procs you should never call directly from your code ;;
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Below is private data you should never use directly from your code ;;
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
 
;
/programs/develop/libraries/libs-dev/libimg/tga/tga.inc
0,0 → 1,35
;;================================================================================================;;
;;//// tga.inc //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;;
;;================================================================================================;;
;; ;;
;; This file is part of Common development libraries (Libs-Dev). ;;
;; ;;
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
;; of the License, or (at your option) any later version. ;;
;; ;;
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;;
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;
;; Lesser General Public License for more details. ;;
;; ;;
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;;
;; If not, see <http://www.gnu.org/licenses/>. ;;
;; ;;
;;================================================================================================;;
 
struct tga.FileHeader
CommentLength db ?
ColormapType db ?
SubType db ?
DontKnow1 dw ?
ColormapSize dw ?
ColormapBpp db ?
DontKnow2 dd ?
Width dw ?
Height dw ?
BitPerPixel db ?
DontKnow3 db ?
ends
 
tga.flags.top_down_row_order equ 32 ;bit5
tga.flags.interlace_type equ 192;bits6/7
/programs/develop/libraries/libs-dev/libimg/z80/z80.asm
0,0 → 1,257
;;================================================================================================;;
;;//// z80.asm //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;;
;;================================================================================================;;
;; ;;
;; This file is part of Common development libraries (Libs-Dev). ;;
;; ;;
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
;; of the License, or (at your option) any later version. ;;
;; ;;
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;;
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;
;; Lesser General Public License for more details. ;;
;; ;;
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;;
;; If not, see <http://www.gnu.org/licenses/>. ;;
;; ;;
;;================================================================================================;;
;; ;;
;; References: ;;
;; 1. ;;
;; ;;
;;================================================================================================;;
 
include 'z80.inc'
 
;;================================================================================================;;
proc img.is.z80 _data, _length ;//////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Determine if raw data could be decoded (is in z80 screen format) ;;
;;------------------------------------------------------------------------------------------------;;
;> _data = raw data as read from file/stream ;;
;> _length = data length ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = false / true ;;
;;================================================================================================;;
xor eax,eax
cmp [_length],6929
setz al
je @f
cmp [_length],6912
setz al
@@:
ret
endp
 
;;================================================================================================;;
proc img.decode.z80 _data, _length ;//////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Decode data into image if it contains correctly formed raw data in z80 screen format ;;
;;------------------------------------------------------------------------------------------------;;
;> _data = raw data as read from file/stream ;;
;> _length = data length ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) or pointer to image ;;
;;================================================================================================;;
;---------------------------------------------------------------------------------------------------
;During the decoding:
;bl - PixelLeft (this means how much pixels left to put in current string)
;bh - CurrentString
;High half of ebx - use DualStos (two frames per one pixel_write)
;cl - PixelColorIndexInPalette
;ch - BackgroundColorIndexInPalette
;High half of ecx - blinking flag
;edx - address of current attribute byte
;---------------------------------------------------------------------------------------------------
locals
frame1 dd ?
OffsetIn2ndFrame dd ?
endl
xor eax,eax
pushad
cld ;paranoia
stdcall img.create,256,192,Image.bpp8
test eax,eax
jz img.decode.z80.locret ;test if allocation failed
mov [frame1],eax
mov esi,z80._._16color_palette
mov ecx,16
mov edi,[eax+Image.Palette]
rep movsd ;write palette for the first frame
mov esi,[_data]
cmp [_length],6929
jne @f
add esi,17 ;in case of 6929 byte files we just skip the info in the begininning.
@@:
;---------------------------------------------------------------------------------------------------
;At first we'll determine if there are any blinking pixels
;if no - we'll produce statical single image
mov ecx,768
lea edx,[esi+6912-768];edx points to attribute area
xor ebx,ebx ;begin from <0,0> (for further decoding)
@@:
test byte[edx+ecx-1],z80.BlinkFlag ;such addressing is a good optimisation
;(as I hope), edx is unchanged
jnz .decode_z80_with_blinking
loop @b
.decode_z80_without_blinking:
jmp .decode_z80_main_stage
 
.decode_z80_with_blinking:
or ebx,0xFFFF0000 ;use DualStos
mov ecx,eax ;eax still points to the first frame
stdcall img.create,256,192,Image.bpp8
test eax,eax
jz img.decode.z80.failed
mov [eax+Image.Previous],ecx
mov [ecx+Image.Next],eax
mov esi,z80._._16color_palette
mov ecx,16
mov edi,[eax+Image.Palette]
rep movsd ;write palette for the second frame
mov eax,[eax+Image.Data]
mov [OffsetIn2ndFrame],eax
;-------------------------------------------------------------------------------
.decode_z80_main_stage:
;2nd stage - convert z80 screen to 8bpp image with palette
.decode_z80_main_stage_main_loop:
test bl,7
jnz .decode_z80_main_stage_put_now
 
._z80_update_attributes:
movsx ecx,byte[edx] ;note that BlinkFlag is the highest bit in attribute
;byte, so ecx's highest bit is set automatically
shl ecx,5
shr cl,5
and ch,0xF
test ch,1000b
jz @f
or ecx,1000b ;it has the same size with 'or cl,1000b' but could be faster
@@:
inc edx
 
lodsb
mov ah,al
 
.decode_z80_main_stage_put_now:
shl ah,1
;-------------------------------------------------------------------------------
._z80_put_pixel:
;In: CF - put pixel with color CL, !CF - pixel with color CH
;High parts of ebx and ecx - as described above
mov al,cl ;'mov' doesn't affect flags
jc @f
mov al,ch
@@:
stosb ;'stosb' doesn't affect flags
 
test ebx,ebx
jns @f
test ecx,ecx
jns .1
mov al,ch
.1:
xchg [OffsetIn2ndFrame],edi
stosb
xchg [OffsetIn2ndFrame],edi
@@:
inc bl ;next pixel
jz .decode_z80_main_stage_row_finished
jmp .decode_z80_main_stage_main_loop
;-------------------------------------------------------------------------------
.decode_z80_main_stage_row_finished:
cmp bh,191 ;is image finished?
jb .decode_z80_main_stage_image_not_finished ;no.
.decode_z80_finish:
jmp .locret ;now really finished
;-------------------------------------------------------------------------------
;or not finished yet. Branch according to a row number (see documentation)
.decode_z80_main_stage_next_third:
sub bh,7
sub edi,256*(8-1)
jmp .decode_z80_main_stage_main_loop
 
.decode_z80_main_stage_image_not_finished:
;next row
add bh,8 ;refer to documentation
add edi,256*(8-1)
 
;if finished row is 63 or 127 then we process next third of the image
cmp bh,63+8
je .decode_z80_main_stage_next_third
cmp bh,127+8
je .decode_z80_main_stage_next_third
 
cmp bh,56+8 ;if finished row in [56;63) or [120;127) or [184;191)
jb .decode_z80_main_stage_main_loop
cmp bh,63+8
jb .4
cmp bh,120+8
jb .decode_z80_main_stage_main_loop
cmp bh,127+8
jb .4
cmp bh,184+8
jb .decode_z80_main_stage_main_loop
;note that if we are here then bh is < 191 (see label .2) but >= 184+8
.4:
;and if we here then bh is in [56;63) or [120;127) or [184;191)
sub bh,(8+56-1)
sub edi,256*(8+56-1)
sub edx,z80.AttrString*8
jmp .decode_z80_main_stage_main_loop
img.decode.z80.locret:
popad
ret
img.decode.z80.failed:
stdcall img.destroy,[frame1]
jmp img.decode.z80.locret
endp
 
;;================================================================================================;;
proc img.encode.z80 _img, _p_length ;/////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Encode image into raw data in z80 screen format ;;
;;------------------------------------------------------------------------------------------------;;
;> _img = pointer to image ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) or pointer to encoded data ;;
;< _p_length = encoded data length ;;
;;================================================================================================;;
xor eax, eax
ret
endp
 
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Below are private procs you should never call directly from your code ;;
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
 
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Below is private data you should never use directly from your code ;;
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
z80._._16color_palette:
dd 0 ; black
dd 0x000000b0 ; blue
dd 0x00b00000 ; red
dd 0x00b000b0 ; magenta
dd 0x0000b000 ; green
dd 0x0000b0b0 ; cyan
dd 0x00b0b000 ; yellow
dd 0x00b0b0b0 ; gray
dd 0 ; black
dd 0x000000ff ; light blue
dd 0x00ff0000 ; light red
dd 0x00ff00ff ; light magenta
dd 0x0000ff00 ; light green
dd 0x0000ffff ; light cyan
dd 0x00ffff00 ; light yellow
dd 0x00ffffff ; white
/programs/develop/libraries/libs-dev/libimg/z80/z80.inc
0,0 → 1,23
;;================================================================================================;;
;;//// z80.inc //// (c) Nable, 2007-2008 /////////////////////////////////////////////////////////;;
;;================================================================================================;;
;; ;;
;; This file is part of Common development libraries (Libs-Dev). ;;
;; ;;
;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;;
;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;;
;; of the License, or (at your option) any later version. ;;
;; ;;
;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;;
;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;
;; Lesser General Public License for more details. ;;
;; ;;
;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;;
;; If not, see <http://www.gnu.org/licenses/>. ;;
;; ;;
;;================================================================================================;;
z80.PixColor equ 000111b
z80.BgrColor equ 111000b
z80.BrightFlag equ (1 shl 6)
z80.BlinkFlag equ (1 shl 7)
z80.AttrString equ 32