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 ;;
;< 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 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]
test eax, eax
jz .error
cmp dword[esp + 4], 0
cmp [img], 0
jnz @f
mov [esp + 4], eax
mov [img], eax
@@:
mov ecx, [esp]
mov ecx, [prev]
jecxz @f
mov [ecx + Image.Next], eax
mov [eax + Image.Previous], ecx
@@:
mov [prev], eax
push [ebx + Image.Flags]
pop [eax + Image.Flags]
push [ebx + Image.Delay]
pop [eax + Image.Delay]
mov [eax + Image.Previous], ecx
mov [esp], eax
mov ebx, [ebx + Image.Next]
test ebx, ebx
jnz .loop
.quit:
pop eax eax edi esi ebx
ret
mov eax, [img]
.error:
pop eax eax edi esi ebx
pop edi esi ebx
ret
endp
@ -86,65 +90,44 @@ proc img.convert.layer _src, _dst, _dst_type, _flags, _param
;< ecx = error code / undefined ;;
;;================================================================================================;;
locals
width rd 1
height rd 1
fun rd 1
endl
push ebx esi edi
mov ebx, [_src]
mov eax, 1
mov ecx, [_dst_type]
shl eax, cl
mov ecx, [ebx + Image.Type]
test eax, [img.types_table + 4*ecx]
mov eax, [ebx + Image.Type]
mov esi, [img.convert.table + 4*eax]
.next:
lodsd
test eax, eax
jnz @f
mov ecx, LIBIMG_ERROR_BIT_DEPTH
jmp .error
jmp .exit
@@:
cmp eax, [_dst_type]
lodsd
jnz .next
mov [fun], eax
mov eax, [_dst]
test eax, eax
jnz @f
stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], [_dst_type]
test eax, eax
jz .error
jz .exit
mov [_dst], eax
@@:
mov edi, [eax + Image.Data]
mov esi, [ebx + Image.Data]
mov eax, [ebx + Image.Type]
cmp eax, Image.bpp8i
je .bpp8i
cmp eax, Image.bpp8g
je .bpp8g
cmp eax, Image.bpp24
je .bpp24
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
stdcall [fun], [_src], [_dst]
mov eax, [_dst]
.exit:
pop edi esi ebx
ret
endp
.find_in_table_and_jump:
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:
proc img._.convert.bpp8i_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@ -165,15 +148,28 @@ endl
mov [edi], ax
shr eax, 16
mov [edi + 2], al
mov eax, [_dst]
jmp .quit
ret
endp
proc img._.convert.bpp8i_to_bpp32 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
.bpp8g:
mov edx, img.convert.bpp8g.table
jmp .find_in_table_and_jump
.bpp8g_to_bpp1:
mov ebx, [ebx + Image.Palette]
@@:
movzx eax, byte[esi]
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, [eax + Image.Palette]
mov dword[eax], 0x00000000
@ -205,17 +201,10 @@ endl
@@:
dec edx
jnz .bpp8g_to_bpp1.line
mov eax, [_dst]
jmp .quit
ret
endp
.bpp8g_to_bpp8g:
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
rep movsb
mov eax, [_dst]
jmp .quit
.bpp8g_to_bpp24:
proc img._.convert.bpp8g_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@@:
@ -227,13 +216,11 @@ endl
add edi, 3
sub ecx, 1
jnz @b
mov eax, [_dst]
jmp .quit
ret
endp
.bpp24:
mov edx, img.convert.bpp24.table
jmp .find_in_table_and_jump
.bpp24_to_bpp24:
proc img._.convert.bpp24_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
lea ecx, [ecx*3]
@ -243,9 +230,11 @@ endl
mov ecx, edx
and ecx, 3
rep movsb
mov eax, [_dst]
jmp .quit
.bpp24_to_bpp8g:
ret
endp
proc img._.convert.bpp24_to_bpp8g _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@@:
@ -261,9 +250,11 @@ endl
add edi, 1
sub ecx, 1
jnz @b
mov eax, [_dst]
jmp .quit
.bpp24_to_bpp32:
ret
endp
proc img._.convert.bpp24_to_bpp32 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@@:
@ -274,14 +265,11 @@ endl
stosd
dec ecx
jnz @b
mov eax, [_dst]
jmp .quit
ret
endp
.bpp32:
mov edx, img.convert.bpp32.table
jmp .find_in_table_and_jump
.bpp32_to_bpp24:
proc img._.convert.bpp32_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@@:
@ -293,14 +281,19 @@ endl
add edi, 3
sub ecx, 1
jnz @b
mov eax, [_dst]
jmp .quit
ret
endp
.bpp15:
mov edx, img.convert.bpp15.table
jmp .find_in_table_and_jump
.bpp15_to_bpp24:
proc img._.convert.bpp32_to_bpp32 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
rep movsd
ret
endp
proc img._.convert.bpp15_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@ -420,11 +413,12 @@ end repeat
jnb .bpp15.amd.loop
jmp .bpp15.tail
.quit:
ret
endp
.bpp16:
mov edx, img.convert.bpp16.table
jmp .find_in_table_and_jump
.bpp16_to_bpp24:
proc img._.convert.bpp16_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
.bpp16.intel:
@ -542,11 +536,16 @@ end repeat
jnb .bpp16.amd.loop
jmp .bpp16.tail
.quit:
ret
endp
.bpp1:
mov edx, img.convert.bpp1.table
jmp .find_in_table_and_jump
.bpp1_to_bpp24:
proc img._.convert.bpp1_to_bpp24 _src, _dst
locals
width rd 1
height rd 1
endl
push [ebx + Image.Width]
pop [width]
push [ebx + Image.Height]
@ -577,14 +576,11 @@ end repeat
jnz .bpp1_to_bpp24.bit
jmp .bpp1_to_bpp24.byte
.bpp1.done:
mov eax, [_dst]
jmp .quit
ret
endp
.bpp8a:
mov edx, img.convert.bpp8a.table
jmp .find_in_table_and_jump
.bpp8a_to_bpp1:
proc img._.convert.bpp8a_to_bpp1 _src, _dst
mov eax, [_dst]
mov eax, [eax + Image.Palette]
mov dword[eax], 0x00000000
@ -616,10 +612,11 @@ end repeat
@@:
dec edx
jnz .bpp8a_to_bpp1.line
mov eax, [_dst]
jmp .quit
ret
endp
.bpp8a_to_bpp24:
proc img._.convert.bpp8a_to_bpp24 _src, _dst
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@@:
@ -631,35 +628,53 @@ end repeat
add edi, 3
sub ecx, 1
jnz @b
mov eax, [_dst]
jmp .quit
.error:
xor eax, eax
.quit:
pop edi esi ebx
ret
endp
img.convert.bpp8i.table:
dd Image.bpp24, img.convert.layer.bpp8i_to_bpp24
img.convert.bpp8g.table:
dd Image.bpp24, img.convert.layer.bpp8g_to_bpp24
dd Image.bpp8g, img.convert.layer.bpp8g_to_bpp8g
dd Image.bpp1, img.convert.layer.bpp8g_to_bpp1
dd Image.bpp24, img._.convert.bpp8i_to_bpp24
dd Image.bpp32, img._.convert.bpp8i_to_bpp32
dd 0
img.convert.bpp24.table:
dd Image.bpp24, img.convert.layer.bpp24_to_bpp24
dd Image.bpp8g, img.convert.layer.bpp24_to_bpp8g
dd Image.bpp32, img.convert.layer.bpp24_to_bpp32
dd Image.bpp24, img._.convert.bpp24_to_bpp24
dd Image.bpp8g, img._.convert.bpp24_to_bpp8g
dd Image.bpp32, img._.convert.bpp24_to_bpp32
dd 0
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:
dd Image.bpp24, img.convert.layer.bpp15_to_bpp24
dd Image.bpp24, img._.convert.bpp15_to_bpp24
dd 0
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:
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:
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 '../../../../macros.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
include 'libimg.inc'
@ -124,13 +127,49 @@ endp
;;================================================================================================;;
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 ;;
;;================================================================================================;;
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
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
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
type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4
img._.do_rgb.handlers:
@ -2786,7 +2815,10 @@ export \
align 16
@IMPORT:
library archiver, 'archiver.obj'
library \
archiver, 'archiver.obj', \
libio , 'libio.obj'
import archiver, \
deflate_unpack2, 'deflate_unpack2',\
deflateInit2, 'deflateInit2',\
@ -2795,6 +2827,12 @@ import archiver, \
deflateEnd, 'deflateEnd',\
calc_crc32, 'calc_crc32'
import libio , \
file.size , 'file_size' , \
file.open , 'file_open' , \
file.read , 'file_read' , \
file.close, 'file_close'
align 4
; mutex for unpacker loading
deflate_loader_mutex dd 0