img.scale and img.convert fix for multiframe images

new function: img.get_scaled_size


git-svn-id: svn://kolibrios.org@6807 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Ivan Baravy 2016-12-22 23:29:25 +00:00
parent c299820b03
commit 741b6ad89c
4 changed files with 3721 additions and 3519 deletions

View File

@ -17,15 +17,70 @@
;; ;;
;;================================================================================================;;
;;================================================================================================;;
proc img.convert _src, _dst, _dst_type, _flags, _param ;;
;;------------------------------------------------------------------------------------------------;;
;? scale _image ;;
;? convert _image ;;
;;------------------------------------------------------------------------------------------------;;
;> [_src] = pointer to source image ;;
;> [_dst] = pointer to destination image, or 0 to create a new one ;;
;> [_dst_type] = Image.Type of resulting image ;;
;> [_flags] = see libimg.inc ;;
;> [_dst_type] = the Image.Type of converted image ;;
;> [_dst] = pointer to destination image, if any ;;
;> [_param] = depends on _flags fields, see libimg.inc ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 / pointer to converted image ;;
;< ecx = error code / undefined ;;
;;================================================================================================;;
push ebx esi edi 0 0
mov ebx, [_src]
@@:
mov eax, [ebx + Image.Previous]
test eax, eax
jz .loop
mov ebx, eax
jmp @b
.loop:
stdcall img.convert.layer, ebx, [_dst], [_dst_type], [_flags], [_param]
test eax, eax
jz .error
cmp dword[esp + 4], 0
jnz @f
mov [esp + 4], eax
@@:
mov ecx, [esp]
jecxz @f
mov [ecx + Image.Next], 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
.error:
pop eax eax edi esi ebx
ret
endp
;;================================================================================================;;
proc img.convert.layer _src, _dst, _dst_type, _flags, _param ;;
;;------------------------------------------------------------------------------------------------;;
;? convert _image layer ;;
;;------------------------------------------------------------------------------------------------;;
;> [_src] = pointer to source image ;;
;> [_dst] = pointer to destination image, or 0 to create a new one ;;
;> [_dst_type] = Image.Type of resulting image ;;
;> [_flags] = see libimg.inc ;;
;> [_param] = depends on _flags fields, see libimg.inc ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 / pointer to converted image ;;
;< ecx = error code / undefined ;;
@ -34,6 +89,8 @@ locals
width rd 1
height rd 1
endl
push ebx esi edi
mov ebx, [_src]
mov eax, 1
mov ecx, [_dst_type]
@ -151,6 +208,13 @@ endl
mov eax, [_dst]
jmp .quit
.bpp8g_to_bpp8g:
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]
imul ecx, [ebx + Image.Height]
@ -199,6 +263,19 @@ endl
jnz @b
mov eax, [_dst]
jmp .quit
.bpp24_to_bpp32:
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
@@:
lodsw
ror eax, 16
lodsb
rol eax, 16
stosd
dec ecx
jnz @b
mov eax, [_dst]
jmp .quit
.bpp32:
@ -561,25 +638,28 @@ end repeat
.error:
xor eax, eax
.quit:
pop edi esi ebx
ret
endp
img.convert.bpp8i.table:
dd Image.bpp24, img.convert.bpp8i_to_bpp24
dd Image.bpp24, img.convert.layer.bpp8i_to_bpp24
img.convert.bpp8g.table:
dd Image.bpp24, img.convert.bpp8g_to_bpp24
dd Image.bpp1, img.convert.bpp8g_to_bpp1
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
img.convert.bpp24.table:
dd Image.bpp24, img.convert.bpp24_to_bpp24
dd Image.bpp8g, img.convert.bpp24_to_bpp8g
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
img.convert.bpp32.table:
dd Image.bpp24, img.convert.bpp32_to_bpp24
dd Image.bpp24, img.convert.layer.bpp32_to_bpp24
img.convert.bpp15.table:
dd Image.bpp24, img.convert.bpp15_to_bpp24
dd Image.bpp24, img.convert.layer.bpp15_to_bpp24
img.convert.bpp16.table:
dd Image.bpp24, img.convert.bpp16_to_bpp24
dd Image.bpp24, img.convert.layer.bpp16_to_bpp24
img.convert.bpp1.table:
dd Image.bpp24, img.convert.bpp1_to_bpp24
dd Image.bpp24, img.convert.layer.bpp1_to_bpp24
img.convert.bpp8a.table:
dd Image.bpp24, img.convert.bpp8a_to_bpp24
dd Image.bpp24, img.convert.layer.bpp8a_to_bpp24

View File

@ -49,7 +49,6 @@ include 'xbm/xbm.asm'
include 'scale.asm'
include 'convert.asm'
;include 'transform.asm'
;;================================================================================================;;
proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
@ -186,7 +185,10 @@ endp
;;================================================================================================;;
proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? decodes image data into RGB triplets and returns pointer to memory area containing them ;;
;? decodes image data into RGB triplets and returns pointer to memory area of following structure:;;
;? width dd ? ;;
;? height dd ? ;;
;? rgb triplets ;;
;;------------------------------------------------------------------------------------------------;;
;> [_img] = pointer to source image ;;
;;------------------------------------------------------------------------------------------------;;
@ -696,13 +698,13 @@ proc img.encode _img, _common, _specific ;//////////////////////////////////////
;? encode image to some format ;;
;;------------------------------------------------------------------------------------------------;;
;> [_img] = pointer to input image ;;
;> [_common] = some most important options ;;
;> [_common] = some most important/common options ;;
; 0x00 : byte : format id (defined in libimg.inc) ;;
; 0x01 : byte : fast encoding (0) / best compression ratio (255) ;;
; 0 : store uncompressed data (if supported both by the format and libimg) ;;
; 1 - 255 : use compression, if supported ;;
; this option may be ignored if any format specific options are defined ;;
; i.e. the 0 here will be ignored if some compression algorithm is specified ;;
; i.e. 0 here will be ignored if particular compression algorithm is specified ;;
; 0x02 : byte : flags (bitfield) ;;
; 0x01 : return an error if format specific conditions cannot be met ;;
; 0x02 : preserve current bit depth. means 8bpp/16bpp/24bpp and so on ;;
@ -2301,6 +2303,9 @@ endl
.flip:
stdcall img.flip.layer, [_img], FLIP_VERTICAL
test eax, eax
jz .error
jmp .exit
.exchange_dims:
@ -2443,7 +2448,7 @@ img.types_table: ; entries order must correspond to type defnitions in libimg.in
.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 )
.bpp8g dd (1 SHL Image.bpp24) OR (1 SHL Image.bpp1 ) OR (1 SHL Image.bpp8g)
.bpp8a dd (1 SHL Image.bpp24)
;;================================================================================================;;
@ -2656,11 +2661,12 @@ endp
;;================================================================================================;;
img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? --- TBD --- ;;
;? Get scanline length of image in bytes ;;
;;------------------------------------------------------------------------------------------------;;
;> --- TBD --- ;;
;> eax = width of image in pixels ;;
;> ebx = image ;;
;;------------------------------------------------------------------------------------------------;;
;< --- TBD --- ;;
;< eax = scanline length in bytes ;;
;;================================================================================================;;
cmp [ebx + Image.Type], Image.bpp1
jz .bpp1.1
@ -2761,7 +2767,7 @@ export \
img.encode , 'img_encode' , \
img.create , 'img_create' , \
img.destroy , 'img_destroy' , \
img.destroy.layer, 'img_destroy_layer', \
img.destroy.layer , 'img_destroy_layer' , \
img.count , 'img_count' , \
img.lock_bits , 'img_lock_bits' , \
img.unlock_bits , 'img_unlock_bits' , \
@ -2771,8 +2777,9 @@ export \
img.rotate.layer , 'img_rotate_layer' , \
img.draw , 'img_draw' , \
img.scale , 'img_scale' , \
img.get_scaled_size, 'img_get_scaled_size', \
img.convert , 'img_convert' , \
img.formats_table, 'img_formats_table'
img.formats_table , 'img_formats_table'
; import from deflate unpacker
; is initialized only when PNG loading is requested

View File

@ -34,10 +34,13 @@ LIBIMG_FORMAT_XBM = 13
LIBIMG_FORMAT_Z80 = 14
; scale type ; corresponding img.scale params
LIBIMG_SCALE_NONE = 0 ; do not scale
LIBIMG_SCALE_INTEGER = 1 ; scale factor ; reserved 0
LIBIMG_SCALE_TILE = 2 ; new width ; new height
LIBIMG_SCALE_STRETCH = 3 ; new width ; new height
LIBIMG_SCALE_FIT_RECT = 4 ; new width ; new height
LIBIMG_SCALE_FIT_BOTH = LIBIMG_SCALE_STRETCH
LIBIMG_SCALE_FIT_MIN = 4 ; new width ; new height
LIBIMG_SCALE_FIT_RECT = LIBIMG_SCALE_FIT_MIN
LIBIMG_SCALE_FIT_WIDTH = 5 ; new width ; new height
LIBIMG_SCALE_FIT_HEIGHT = 6 ; new width ; new height
LIBIMG_SCALE_FIT_MAX = 7 ; new width ; new height
@ -62,13 +65,13 @@ LIBIMG_ERROR_NOT_INPLEMENTED = 9
LIBIMG_ERROR_INVALID_INPUT = 10
; encode flags (byte 0x02 of _common option)
LIBIMG_ENCODE_STRICT_SPECIFIC = 0x01
;LIBIMG_ENCODE_STRICT_SPECIFIC = 0x01
LIBIMG_ENCODE_STRICT_BIT_DEPTH = 0x02
LIBIMG_ENCODE_DELETE_ALPHA = 0x08
LIBIMG_ENCODE_FLUSH_ALPHA = 0x10
;LIBIMG_ENCODE_DELETE_ALPHA = 0x08
;LIBIMG_ENCODE_FLUSH_ALPHA = 0x10
; convert flags
; TBD
; none so far
struct FormatsTableEntry
Format_id dd ?

View File

@ -17,6 +17,89 @@
;; ;;
;;================================================================================================;;
;;================================================================================================;;
proc img.get_scaled_size _width, _height, _scale_type, _param1, _param2 ;;
;;------------------------------------------------------------------------------------------------;;
;? calculate resulting width and height if image of _width and _height is scaled via _scale_type ;;
;;------------------------------------------------------------------------------------------------;;
;> [_width] = width of input image ;;
;> [_height] = height of input image ;;
;> [_scale_type] = see libimg.inc (LIBIMG_SCALE_*) ;;
;> [_param1] = depends on _scale_type, see libimg.inc ;;
;> [_param2] = depends on _scale_type, see libimg.inc ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = width ;;
;< ecx = height ;;
;;================================================================================================;;
push ebx esi edi
mov eax, [_scale_type]
cmp eax, LIBIMG_SCALE_FIT_MIN
jz .fit_min
.fit_min:
xor edx, edx
mov eax, [_width]
shl eax, 1
mov ecx, [_param1]
add eax, ecx
shl eax, 15
div ecx
mov ebx, eax
xor edx, edx
mov eax, [_height]
shl eax, 1
mov ecx, [_param2]
add eax, ecx
shl eax, 15
div ecx
cmp eax, ebx
ja .fit_height
jmp .fit_width
jmp .quit
.fit_max:
jmp .quit
.fit_width:
xor edx, edx
mov eax, [_width]
shl eax, 16
div [_param1]
mov ecx, eax
xor edx, edx
mov eax, [_height]
shl eax, 16
mov ebx, ecx
shr ebx, 1
add eax, ebx
div ecx
mov ecx, eax
mov eax, [_param1]
jmp .quit
.fit_height:
xor edx, edx
mov eax, [_height]
shl eax, 16
div [_param2]
mov ecx, eax
xor edx, edx
mov eax, [_width]
shl eax, 16
mov ebx, ecx
shr ebx, 1
add eax, ebx
div ecx
mov ecx, [_param2]
jmp .quit
.quit:
pop edi esi ebx
ret
endp
;;================================================================================================;;
proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale, _inter, _param1, _param2 ;;
;;------------------------------------------------------------------------------------------------;;
@ -27,11 +110,68 @@ proc img.scale _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale,
;> [_crop_y] = top coord of cropping rect ;;
;> [_crop_width] = width of cropping rect ;;
;> [_crop_height] = height of cropping rect ;;
;> [_dst] = pointer to resulting image / 0 ;;
;> [_scale] = how to change width and height. see libimg.inc ;;
;> [_inter] = interpolation algorithm ;;
;> [_param1] = see libimg.inc ;;
;> [_param2] = see libimg.inc ;;
;> [_dst] = pointer to resulting image, 0 to create new one ;;
;> [_scale] = scaling method, see libimg.inc (LIBIMG_SCALE_*) ;;
;> [_inter] = interpolation algorithm, see libimg.inc (LIBIMG_INTER_*) ;;
;> [_param1] = depends on _scale, see libimg.inc ;;
;> [_param2] = depends on _scale, see libimg.inc ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 / pointer to scaled image ;;
;< ecx = error code / undefined ;;
;;================================================================================================;;
push ebx esi edi 0 0
mov ebx, [_src]
@@:
mov eax, [ebx + Image.Previous]
test eax, eax
jz .loop
mov ebx, eax
jmp @b
.loop:
stdcall img.scale.layer, ebx, [_crop_x], [_crop_y], [_crop_width], [_crop_height], [_dst], [_scale], [_inter], [_param1], [_param2]
test eax, eax
jz .error
cmp dword[esp + 4], 0
jnz @f
mov [esp + 4], eax
@@:
mov ecx, [esp]
jecxz @f
mov [ecx + Image.Next], 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
.error:
pop eax eax edi esi ebx
ret
endp
;;================================================================================================;;
proc img.scale.layer _src, _crop_x, _crop_y, _crop_width, _crop_height, _dst, _scale, _inter, _param1, _param2 ;;
;;------------------------------------------------------------------------------------------------;;
;? scale _image layer ;;
;;------------------------------------------------------------------------------------------------;;
;> [_src] = pointer to source image ;;
;> [_crop_x] = left coord of cropping rect ;;
;> [_crop_y] = top coord of cropping rect ;;
;> [_crop_width] = width of cropping rect ;;
;> [_crop_height] = height of cropping rect ;;
;> [_dst] = pointer to resulting image, 0 to create new one ;;
;> [_scale] = scaling method, see libimg.inc (LIBIMG_SCALE_*) ;;
;> [_inter] = interpolation algorithm, see libimg.inc (LIBIMG_INTER_*) ;;
;> [_param1] = depends on _scale, see libimg.inc ;;
;> [_param2] = depends on _scale, see libimg.inc ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 / pointer to scaled image ;;
;< ecx = error code / undefined ;;
@ -63,6 +203,7 @@ locals
rem_x rd 1
rem_y rd 1
endl
push ebx esi edi
mov ebx, [_src]
push [ebx + Image.Width]
pop [src_width_pixels]
@ -127,69 +268,13 @@ endl
.scale_type.tile:
jmp .tile
.scale_type.fit_rect:
mov eax, [_param1]
shl eax, 16
add eax, 0x00008000
xor edx, edx
div [src_width_pixels]
mov ebx, eax
mov eax, [_param2]
shl eax, 16
add eax, 0x00008000
xor edx, edx
div [src_height_pixels]
mov ecx, eax
cmp ebx, ecx
jb @f
mov ebx, ecx
@@:
jmp .scale_type.fit_common
.scale_type.fit_max:
mov eax, [_param1]
shl eax, 16
add eax, 0x00008000
xor edx, edx
div [src_width_pixels]
mov ebx, eax
mov eax, [_param2]
shl eax, 16
add eax, 0x00008000
xor edx, edx
div [src_height_pixels]
mov ecx, eax
cmp ebx, ecx
ja @f
mov ebx, ecx
@@:
jmp .scale_type.fit_common
.scale_type.fit_width:
mov eax, [_param1]
shl eax, 16
add eax, 0x00008000
xor edx, edx
div [src_width_pixels]
mov ebx, eax
jmp .scale_type.fit_common
.scale_type.fit_height:
mov eax, [_param2]
shl eax, 16
add eax, 0x00008000
xor edx, edx
div [src_height_pixels]
mov ebx, eax
jmp .scale_type.fit_common
.scale_type.fit_common:
mov eax, [src_width_pixels]
mul ebx
shr eax, 16
mov [dst_width_pixels], eax
imul eax, [bytes_per_pixel]
mov [dst_width_bytes], eax
mov eax, [src_height_pixels]
mul ebx
shr eax, 16
mov [dst_height_pixels], eax
jmp .define_inter
mov eax, [_src]
stdcall img.get_scaled_size, [eax + Image.Width], [eax + Image.Height], [_scale], [_param1], [_param2]
mov [_param1], eax
mov [_param2], ecx
.scale_type.stretch:
mov eax, [_param1]
mov [dst_width_pixels], eax
@ -222,6 +307,15 @@ endl
test eax, eax
jz .error
mov [_dst], eax
mov edi, [_src]
push [edi + Image.Flags]
pop [eax + Image.Flags]
push [edi + Image.Delay]
pop [eax + Image.Delay]
push [edi + Image.Previous]
pop [eax + Image.Previous]
push [edi + Image.Next]
pop [eax + Image.Next]
@@:
mov edi, [eax + Image.Data]
mov [dst_data], edi
@ -380,6 +474,15 @@ endl
test eax, eax
jz .error
mov [_dst], eax
mov edi, [_src]
push [edi + Image.Flags]
pop [eax + Image.Flags]
push [edi + Image.Delay]
pop [eax + Image.Delay]
push [edi + Image.Previous]
pop [eax + Image.Previous]
push [edi + Image.Next]
pop [eax + Image.Next]
@@:
mov edi, [eax + Image.Data]
mov [dst_data], edi
@ -435,6 +538,15 @@ endl
test eax, eax
jz .error
mov [_dst], eax
mov edi, [_src]
push [edi + Image.Flags]
pop [eax + Image.Flags]
push [edi + Image.Delay]
pop [eax + Image.Delay]
push [edi + Image.Previous]
pop [eax + Image.Previous]
push [edi + Image.Next]
pop [eax + Image.Next]
@@:
mov edi, [eax + Image.Data]
mov [dst_data], edi
@ -705,7 +817,7 @@ end repeat
.error:
xor eax, eax
.quit:
pop edi esi ebx
ret
endp