libimg: add img.from_file, refactor img.convert.

Add new function, img.from_file: gets file name and returns decoded Image.
Make img.convert code less spaghetti: use jump table, not a chain of jmp's.


git-svn-id: svn://kolibrios.org@7105 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Ivan Baravy 2017-10-31 21:33:52 +00:00
parent 437e995f11
commit 6cf659fe71
3 changed files with 593 additions and 540 deletions

View File

@ -33,7 +33,13 @@ proc img.convert _src, _dst, _dst_type, _flags, _param
;< eax = 0 / pointer to converted image ;; ;< eax = 0 / pointer to converted image ;;
;< ecx = error code / undefined ;; ;< ecx = error code / undefined ;;
;;================================================================================================;; ;;================================================================================================;;
push ebx esi edi 0 0 locals
img dd ?
prev dd ?
endl
push ebx esi edi
mov [img], 0
mov [prev], 0
mov ebx, [_src] mov ebx, [_src]
@@: @@:
mov eax, [ebx + Image.Previous] mov eax, [ebx + Image.Previous]
@ -45,28 +51,26 @@ proc img.convert _src, _dst, _dst_type, _flags, _param
stdcall img.convert.layer, ebx, [_dst], [_dst_type], [_flags], [_param] stdcall img.convert.layer, ebx, [_dst], [_dst_type], [_flags], [_param]
test eax, eax test eax, eax
jz .error jz .error
cmp dword[esp + 4], 0 cmp [img], 0
jnz @f jnz @f
mov [esp + 4], eax mov [img], eax
@@: @@:
mov ecx, [esp] mov ecx, [prev]
jecxz @f jecxz @f
mov [ecx + Image.Next], eax mov [ecx + Image.Next], eax
mov [eax + Image.Previous], ecx
@@: @@:
mov [prev], eax
push [ebx + Image.Flags] push [ebx + Image.Flags]
pop [eax + Image.Flags] pop [eax + Image.Flags]
push [ebx + Image.Delay] push [ebx + Image.Delay]
pop [eax + Image.Delay] pop [eax + Image.Delay]
mov [eax + Image.Previous], ecx
mov [esp], eax
mov ebx, [ebx + Image.Next] mov ebx, [ebx + Image.Next]
test ebx, ebx test ebx, ebx
jnz .loop jnz .loop
.quit: mov eax, [img]
pop eax eax edi esi ebx
ret
.error: .error:
pop eax eax edi esi ebx pop edi esi ebx
ret ret
endp endp
@ -86,65 +90,44 @@ proc img.convert.layer _src, _dst, _dst_type, _flags, _param
;< ecx = error code / undefined ;; ;< ecx = error code / undefined ;;
;;================================================================================================;; ;;================================================================================================;;
locals locals
width rd 1 fun rd 1
height rd 1
endl endl
push ebx esi edi push ebx esi edi
mov ebx, [_src] mov ebx, [_src]
mov eax, 1 mov eax, [ebx + Image.Type]
mov ecx, [_dst_type] mov esi, [img.convert.table + 4*eax]
shl eax, cl .next:
mov ecx, [ebx + Image.Type] lodsd
test eax, [img.types_table + 4*ecx] test eax, eax
jnz @f jnz @f
mov ecx, LIBIMG_ERROR_BIT_DEPTH mov ecx, LIBIMG_ERROR_BIT_DEPTH
jmp .error jmp .exit
@@: @@:
cmp eax, [_dst_type]
lodsd
jnz .next
mov [fun], eax
mov eax, [_dst] mov eax, [_dst]
test eax, eax test eax, eax
jnz @f jnz @f
stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], [_dst_type] stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], [_dst_type]
test eax, eax test eax, eax
jz .error jz .exit
mov [_dst], eax mov [_dst], eax
@@: @@:
mov edi, [eax + Image.Data] mov edi, [eax + Image.Data]
mov esi, [ebx + Image.Data] mov esi, [ebx + Image.Data]
mov eax, [ebx + Image.Type] mov eax, [ebx + Image.Type]
cmp eax, Image.bpp8i stdcall [fun], [_src], [_dst]
je .bpp8i mov eax, [_dst]
cmp eax, Image.bpp8g .exit:
je .bpp8g pop edi esi ebx
cmp eax, Image.bpp24 ret
je .bpp24 endp
cmp eax, Image.bpp32
je .bpp32
cmp eax, Image.bpp15
je .bpp15
cmp eax, Image.bpp16
je .bpp16
cmp eax, Image.bpp1
je .bpp1
cmp eax, Image.bpp8a
je .bpp8a
mov ecx, LIBIMG_ERROR_BIT_DEPTH
jmp .error
.find_in_table_and_jump: proc img._.convert.bpp8i_to_bpp24 _src, _dst
mov ecx, [_dst_type]
@@:
mov eax, [edx]
add edx, 8
cmp eax, ecx
jne @b
jmp dword[edx - 4]
.bpp8i:
mov edx, img.convert.bpp8i.table
jmp .find_in_table_and_jump
.bpp8i_to_bpp24:
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@ -165,15 +148,28 @@ endl
mov [edi], ax mov [edi], ax
shr eax, 16 shr eax, 16
mov [edi + 2], al mov [edi + 2], al
mov eax, [_dst] ret
jmp .quit endp
proc img._.convert.bpp8i_to_bpp32 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
.bpp8g: mov ebx, [ebx + Image.Palette]
mov edx, img.convert.bpp8g.table @@:
jmp .find_in_table_and_jump movzx eax, byte[esi]
.bpp8g_to_bpp1: add esi, 1
mov eax, [ebx + eax*4]
mov [edi], eax
add edi, 4
dec ecx
jnz @b
ret
endp
proc img._.convert.bpp8g_to_bpp1 _src, _dst
mov eax, [_dst] mov eax, [_dst]
mov eax, [eax + Image.Palette] mov eax, [eax + Image.Palette]
mov dword[eax], 0x00000000 mov dword[eax], 0x00000000
@ -205,17 +201,10 @@ endl
@@: @@:
dec edx dec edx
jnz .bpp8g_to_bpp1.line jnz .bpp8g_to_bpp1.line
mov eax, [_dst] ret
jmp .quit endp
.bpp8g_to_bpp8g: proc img._.convert.bpp8g_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
rep movsb
mov eax, [_dst]
jmp .quit
.bpp8g_to_bpp24:
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@@: @@:
@ -227,13 +216,11 @@ endl
add edi, 3 add edi, 3
sub ecx, 1 sub ecx, 1
jnz @b jnz @b
mov eax, [_dst] ret
jmp .quit endp
.bpp24:
mov edx, img.convert.bpp24.table proc img._.convert.bpp24_to_bpp24 _src, _dst
jmp .find_in_table_and_jump
.bpp24_to_bpp24:
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
lea ecx, [ecx*3] lea ecx, [ecx*3]
@ -243,9 +230,11 @@ endl
mov ecx, edx mov ecx, edx
and ecx, 3 and ecx, 3
rep movsb rep movsb
mov eax, [_dst] ret
jmp .quit endp
.bpp24_to_bpp8g:
proc img._.convert.bpp24_to_bpp8g _src, _dst
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@@: @@:
@ -261,9 +250,11 @@ endl
add edi, 1 add edi, 1
sub ecx, 1 sub ecx, 1
jnz @b jnz @b
mov eax, [_dst] ret
jmp .quit endp
.bpp24_to_bpp32:
proc img._.convert.bpp24_to_bpp32 _src, _dst
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@@: @@:
@ -274,14 +265,11 @@ endl
stosd stosd
dec ecx dec ecx
jnz @b jnz @b
mov eax, [_dst] ret
jmp .quit endp
.bpp32: proc img._.convert.bpp32_to_bpp24 _src, _dst
mov edx, img.convert.bpp32.table
jmp .find_in_table_and_jump
.bpp32_to_bpp24:
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@@: @@:
@ -293,14 +281,19 @@ endl
add edi, 3 add edi, 3
sub ecx, 1 sub ecx, 1
jnz @b jnz @b
mov eax, [_dst] ret
jmp .quit endp
.bpp15: proc img._.convert.bpp32_to_bpp32 _src, _dst
mov edx, img.convert.bpp15.table mov ecx, [ebx + Image.Width]
jmp .find_in_table_and_jump imul ecx, [ebx + Image.Height]
.bpp15_to_bpp24: rep movsd
ret
endp
proc img._.convert.bpp15_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@ -420,11 +413,12 @@ end repeat
jnb .bpp15.amd.loop jnb .bpp15.amd.loop
jmp .bpp15.tail jmp .bpp15.tail
.quit:
ret
endp
.bpp16:
mov edx, img.convert.bpp16.table proc img._.convert.bpp16_to_bpp24 _src, _dst
jmp .find_in_table_and_jump
.bpp16_to_bpp24:
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
.bpp16.intel: .bpp16.intel:
@ -542,11 +536,16 @@ end repeat
jnb .bpp16.amd.loop jnb .bpp16.amd.loop
jmp .bpp16.tail jmp .bpp16.tail
.quit:
ret
endp
.bpp1:
mov edx, img.convert.bpp1.table proc img._.convert.bpp1_to_bpp24 _src, _dst
jmp .find_in_table_and_jump locals
.bpp1_to_bpp24: width rd 1
height rd 1
endl
push [ebx + Image.Width] push [ebx + Image.Width]
pop [width] pop [width]
push [ebx + Image.Height] push [ebx + Image.Height]
@ -577,14 +576,11 @@ end repeat
jnz .bpp1_to_bpp24.bit jnz .bpp1_to_bpp24.bit
jmp .bpp1_to_bpp24.byte jmp .bpp1_to_bpp24.byte
.bpp1.done: .bpp1.done:
mov eax, [_dst] ret
jmp .quit endp
.bpp8a: proc img._.convert.bpp8a_to_bpp1 _src, _dst
mov edx, img.convert.bpp8a.table
jmp .find_in_table_and_jump
.bpp8a_to_bpp1:
mov eax, [_dst] mov eax, [_dst]
mov eax, [eax + Image.Palette] mov eax, [eax + Image.Palette]
mov dword[eax], 0x00000000 mov dword[eax], 0x00000000
@ -616,10 +612,11 @@ end repeat
@@: @@:
dec edx dec edx
jnz .bpp8a_to_bpp1.line jnz .bpp8a_to_bpp1.line
mov eax, [_dst] ret
jmp .quit endp
.bpp8a_to_bpp24:
proc img._.convert.bpp8a_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width] mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height] imul ecx, [ebx + Image.Height]
@@: @@:
@ -631,35 +628,53 @@ end repeat
add edi, 3 add edi, 3
sub ecx, 1 sub ecx, 1
jnz @b jnz @b
mov eax, [_dst]
jmp .quit
.error:
xor eax, eax
.quit:
pop edi esi ebx
ret ret
endp endp
img.convert.bpp8i.table: img.convert.bpp8i.table:
dd Image.bpp24, img.convert.layer.bpp8i_to_bpp24 dd Image.bpp24, img._.convert.bpp8i_to_bpp24
img.convert.bpp8g.table: dd Image.bpp32, img._.convert.bpp8i_to_bpp32
dd Image.bpp24, img.convert.layer.bpp8g_to_bpp24 dd 0
dd Image.bpp8g, img.convert.layer.bpp8g_to_bpp8g
dd Image.bpp1, img.convert.layer.bpp8g_to_bpp1
img.convert.bpp24.table: img.convert.bpp24.table:
dd Image.bpp24, img.convert.layer.bpp24_to_bpp24 dd Image.bpp24, img._.convert.bpp24_to_bpp24
dd Image.bpp8g, img.convert.layer.bpp24_to_bpp8g dd Image.bpp8g, img._.convert.bpp24_to_bpp8g
dd Image.bpp32, img.convert.layer.bpp24_to_bpp32 dd Image.bpp32, img._.convert.bpp24_to_bpp32
dd 0
img.convert.bpp32.table: img.convert.bpp32.table:
dd Image.bpp24, img.convert.layer.bpp32_to_bpp24 dd Image.bpp24, img._.convert.bpp32_to_bpp24
dd Image.bpp32, img._.convert.bpp32_to_bpp32
dd 0
img.convert.bpp15.table: img.convert.bpp15.table:
dd Image.bpp24, img.convert.layer.bpp15_to_bpp24 dd Image.bpp24, img._.convert.bpp15_to_bpp24
dd 0
img.convert.bpp16.table: img.convert.bpp16.table:
dd Image.bpp24, img.convert.layer.bpp16_to_bpp24 dd Image.bpp24, img._.convert.bpp16_to_bpp24
dd 0
img.convert.bpp1.table: img.convert.bpp1.table:
dd Image.bpp24, img.convert.layer.bpp1_to_bpp24 dd Image.bpp24, img._.convert.bpp1_to_bpp24
dd 0
img.convert.bpp8g.table:
dd Image.bpp24, img._.convert.bpp8g_to_bpp24
dd Image.bpp1, img._.convert.bpp8g_to_bpp1
dd 0
img.convert.bpp2i.table:
dd 0
img.convert.bpp4i.table:
dd 0
img.convert.bpp8a.table: img.convert.bpp8a.table:
dd Image.bpp24, img.convert.layer.bpp8a_to_bpp24 dd Image.bpp24, img._.convert.bpp8a_to_bpp24
dd 0
img.convert.table:
dd 0 ; no image type zero
dd img.convert.bpp8i.table
dd img.convert.bpp24.table
dd img.convert.bpp32.table
dd img.convert.bpp15.table
dd img.convert.bpp16.table
dd img.convert.bpp1.table
dd img.convert.bpp8g.table
dd img.convert.bpp2i.table
dd img.convert.bpp4i.table
dd img.convert.bpp8a.table

View File

@ -26,7 +26,10 @@ include '../../../../struct.inc'
include '../../../../proc32.inc' include '../../../../proc32.inc'
include '../../../../macros.inc' include '../../../../macros.inc'
include '../../../../config.inc' include '../../../../config.inc'
;include '../../../../debug.inc' include '../../../../debug-fdo.inc'
__DEBUG__ = 0
__DEBUG_LEVEL__ = 1
include '../../../../develop/libraries/libs-dev/libio/libio.inc'
purge section,mov,add,sub purge section,mov,add,sub
include 'libimg.inc' include 'libimg.inc'
@ -124,13 +127,49 @@ endp
;;================================================================================================;; ;;================================================================================================;;
proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;; proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;; ;? load file from disk and decode it ;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;> --- TBD --- ;; ;> [_filename] = file name as passed to libio ;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;< eax = 0 / pointer to image ;; ;< eax = 0 / pointer to image ;;
;;================================================================================================;; ;;================================================================================================;;
xor eax, eax locals
fd dd ?
img_data_len dd ?
img_data dd ? ; raw bytes
img dd ? ; Image pointer
endl
DEBUGF 2, 'img.from_file: %s\n', [_filename]
push ebx
mov [img], 0
invoke file.open, [_filename], O_READ
mov [fd], eax
test eax, eax
jz .exit
invoke file.size, [_filename]
test eax, eax
jnz .exit_close
mov [img_data_len], ebx
invoke mem.alloc, ebx
test eax, eax
jz .exit_close
mov [img_data], eax
invoke file.read, [fd], eax, [img_data_len]
cmp eax, -1
jz .exit_free_close
cmp eax, [img_data_len]
jnz .exit_free_close
stdcall img.decode, [img_data], [img_data_len], 0
test eax, eax
jz .exit_free_close
mov [img], eax
.exit_free_close:
invoke mem.free, [img_data]
.exit_close:
invoke file.close, [fd]
mov eax, [img]
.exit:
pop ebx
ret ret
endp endp
@ -2439,18 +2478,6 @@ img.formats_table:
.z80 dd LIBIMG_FORMAT_Z80, img.is.z80, img.decode.z80, img.encode.z80, 0 ;this must be the last entry as there are no signatures in z80 screens at all .z80 dd LIBIMG_FORMAT_Z80, img.is.z80, img.decode.z80, img.encode.z80, 0 ;this must be the last entry as there are no signatures in z80 screens at all
dd 0 dd 0
align 4
img.types_table: ; entries order must correspond to type defnitions in libimg.inc
dd 0 ; there is no Image.bpp* = 0
.bpp8i dd (1 SHL Image.bpp24)
.bpp24 dd (1 SHL Image.bpp24) OR (1 SHL Image.bpp8g)
.bpp32 dd (1 SHL Image.bpp24)
.bpp15 dd (1 SHL Image.bpp24)
.bpp16 dd (1 SHL Image.bpp24)
.bpp1 dd (1 SHL Image.bpp24)
.bpp8g dd (1 SHL Image.bpp24) OR (1 SHL Image.bpp1 ) OR (1 SHL Image.bpp8g)
.bpp8a dd (1 SHL Image.bpp24)
;;================================================================================================;; ;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;; ;;================================================================================================;;
@ -2717,6 +2744,8 @@ img._.get_scanline_len: ;///////////////////////////////////////////////////////
;;////////////////////////////////////////////////////////////////////////////////////////////////;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;; ;;================================================================================================;;
include_debug_strings
align 4 align 4
type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4 type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4
img._.do_rgb.handlers: img._.do_rgb.handlers:
@ -2786,7 +2815,10 @@ export \
align 16 align 16
@IMPORT: @IMPORT:
library archiver, 'archiver.obj' library \
archiver, 'archiver.obj', \
libio , 'libio.obj'
import archiver, \ import archiver, \
deflate_unpack2, 'deflate_unpack2',\ deflate_unpack2, 'deflate_unpack2',\
deflateInit2, 'deflateInit2',\ deflateInit2, 'deflateInit2',\
@ -2795,6 +2827,12 @@ import archiver, \
deflateEnd, 'deflateEnd',\ deflateEnd, 'deflateEnd',\
calc_crc32, 'calc_crc32' calc_crc32, 'calc_crc32'
import libio , \
file.size , 'file_size' , \
file.open , 'file_open' , \
file.read , 'file_read' , \
file.close, 'file_close'
align 4 align 4
; mutex for unpacker loading ; mutex for unpacker loading
deflate_loader_mutex dd 0 deflate_loader_mutex dd 0