diff --git a/programs/develop/libraries/libs-dev/libimg/convert.asm b/programs/develop/libraries/libs-dev/libimg/convert.asm
index 398b73c552..c91d639fca 100644
--- a/programs/develop/libraries/libs-dev/libimg/convert.asm
+++ b/programs/develop/libraries/libs-dev/libimg/convert.asm
@@ -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
diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.asm b/programs/develop/libraries/libs-dev/libimg/libimg.asm
index d2228b720d..556fbc75f2 100644
--- a/programs/develop/libraries/libs-dev/libimg/libimg.asm
+++ b/programs/develop/libraries/libs-dev/libimg/libimg.asm
@@ -1,2811 +1,2818 @@
-;;================================================================================================;;
-;;//// libimg.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009, (c) dunkaist, 2011-2013 ///////;;
-;;================================================================================================;;
-;; ;;
-;; 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 . ;;
-;; ;;
-;;================================================================================================;;
-
-
-format MS COFF
-
-public @EXPORT as 'EXPORTS'
-
-include '../../../../struct.inc'
-include '../../../../proc32.inc'
-include '../../../../macros.inc'
-include '../../../../config.inc'
-;include '../../../../debug.inc'
-purge section,mov,add,sub
-
-include 'libimg.inc'
-
-section '.flat' code readable align 16
-
-include 'bmp/bmp.asm'
-include 'gif/gif.asm'
-include 'jpeg/jpeg.asm'
-include 'png/png.asm'
-include 'tga/tga.asm'
-include 'z80/z80.asm'
-include 'ico_cur/ico_cur.asm'
-include 'pcx/pcx.asm'
-include 'xcf/xcf.asm'
-include 'tiff/tiff.asm'
-include 'pnm/pnm.asm'
-include 'wbmp/wbmp.asm'
-include 'xbm/xbm.asm'
-
-include 'scale.asm'
-include 'convert.asm'
-;include 'transform.asm'
-
-;;================================================================================================;;
-proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? Library entry point (called after library load) ;;
-;;------------------------------------------------------------------------------------------------;;
-;> eax = pointer to memory allocation routine ;;
-;> ebx = pointer to memory freeing routine ;;
-;> ecx = pointer to memory reallocation routine ;;
-;> edx = pointer to library loading routine ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 1 (fail) / 0 (ok) (library initialization result) ;;
-;;================================================================================================;;
- mov [mem.alloc], eax
- mov [mem.free], ebx
- mov [mem.realloc], ecx
- mov [dll.load], edx
-
- or edx,edx
- jz @f
- invoke dll.load, @IMPORT
- @@:
-
- 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
-
-;;================================================================================================;;
-proc img.is_img _data, _length ;//////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< --- TBD --- ;;
-;;================================================================================================;;
- push ebx
- mov ebx, img.formats_table
- @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
- or eax, eax
- jnz @f
- add ebx, sizeof.FormatsTableEntry
- cmp dword[ebx], 0
- jnz @b
- xor eax, eax
- @@: pop ebx
- ret
-endp
-
-;;================================================================================================;;
-proc img.info _data, _length ;////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< --- TBD --- ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to image ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img.to_file _img, _filename ;////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = false / true ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to image ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img.to_rgb2 _img, _out ;/////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? decodes image data into RGB triplets and stores them where [_out] points to ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_img] = pointer to source image ;;
-;> [_out] = where to store RGB triplets ;;
-;;------------------------------------------------------------------------------------------------;;
-;< none ;;
-;;================================================================================================;;
- push esi edi
- mov esi, [_img]
- stdcall img._.validate, esi
- or eax, eax
- jnz .ret
- mov edi, [_out]
- call img._.do_rgb
-.ret:
- pop edi esi
- ret
-endp
-
-;;================================================================================================;;
-proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? decodes image data into RGB triplets and returns pointer to memory area containing them ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_img] = pointer to source image ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to rgb_data (array of [rgb] triplets) ;;
-;;================================================================================================;;
- push esi edi
- mov esi, [_img]
- stdcall img._.validate, esi
- or eax, eax
- jnz .error
-
- mov esi, [_img]
- mov ecx, [esi + Image.Width]
- imul ecx, [esi + Image.Height]
- lea eax, [ecx * 3 + 4 * 3]
- invoke mem.alloc, eax
- or eax, eax
- jz .error
-
- mov edi, eax
- push eax
- mov eax, [esi + Image.Width]
- stosd
- mov eax, [esi + Image.Height]
- stosd
- call img._.do_rgb
- pop eax
- pop edi esi
- ret
-
- .error:
- xor eax, eax
- pop edi esi
- ret
-endp
-
-;;================================================================================================;;
-proc img._.do_rgb ;///////////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? decodes [esi + Image.Data] data into RGB triplets and stores them at [edi] ;;
-;;------------------------------------------------------------------------------------------------;;
-;> esi = pointer to source image ;;
-;> edi = pointer to memory to store RGB triplets ;;
-;;------------------------------------------------------------------------------------------------;;
-;< none ;;
-;;================================================================================================;;
- mov ecx, [esi + Image.Width]
- imul ecx, [esi + Image.Height]
- mov eax, [esi + Image.Type]
- jmp dword [.handlers + (eax-1)*4]
-
-align 16
-.bpp8i:
-; 8 BPP WITH PALETTE -> 24 BPP
- push ebx
- mov ebx, [esi + Image.Palette]
- mov esi, [esi + Image.Data]
- sub ecx, 1
- jz .bpp8i.last
-@@:
- movzx eax, byte [esi]
- add esi, 1
- mov eax, [ebx + eax*4]
- mov [edi], eax
- add edi, 3
- sub ecx, 1
- jnz @b
-.bpp8i.last:
- movzx eax, byte [esi]
- mov eax, [ebx + eax*4]
- mov [edi], ax
- shr eax, 16
- mov [edi+2], al
- pop ebx
- ret
-
-align 16
-.bpp8g:
-; 8 BPP GRAYSCALE -> 24 BPP
- mov esi, [esi + Image.Data]
-@@:
- lodsb
- mov ah, al
- stosb
- stosw
- dec ecx
- jnz @b
- ret
-;
-;align 16
-;.bpp8a: ; considered application layer, may be changed in the future
-;; 8a BPP -> 24 BPP
-; mov esi, [esi + Image.Data]
-;@@:
-; lodsw
-; mov ah, al
-; stosb
-; stosw
-; dec ecx
-; jnz @b
-; 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
-@@:
- 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]
- mov esi, [esi + Image.Data]
- shr ecx, 2
- rep movsd
- ret
-
-align 16
-.bpp32:
-; 32 BPP -> 24 BPP
- mov esi, [esi + Image.Data]
-
- @@:
- mov eax, [esi]
- mov [edi], ax
- shr eax, 16
- mov [edi+2], al
- add esi, 4
- add edi, 3
- sub ecx, 1
- jnz @b
-
- @@:
- ret
-
-align 16
-.bpp1:
- push ebx ebp
- mov ebp, [esi + Image.Width]
- mov edx, [esi + Image.Height]
- shl edx, 16
- mov ebx, [esi + Image.Palette]
- mov esi, [esi + Image.Data]
- .bpp1.pre:
- mov dx, bp
- mov ecx, 7
- .bpp1.begin:
- xor eax, eax
- bt [esi], ecx
- adc eax, 0
- mov eax, [ebx + eax*4]
- mov [edi], ax
- shr eax, 16
- mov [edi + 2], al
- add edi, 3
- dec dx
- jz .bpp1.end_line
- dec ecx
- jns .bpp1.begin
- mov ecx, 7
- inc esi
- jmp .bpp1.begin
- .bpp1.end_line:
- sub edx, 0x10000
- jz .bpp1.quit
- inc esi
- jmp .bpp1.pre
- .bpp1.quit:
- pop ebp ebx
- ret
-
-align 16
-.bpp2i:
- push ebx ebp
- mov ebp, [esi + Image.Width]
- mov edx, [esi + Image.Height]
- shl edx, 16
- mov ebx, [esi + Image.Palette]
- mov esi, [esi + Image.Data]
- .bpp2i.pre:
- mov dx, bp
- mov ecx, 3
- .bpp2i.begin:
- mov eax, 3
- shl ecx, 1
- shl eax, cl
- and al, [esi]
- shr eax, cl
- shr ecx, 1
- mov eax, [ebx + eax*4]
- mov [edi], ax
- shr eax, 16
- mov [edi + 2], al
- add edi, 3
- dec dx
- jz .bpp2i.end_line
- dec ecx
- jns .bpp2i.begin
- mov ecx, 3
- inc esi
- jmp .bpp2i.begin
- .bpp2i.end_line:
- sub edx, 0x10000
- jz .bpp2i.quit
- inc esi
- jmp .bpp2i.pre
- .bpp2i.quit:
- pop ebp ebx
- ret
-
-align 16
-.bpp4i:
- push ebx ebp
- mov ebp, [esi + Image.Width]
- mov edx, [esi + Image.Height]
- shl edx, 16
- mov ebx, [esi + Image.Palette]
- mov esi, [esi + Image.Data]
- .bpp4i.pre:
- mov dx, bp
- mov ecx, 1
- .bpp4i.begin:
- mov eax, 15
- shl ecx, 2
- shl eax, cl
- and al, [esi]
- shr eax, cl
- shr ecx, 2
- mov eax, [ebx + eax*4]
- mov [edi], ax
- shr eax, 16
- mov [edi + 2], al
- add edi, 3
- dec dx
- jz .bpp4i.end_line
- dec ecx
- jns .bpp4i.begin
- mov ecx, 1
- inc esi
- jmp .bpp4i.begin
- .bpp4i.end_line:
- sub edx, 0x10000
- jz .bpp4i.quit
- inc esi
- jmp .bpp4i.pre
- .bpp4i.quit:
- pop ebp ebx
- ret
-
-endp
-
-;;================================================================================================;;
-proc img.decode _data, _length, _options ;////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? decodes loaded into memory graphic file ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_data] = pointer to file in memory ;;
-;> [_length] = size in bytes of memory area pointed to by [_data] ;;
-;> [_options] = 0 / pointer to the structure of additional options ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to image ;;
-;;================================================================================================;;
- push ebx
- mov ebx, img.formats_table
- @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
- or eax, eax
- jnz @f
- add ebx, sizeof.FormatsTableEntry
- cmp dword[ebx], eax ;0
- jnz @b
- pop ebx
- ret
- @@: mov eax, [ebx + FormatsTableEntry.Decode]
- pop ebx
- leave
- jmp eax
-endp
-
-;;================================================================================================;;
-proc img.encode _img, _common, _specific ;////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? encode image to some format ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_img] = pointer to input image ;;
-;> [_common] = some most important 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 ;;
-; 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 ;;
-; 0x04 : delete alpha channel, if any ;;
-; 0x08 : flush alpha channel with 0xff, if any; add it if none ;;
-; 0x03 : byte : reserved, must be 0 ;;
-;> [_specific] = 0 / pointer to the structure of format specific options ;;
-; see .inc for description ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to encoded data ;;
-;< ecx = error code / the size of encoded data ;;
-; 1 : out of memory ;;
-; 2 : format is not supported ;;
-; 3 : specific conditions cannot be satisfied ;;
-; 4 : bit depth cannot be preserved ;;
-;;================================================================================================;;
- mov ebx, [_img]
-
- movzx eax, byte[_common]
- dec eax
- imul eax, sizeof.FormatsTableEntry
- add eax, FormatsTableEntry.Capabilities
- add eax, img.formats_table
- mov eax, [eax]
- test eax, 1 ; is encoding to this format supported at all?
- jnz @f
- mov ecx, LIBIMG_ERROR_FORMAT
- jmp .error
- @@:
- mov ecx, [ebx + Image.Type]
- mov edx, 1
- shl edx, cl
- test eax, edx
- jnz .bit_depth_ok
- test byte[_common+2], LIBIMG_ENCODE_STRICT_BIT_DEPTH
- jz @f
- mov ecx, LIBIMG_ERROR_BIT_DEPTH
- jmp .error
- @@:
- mov edx, 1 SHL Image.bpp24
- test eax, edx
- jnz @f
- mov ecx, LIBIMG_ERROR_BIT_DEPTH
- jmp .error
- @@:
- stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], Image.bpp24
- test eax, eax
- jnz @f
- mov ecx, LIBIMG_ERROR_OUT_OF_MEMORY
- jmp .error
- @@:
- push eax
- stdcall img.to_rgb2, ebx, [eax + Image.Data]
- pop ebx
-
- .bit_depth_ok:
- movzx eax, byte[_common]
- dec eax
- imul eax, sizeof.FormatsTableEntry
- add eax, FormatsTableEntry.Encode
- add eax, img.formats_table
- mov eax, [eax]
- stdcall eax, [_img], [_common], [_specific]
- push eax ecx
- cmp ebx, [_img]
- je @f
- stdcall img.destroy, ebx
- @@:
- pop ecx eax
- jmp .quit
-
- .error:
- xor eax, eax
- .quit:
- ret
-endp
-
-;;================================================================================================;;
-proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? creates an Image structure and initializes some its fields ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_width] = width of an image in pixels ;;
-;> [_height] = height of an image in pixels ;;
-;> [_type] = one of the Image.bppN constants from libimg.inc ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to image ;;
-;;================================================================================================;;
- push ecx
-
- stdcall img._.new
- or eax, eax
- jz .error
-
- mov ecx, [_type]
- mov [eax + Image.Type], ecx
-
- push eax
-
- stdcall img._.resize_data, eax, [_width], [_height]
- or eax, eax
- jz .error.2
-
- pop eax
- jmp .ret
-
- .error.2:
-; pop eax
- stdcall img._.delete; eax
- xor eax, eax
-
- .error:
- .ret:
- pop ecx
- ret
-endp
-
-;;================================================================================================;;
-proc img.destroy.layer _img ;/////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? frees memory occupied by an image and all the memory regions its fields point to ;;
-;? for image sequences deletes only one frame and fixes Previous/Next pointers ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_img] = pointer to image ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 (fail) / 1 (success) ;;
-;;================================================================================================;;
- 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 ;///////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? frees memory occupied by an image and all the memory regions its fields point to ;;
-;? follows Previous/Next pointers and deletes all the images in sequence ;;
-;;------------------------------------------------------------------------------------------------;;
-;> [_img] = pointer to image ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 (fail) / 1 (success) ;;
-;;================================================================================================;;
- 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
-
-;;================================================================================================;;
-proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? Get number of images in the list (e.g. in animated GIF file) ;;
-;;------------------------------------------------------------------------------------------------;;
-;> _img = pointer to image ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = -1 (fail) / >0 (ok) ;;
-;;================================================================================================;;
- push ecx edx
- mov edx, [_img]
- stdcall img._.validate, edx
- or eax, eax
- jnz .error
-
- @@: mov eax, [edx + Image.Previous]
- or eax, eax
- jz @f
- mov edx, eax
- jmp @b
-
- @@: xor ecx, ecx
- @@: inc ecx
- mov eax, [edx + Image.Next]
- or eax, eax
- jz .exit
- mov edx, eax
- jmp @b
-
- .exit:
- mov eax, ecx
- pop edx ecx
- ret
-
- .error:
- or eax, -1
- pop edx ecx
- ret
-endp
-
-;;//// image processing //////////////////////////////////////////////////////////////////////////;;
-
-;;================================================================================================;;
-proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to bits ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = false / true ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? Flip image layer ;;
-;;------------------------------------------------------------------------------------------------;;
-;> _img = pointer to image ;;
-;> _flip_kind = one of FLIP_* constants ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = false / true ;;
-;;================================================================================================;;
-locals
- scanline_len dd ?
-endl
-
- push ebx esi edi
- mov ebx, [_img]
- stdcall img._.validate, ebx
- or eax, eax
- jnz .error
-
- mov ecx, [ebx + Image.Height]
- mov eax, [ebx + Image.Width]
- call img._.get_scanline_len
- mov [scanline_len], eax
-
- test [_flip_kind], FLIP_VERTICAL
- jz .dont_flip_vert
-
- imul eax, ecx
- sub eax, [scanline_len]
- shr ecx, 1
- mov esi, [ebx + Image.Data]
- lea edi, [esi + eax]
-
- .next_line_vert:
- push ecx
-
- mov ecx, [scanline_len]
- push ecx
- shr ecx, 2
- @@:
- dec ecx
- js @f
- mov eax, [esi]
- xchg eax, [edi]
- mov [esi], eax
- add esi, 4
- add edi, 4
- jmp @b
- @@:
-
- pop ecx
- and ecx, 3
- jz .cont_line_vert
- @@:
- mov al, [esi]
- xchg al, [edi]
- mov [esi], al
- add esi, 1
- add edi, 1
- dec ecx
- jnz @b
- .cont_line_vert:
-
- pop ecx
- mov eax, [scanline_len]
- shl eax, 1
- sub edi, eax
- dec ecx
- jnz .next_line_vert
-
- .dont_flip_vert:
-
- test [_flip_kind], FLIP_HORIZONTAL
- jz .exit
-
- mov ecx, [ebx + Image.Height]
- mov eax, [ebx + Image.Type]
- mov esi, [ebx + Image.Data]
- mov edi, [scanline_len]
- add edi, esi
- jmp dword [.handlers_horz + (eax-1)*4]
-
-.bpp32_horz:
- sub edi, 4
-
- .next_line_horz:
- push ecx esi edi
-
- mov ecx, [scanline_len]
- shr ecx, 3
- @@: mov eax, [esi]
- xchg eax, [edi]
- mov [esi], eax
- add esi, 4
- add edi, -4
- sub ecx, 1
- jnz @b
-
- pop edi esi ecx
- add esi, [scanline_len]
- add edi, [scanline_len]
- dec ecx
- jnz .next_line_horz
- jmp .exit
-
-.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
-
-.bpp8ig_horz:
- dec edi
- .next_line_horz8ig:
- push ecx esi edi
-
- mov ecx, [scanline_len]
- shr ecx, 1
- @@: mov al, [esi]
- mov dl, [edi]
- mov [edi], al
- mov [esi], dl
- add esi, 1
- sub edi, 1
- sub ecx, 1
- jnz @b
-
- pop edi esi ecx
- add esi, [scanline_len]
- add edi, [scanline_len]
- dec ecx
- jnz .next_line_horz8ig
- jmp .exit
-
-.bpp24_horz:
- sub edi, 3
- .next_line_horz24:
- push ecx esi edi
-
- mov ecx, [ebx + Image.Width]
- @@:
- mov al, [esi]
- mov dl, [edi]
- mov [edi], al
- mov [esi], dl
- mov al, [esi+1]
- mov dl, [edi+1]
- mov [edi+1], al
- mov [esi+1], dl
- mov al, [esi+2]
- mov dl, [edi+2]
- mov [edi+2], al
- mov [esi+2], dl
- add esi, 3
- sub edi, 3
- sub ecx, 2
- ja @b
-
- pop edi esi ecx
- add esi, [scanline_len]
- add edi, [scanline_len]
- dec ecx
- jnz .next_line_horz24
- jmp .exit
-
-.bpp1_horz:
- mov edi, [scanline_len]
- mov edx, [ebx + Image.Width]
- and edx, 7
- neg edx
- add edx, 8
- and edx, 7
-.bpp1_horz.begin:
- push ebx edx esi
- mov eax, 7
- add edi, esi
- sub edi, 1
- mov ebx, [ebx + Image.Width]
- shr ebx, 1
-.bpp1_horz.bit:
- bt [edi], edx
- jc @f
- btr [esi], eax
- jmp .bpp1_horz.right
- @@:
- bts [esi], eax
- .bpp1_horz.right:
- jnc @f
- bts [edi], edx
- jmp .bpp1_horz.bit_done
- @@:
- btr [edi], edx
- .bpp1_horz.bit_done:
- inc edx
- and edx, 7
- jnz @f
- dec edi
- @@:
- dec eax
- jns @f
- mov eax, 7
- inc esi
- @@:
- dec ebx
- jnz .bpp1_horz.bit
-
- pop esi edx ebx
- add esi, [scanline_len]
- mov edi, [scanline_len]
- dec ecx
- jnz .bpp1_horz.begin
- jmp .exit
-
-
-.bpp2i_horz:
- mov edi, [scanline_len]
- mov edx, [ebx + Image.Width]
- and edx, 3
- neg edx
- add edx, 4
- and edx, 3
-.bpp2i_horz.begin:
- push ebx edx esi
- mov eax, 3
- add edi, esi
- sub edi, 1
- mov ebx, [ebx + Image.Width]
- shr ebx, 1
-.bpp2i_horz.pixel:
- push ebx ecx
- mov ebx, 3
- mov ecx, edx
- shl ebx, cl
- shl ebx, cl
- and bl, [edi]
- shr ebx, cl
- shr ebx, cl
- mov bh, 3
- mov ecx, eax
- shl ebx, cl
- shl ebx, cl
- not bh
- and bh, [esi]
- or bl, bh
- mov bh, [esi]
- mov [esi], bl
- shr ebx, 8
- shr ebx, cl
- shr ebx, cl
- and ebx, 3
- mov bh, 3
- mov ecx, edx
- shl ebx, cl
- shl ebx, cl
- not bh
- and bh, [edi]
- or bl, bh
- mov [edi], bl
- pop ecx ebx
- .bpp2i_horz.pixel_done:
- inc edx
- and edx, 3
- jnz @f
- dec edi
- @@:
- dec eax
- jns @f
- mov eax, 3
- inc esi
- @@:
- dec ebx
- jnz .bpp2i_horz.pixel
-
- pop esi edx ebx
- add esi, [scanline_len]
- mov edi, [scanline_len]
- dec ecx
- jnz .bpp2i_horz.begin
- jmp .exit
-
-
-.bpp4i_horz:
- mov edi, [scanline_len]
- mov edx, [ebx + Image.Width]
- and edx, 1
- neg edx
- add edx, 2
- and edx, 1
-.bpp4i_horz.begin:
- push ebx edx esi
- mov eax, 1
- add edi, esi
- sub edi, 1
- mov ebx, [ebx + Image.Width]
- shr ebx, 1
-.bpp4i_horz.pixel:
- push ebx ecx
- mov ebx, 15
- mov ecx, edx
- shl ecx, 2
- shl ebx, cl
- and bl, [edi]
- shr ebx, cl
- mov bh, 15
- mov ecx, eax
- shl ecx, 2
- shl ebx, cl
- not bh
- and bh, [esi]
- or bl, bh
- mov bh, [esi]
- mov [esi], bl
- shr ebx, 8
- shr ebx, cl
- and ebx, 15
- mov bh, 15
- mov ecx, edx
- shl ecx, 2
- shl ebx, cl
- not bh
- and bh, [edi]
- or bl, bh
- mov [edi], bl
- pop ecx ebx
- .bpp4i_horz.pixel_done:
- inc edx
- and edx, 1
- jnz @f
- dec edi
- @@:
- dec eax
- jns @f
- mov eax, 1
- inc esi
- @@:
- dec ebx
- jnz .bpp4i_horz.pixel
-
- pop esi edx ebx
- add esi, [scanline_len]
- mov edi, [scanline_len]
- dec ecx
- jnz .bpp4i_horz.begin
- jmp .exit
-
-
- .exit:
- xor eax, eax
- inc eax
- pop edi esi ebx
- ret
-
- .error:
- xor eax, eax
- pop edi esi ebx
- ret
-endp
-
-;;================================================================================================;;
-proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? 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 ;;
-;;================================================================================================;;
-locals
- scanline_len_old dd ?
- scanline_len_new dd ?
- scanline_pixels_new dd ?
- line_buffer dd ?
- pixels_ptr dd ?
-endl
-
- mov [line_buffer], 0
-
- push ebx esi edi
- mov ebx, [_img]
- stdcall img._.validate, ebx
- or eax, eax
- jnz .error
-
- cmp [_rotate_kind], ROTATE_90_CCW
- je .rotate_ccw_low
- cmp [_rotate_kind], ROTATE_90_CW
- je .rotate_cw_low
- cmp [_rotate_kind], ROTATE_180
- je .flip
- jmp .exit
-
- .rotate_ccw_low:
- mov eax, [ebx + Image.Height]
- mov [scanline_pixels_new], eax
- call img._.get_scanline_len
- mov [scanline_len_new], eax
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- mov [line_buffer], eax
-
- mov eax, [ebx + Image.Width]
- mov ecx, eax
- call img._.get_scanline_len
- mov [scanline_len_old], eax
-
- mov eax, [scanline_len_new]
- imul eax, ecx
- add eax, [ebx + Image.Data]
- mov [pixels_ptr], eax
-
- cmp [ebx + Image.Type], Image.bpp1
- jz .rotate_ccw1
- cmp [ebx + Image.Type], Image.bpp2i
- jz .rotate_ccw2i
- cmp [ebx + Image.Type], Image.bpp4i
- jz .rotate_ccw4i
- cmp [ebx + Image.Type], Image.bpp8i
- jz .rotate_ccw8ig
- cmp [ebx + Image.Type], Image.bpp8g
- jz .rotate_ccw8ig
- 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
- push ecx
-
- mov edx, [scanline_len_old]
- add [scanline_len_old], -4
-
- mov ecx, [scanline_pixels_new]
- mov esi, [ebx + Image.Data]
- mov edi, [line_buffer]
- @@: mov eax, [esi]
- stosd
- add esi, edx
- dec ecx
- jnz @b
-
- mov eax, [scanline_pixels_new]
- mov edi, [ebx + Image.Data]
- lea esi, [edi + 4]
- mov edx, [scanline_len_old]
- shr edx, 2
- @@: mov ecx, edx
- rep movsd
- add esi, 4
- dec eax
- jnz @b
-
- mov eax, [scanline_len_new]
- sub [pixels_ptr], eax
- mov ecx, [scanline_pixels_new]
- mov esi, [line_buffer]
- mov edi, [pixels_ptr]
- rep movsd
-
- pop ecx
- jmp .next_column_ccw_low
-
-.rotate_ccw8ig:
- .next_column_ccw_low8ig:
- dec ecx
- js .exchange_dims
- push ecx
-
- mov edx, [scanline_len_old]
- add [scanline_len_old], -1
-
- mov ecx, [scanline_pixels_new]
- mov esi, [ebx + Image.Data]
- mov edi, [line_buffer]
- @@: mov al, [esi]
- mov [edi], al
- add esi, edx
- add edi, 1
- sub ecx, 1
- jnz @b
-
- mov eax, [scanline_pixels_new]
- mov edi, [ebx + Image.Data]
- lea esi, [edi + 1]
- 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_low8ig
-
-.rotate_ccw24:
- .next_column_ccw_low24:
- dec ecx
- js .exchange_dims
- push ecx
-
- mov edx, [scanline_len_old]
- add [scanline_len_old], -3
-
- mov ecx, [scanline_pixels_new]
- mov esi, [ebx + Image.Data]
- mov edi, [line_buffer]
- @@: mov al, [esi]
- mov [edi], al
- mov al, [esi+1]
- mov [edi+1], al
- mov al, [esi+2]
- mov [edi+2], al
- add esi, edx
- add edi, 3
- sub ecx, 1
- jnz @b
-
- mov eax, [scanline_pixels_new]
- mov edi, [ebx + Image.Data]
- lea esi, [edi + 3]
- 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_ccw_low24
-
-.rotate_ccw1:
- push ecx edx
-
- mov eax, [ebx + Image.Height]
- add eax, 7
- shr eax, 3
- imul eax, [ebx + Image.Width]
- push eax ; save new data size
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- push eax ; save pointer to new data
-
- mov ecx, [ebx + Image.Width]
- and ecx, 7
- neg ecx
- add ecx, 8
- and ecx, 7
-
- mov edi, eax
- mov esi, [ebx + Image.Data]
- mov eax, 7
- mov edx, [scanline_len_old]
- dec edx
- add esi, edx
-
- .rotate_ccw1.begin:
- bt [esi], ecx
- jc .rotate_ccw1.one
- .rotate_ccw1.zero:
- btr [edi], eax
- jmp @f
- .rotate_ccw1.one:
- bts [edi], eax
- @@:
- add esi, [scanline_len_old]
- dec [scanline_pixels_new]
- jz .rotate_ccw1.end_of_line
- sub eax, 1
- adc edi, 0
- and eax, 7
- jmp .rotate_ccw1.begin
- .rotate_ccw1.end_of_line:
- inc edi
- mov eax, [ebx + Image.Height]
- mov [scanline_pixels_new], eax
- mov eax, 7
- inc ecx
- and ecx, 7
- jz @f
- mov esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_ccw1.begin
- @@:
- dec edx
- js .rotate_ccw1.quit
- mov esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_ccw1.begin
- .rotate_ccw1.quit:
- pop esi ; get pointer to new data
- mov edi, [ebx + Image.Data]
- pop ecx ; get new data size
- rep movsb
- invoke mem.free, esi
- pop edx ecx
- jmp .exchange_dims
-
-
-.rotate_ccw2i:
- push ecx edx
-
- mov eax, [ebx + Image.Height]
- add eax, 3
- shr eax, 2
- imul eax, [ebx + Image.Width]
- push eax ; save new data size
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- push eax ; save pointer to new data
-
- mov ecx, [ebx + Image.Width]
- and ecx, 3
- neg ecx
- add ecx, 4
- and ecx, 3
-
- mov edi, eax
- mov esi, [ebx + Image.Data]
- mov eax, 3
- mov edx, [scanline_len_old]
- dec edx
- add esi, edx
-
- .rotate_ccw2i.begin:
- push ebx ecx
- mov ebx, 3
- shl ebx, cl
- shl ebx, cl
- and bl, [esi]
- shr ebx, cl
- shr ebx, cl
- mov bh, 3
- mov ecx, eax
- shl ebx, cl
- shl ebx, cl
- not bh
- and bh, [edi]
- or bl, bh
- mov [edi], bl
- pop ecx ebx
-
- add esi, [scanline_len_old]
- dec [scanline_pixels_new]
- jz .rotate_ccw2i.end_of_line
- sub eax, 1
- adc edi, 0
- and eax, 3
- jmp .rotate_ccw2i.begin
- .rotate_ccw2i.end_of_line:
- inc edi
- mov eax, 3
- mov esi, [ebx + Image.Height]
- mov [scanline_pixels_new], esi
- inc ecx
- and ecx, 3
- jz @f
- mov esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_ccw2i.begin
- @@:
- dec edx
- js .rotate_ccw2i.quit
- mov esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_ccw2i.begin
- .rotate_ccw2i.quit:
- pop esi ; get pointer to new data
- mov edi, [ebx + Image.Data]
- pop ecx ; get new data size
- rep movsb
- invoke mem.free, esi
- pop edx ecx
- jmp .exchange_dims
-
-
-.rotate_ccw4i:
- push ecx edx
-
- mov eax, [ebx + Image.Height]
- add eax, 1
- shr eax, 1
- imul eax, [ebx + Image.Width]
- push eax ; save new data size
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- push eax ; save pointer to new data
-
- mov ecx, [ebx + Image.Width]
- and ecx, 1
- neg ecx
- add ecx, 2
- and ecx, 1
-
- mov edi, eax
- mov esi, [ebx + Image.Data]
- mov eax, 1
- mov edx, [scanline_len_old]
- dec edx
- add esi, edx
-
- .rotate_ccw4i.begin:
- push ebx ecx
- mov ebx, 15
- shl ecx, 2
- shl ebx, cl
- and bl, [esi]
- shr ebx, cl
- mov bh, 15
- mov ecx, eax
- shl ecx, 2
- shl ebx, cl
- not bh
- and bh, [edi]
- or bl, bh
- mov [edi], bl
- pop ecx ebx
-
- add esi, [scanline_len_old]
- dec [scanline_pixels_new]
- jz .rotate_ccw4i.end_of_line
- sub eax, 1
- adc edi, 0
- and eax, 1
- jmp .rotate_ccw4i.begin
- .rotate_ccw4i.end_of_line:
- inc edi
- mov eax, 1
- mov esi, [ebx + Image.Height]
- mov [scanline_pixels_new], esi
- inc ecx
- and ecx, 1
- jz @f
- mov esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_ccw4i.begin
- @@:
- dec edx
- js .rotate_ccw4i.quit
- mov esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_ccw4i.begin
- .rotate_ccw4i.quit:
- pop esi ; get pointer to new data
- mov edi, [ebx + Image.Data]
- pop ecx ; get new data size
- rep movsb
- invoke mem.free, esi
- pop edx ecx
- jmp .exchange_dims
-
-
-
- .rotate_cw_low:
- mov eax, [ebx + Image.Height]
- mov [scanline_pixels_new], eax
- call img._.get_scanline_len
- mov [scanline_len_new], eax
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- mov [line_buffer], eax
-
- mov eax, [ebx + Image.Width]
- mov ecx, eax
- call img._.get_scanline_len
- mov [scanline_len_old], eax
-
- mov eax, [scanline_len_new]
- imul eax, ecx
- add eax, [ebx + Image.Data]
- mov [pixels_ptr], eax
-
- cmp [ebx + Image.Type], Image.bpp1
- jz .rotate_cw1
- cmp [ebx + Image.Type], Image.bpp2i
- jz .rotate_cw2i
- cmp [ebx + Image.Type], Image.bpp4i
- jz .rotate_cw4i
- cmp [ebx + Image.Type], Image.bpp8i
- jz .rotate_cw8ig
- cmp [ebx + Image.Type], Image.bpp8g
- jz .rotate_cw8ig
- 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
- push ecx
-
- mov edx, [scanline_len_old]
- add [scanline_len_old], -4
-
- mov ecx, [scanline_pixels_new]
- mov esi, [pixels_ptr]
- add esi, -4
- mov edi, [line_buffer]
- @@: mov eax, [esi]
- stosd
- sub esi, edx
- dec ecx
- jnz @b
-
- mov eax, [scanline_pixels_new]
- dec eax
- mov edi, [ebx + Image.Data]
- add edi, [scanline_len_old]
- lea esi, [edi + 4]
- mov edx, [scanline_len_old]
- shr edx, 2
- @@: mov ecx, edx
- rep movsd
- add esi, 4
- dec eax
- jnz @b
-
- mov eax, [scanline_len_new]
- sub [pixels_ptr], eax
- mov ecx, [scanline_pixels_new]
- mov esi, [line_buffer]
- mov edi, [pixels_ptr]
- rep movsd
-
- pop ecx
- jmp .next_column_cw_low
-
-.rotate_cw8ig:
- .next_column_cw_low8ig:
- dec ecx
- js .exchange_dims
- push ecx
-
- mov edx, [scanline_len_old]
- add [scanline_len_old], -1
-
- mov ecx, [scanline_pixels_new]
- mov esi, [pixels_ptr]
- add esi, -1
- mov edi, [line_buffer]
- @@: mov al, [esi]
- mov [edi], al
- sub esi, edx
- add edi, 1
- 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 + 1]
- 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, 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_low8ig
-
-.rotate_cw24:
- .next_column_cw_low24:
- dec ecx
- js .exchange_dims
- push ecx
-
- mov edx, [scanline_len_old]
- add [scanline_len_old], -3
-
- mov ecx, [scanline_pixels_new]
- mov esi, [pixels_ptr]
- add esi, -3
- mov edi, [line_buffer]
- @@: mov al, [esi]
- mov [edi], al
- mov al, [esi+1]
- mov [edi+1], al
- mov al, [esi+2]
- mov [edi+2], al
- sub esi, edx
- add edi, 3
- 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 + 3]
- 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_low24
-
-
-.rotate_cw1:
- push ecx edx
-
- mov eax, [ebx + Image.Height]
- add eax, 7
- shr eax, 3
- imul [ebx + Image.Width]
- push eax ; save new data size
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- push eax ; save pointer to new data
-
- mov edi, eax
- mov esi, [ebx + Image.Data]
- mov eax, [ebx + Image.Height]
- dec eax
- imul eax, [scanline_len_old]
- add esi, eax
- mov eax, 7
- mov ecx, 7
- mov edx, 0
-
- .rotate_cw1.begin:
- bt [esi], ecx
- jc .rotate_cw1.one
- .rotate_cw1.zero:
- btr [edi], eax
- jmp @f
- .rotate_cw1.one:
- bts [edi], eax
- @@:
- sub esi, [scanline_len_old]
- dec [scanline_pixels_new]
- jz .rotate_cw1.end_of_line
- sub eax, 1
- adc edi, 0
- and eax, 7
- jmp .rotate_cw1.begin
- .rotate_cw1.end_of_line:
- inc edi
- mov eax, [ebx + Image.Height]
- mov [scanline_pixels_new], eax
- mov eax, 7
- dec ecx
- jns @f
- mov ecx, 7
- inc edx
- cmp edx, [scanline_len_old]
- je .rotate_cw1.quit
- @@:
- mov esi, [ebx + Image.Height]
- dec esi
- imul esi, [scanline_len_old]
- add esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_cw1.begin
- .rotate_cw1.quit:
- pop eax ; get pointer to new data
- mov esi, eax
- mov edi, [ebx + Image.Data]
- pop ecx ; get new data size
- rep movsb
- invoke mem.free, eax
- pop edx ecx
- jmp .exchange_dims
-
-
-.rotate_cw2i:
- push ecx edx
-
- mov eax, [ebx + Image.Height]
- add eax, 3
- shr eax, 2
- imul [ebx + Image.Width]
- push eax ; save new data size
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- push eax ; save pointer to new data
-
- mov edi, eax
- mov esi, [ebx + Image.Data]
- mov eax, [ebx + Image.Height]
- dec eax
- imul eax, [scanline_len_old]
- add esi, eax
- mov eax, 3
- mov ecx, 3
- mov edx, 0
-
- .rotate_cw2i.begin:
- push ebx ecx
- mov ebx, 3
- shl ebx, cl
- shl ebx, cl
- and bl, [esi]
- shr ebx, cl
- shr ebx, cl
- mov bh, 3
- mov ecx, eax
- shl ebx, cl
- shl ebx, cl
- not bh
- and bh, [edi]
- or bl, bh
- mov [edi], bl
- pop ecx ebx
-
- sub esi, [scanline_len_old]
- dec [scanline_pixels_new]
- jz .rotate_cw2i.end_of_line
- sub eax, 1
- adc edi, 0
- and eax, 3
- jmp .rotate_cw2i.begin
- .rotate_cw2i.end_of_line:
- inc edi
- mov eax, [ebx + Image.Height]
- mov [scanline_pixels_new], eax
- mov eax, 3
- dec ecx
- jns @f
- mov ecx, 3
- inc edx
- cmp edx, [scanline_len_old]
- je .rotate_cw2i.quit
- @@:
- mov esi, [ebx + Image.Height]
- dec esi
- imul esi, [scanline_len_old]
- add esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_cw2i.begin
- .rotate_cw2i.quit:
- pop eax ; get pointer to new data
- mov esi, eax
- mov edi, [ebx + Image.Data]
- pop ecx ; get new data size
- rep movsb
- invoke mem.free, eax
- pop edx ecx
- jmp .exchange_dims
-
-
-.rotate_cw4i:
- push ecx edx
-
- mov eax, [ebx + Image.Height]
- add eax, 1
- shr eax, 1
- imul [ebx + Image.Width]
- push eax ; save new data size
-
- invoke mem.alloc, eax
- or eax, eax
- jz .error
- push eax ; save pointer to new data
-
- mov edi, eax
- mov esi, [ebx + Image.Data]
- mov eax, [ebx + Image.Height]
- dec eax
- imul eax, [scanline_len_old]
- add esi, eax
- mov eax, 1
- mov ecx, 1
- mov edx, 0
-
- .rotate_cw4i.begin:
- push ebx ecx
- mov ebx, 15
- shl ecx, 2
- shl ebx, cl
- and bl, [esi]
- shr ebx, cl
- mov bh, 15
- mov ecx, eax
- shl ecx, 2
- shl ebx, cl
- not bh
- and bh, [edi]
- or bl, bh
- mov [edi], bl
- pop ecx ebx
-
- sub esi, [scanline_len_old]
- dec [scanline_pixels_new]
- jz .rotate_cw4i.end_of_line
- sub eax, 1
- adc edi, 0
- and eax, 1
- jmp .rotate_cw4i.begin
- .rotate_cw4i.end_of_line:
- inc edi
- mov eax, [ebx + Image.Height]
- mov [scanline_pixels_new], eax
- mov eax, 1
- dec ecx
- jns @f
- mov ecx, 1
- inc edx
- cmp edx, [scanline_len_old]
- je .rotate_cw4i.quit
- @@:
- mov esi, [ebx + Image.Height]
- dec esi
- imul esi, [scanline_len_old]
- add esi, [ebx + Image.Data]
- add esi, edx
- jmp .rotate_cw4i.begin
- .rotate_cw4i.quit:
- pop eax ; get pointer to new data
- mov esi, eax
- mov edi, [ebx + Image.Data]
- pop ecx ; get new data size
- rep movsb
- invoke mem.free, eax
- pop edx ecx
- jmp .exchange_dims
-
-
- .flip:
- jmp .exit
-
- .exchange_dims:
- push [ebx + Image.Width] [ebx + Image.Height]
- pop [ebx + Image.Width] [ebx + Image.Height]
-
- .exit:
- invoke mem.free, [line_buffer]
- xor eax, eax
- inc eax
- pop edi esi ebx
- ret
-
- .error:
- invoke mem.free, [line_buffer]
- xor eax, eax
- pop edi esi ebx
- 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
- push eax
- mov eax, [ebx + Image.Width]
- imul eax, [_ypos]
- add eax, [_xpos]
- call img._.get_scanline_len
- add eax, [ebx + Image.Data]
- mov edx, [_x - 2]
- mov dx, word [_y]
- mov esi, [ebx + Image.Type]
- mov esi, [type2bpp + (esi-1)*4]
- mov edi, [ebx + Image.Palette]
- xchg eax, ebx
- pop eax
- push ebp
- push 65
- pop ebp
- xchg eax, ebp
- int 40h
- pop ebp
-.done:
- pop edi esi ebx
- ret
-endp
-
-
-align 4
-img.formats_table:
- .bmp dd LIBIMG_FORMAT_BMP, img.is.bmp, img.decode.bmp, img.encode.bmp, 1 + (1 SHL Image.bpp24) + (1 SHL Image.bpp32)
- .ico dd LIBIMG_FORMAT_ICO, img.is.ico, img.decode.ico_cur, img.encode.ico, 0
- .cur dd LIBIMG_FORMAT_CUR, img.is.cur, img.decode.ico_cur, img.encode.cur, 0
- .gif dd LIBIMG_FORMAT_GIF, img.is.gif, img.decode.gif, img.encode.gif, 0
- .png dd LIBIMG_FORMAT_PNG, img.is.png, img.decode.png, img.encode.png, 1 + (1 SHL Image.bpp24)
- .jpg dd LIBIMG_FORMAT_JPEG, img.is.jpg, img.decode.jpg, img.encode.jpg, 0
- .tga dd LIBIMG_FORMAT_TGA, img.is.tga, img.decode.tga, img.encode.tga, 0
- .pcx dd LIBIMG_FORMAT_PCX, img.is.pcx, img.decode.pcx, img.encode.pcx, 0
- .xcf dd LIBIMG_FORMAT_XCF, img.is.xcf, img.decode.xcf, img.encode.xcf, 0
- .tiff dd LIBIMG_FORMAT_TIFF, img.is.tiff, img.decode.tiff, img.encode.tiff,0
- .pnm dd LIBIMG_FORMAT_PNM, img.is.pnm, img.decode.pnm, img.encode.pnm, 1 + (1 SHL Image.bpp1) + (1 SHL Image.bpp8g) + (1 SHL Image.bpp24)
- .wbmp dd LIBIMG_FORMAT_WBMP, img.is.wbmp, img.decode.wbmp, img.encode.wbmp,0
- .xbm dd LIBIMG_FORMAT_XBM, img.is.xbm, img.decode.xbm, img.encode.xbm, 0
- .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 )
- .bpp8a dd (1 SHL Image.bpp24)
-
-;;================================================================================================;;
-;;////////////////////////////////////////////////////////////////////////////////////////////////;;
-;;================================================================================================;;
-;! Below are private procs you should never call directly from your code ;;
-;;================================================================================================;;
-;;////////////////////////////////////////////////////////////////////////////////////////////////;;
-;;================================================================================================;;
-
-
-;;================================================================================================;;
-proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< --- TBD --- ;;
-;;================================================================================================;;
- xor eax, eax
- ret
-endp
-
-;;================================================================================================;;
-proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = 0 / pointer to image ;;
-;;================================================================================================;;
- invoke mem.alloc, sizeof.Image
- test eax, eax
- jz @f
- push ecx
- 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
- pop ecx
-@@:
- ret
-endp
-
-;;================================================================================================;;
-proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< eax = false / true ;;
-;;================================================================================================;;
- push edx
- mov edx, [_img]
- cmp [edx + Image.Data], 0
- je @f
- invoke mem.free, [edx + Image.Data]
- @@: cmp [edx + Image.Extended], 0
- je @f
- invoke mem.free, [edx + Image.Extended]
- @@: invoke mem.free, edx
- pop edx
- ret
-endp
-
-;;================================================================================================;;
-proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< --- TBD --- ;;
-;;================================================================================================;;
- push ebx esi
- mov ebx, [_img]
- mov eax, [_height]
-; our memory is limited, [_width]*[_height] must not overflow
-; image with width or height greater than 65535 is most likely bogus
- cmp word [_width+2], 0
- jnz .error
- cmp word [_height+2], 0
- jnz .error
- imul eax, [_width]
- test eax, eax
- jz .error
- cmp [ebx + Image.Type], Image.bpp1
- jz .bpp1
- cmp [ebx + Image.Type], Image.bpp2i
- jz .bpp2i
- cmp [ebx + Image.Type], Image.bpp4i
- jz .bpp4i
- cmp [ebx + Image.Type], Image.bpp8i
- jz .bpp8i
- cmp [ebx + Image.Type], Image.bpp8g
- jz .bpp8g
- cmp [ebx + Image.Type], Image.bpp8a
- jz .bpp8a
- cmp [ebx + Image.Type], Image.bpp24
- jz .bpp24
-.bpp32:
- shl eax, 2
- jmp @f
-.bpp24:
- lea eax, [eax*3]
- jmp @f
-.bpp8i:
- add eax, 256*4 ; for palette
-.bpp8g:
- jmp @f
-.bpp8a:
- shl eax, 1
- jmp @f
-.bpp4i:
- mov eax, [_width]
- add eax, 1
- shr eax, 1
- imul eax, [_height]
- mov ecx, eax
- mov eax, [_height]
- add eax, 1
- shr eax, 1
- imul eax, [_width]
- cmp eax, ecx
- jge .bpp4i.skip
- mov eax, ecx
- .bpp4i.skip:
- add eax, 16*4 ; for palette
- jmp @f
-.bpp2i:
- mov eax, [_width]
- add eax, 3
- shr eax, 2
- imul eax, [_height]
- mov ecx, eax
- mov eax, [_height]
- add eax, 3
- shr eax, 2
- imul eax, [_width]
- cmp eax, ecx
- jge .bpp2i.skip
- mov eax, ecx
- .bpp2i.skip:
- add eax, 4*4 ; for palette
- jmp @f
-.bpp1:
- mov eax, [_width]
- add eax, 7
- shr eax, 3
- imul eax, [_height]
- mov ecx, eax
- mov eax, [_height]
- add eax, 7
- shr eax, 3
- imul eax, [_width]
- cmp eax, ecx
- jge .bpp1.skip
- mov eax, ecx
- .bpp1.skip:
-
- add eax, 2*4 ; for palette
-@@:
- mov esi, eax
- invoke mem.realloc, [ebx + Image.Data], eax
- or eax, eax
- jz .error
-
- mov [ebx + Image.Data], eax
- push [_width]
- pop [ebx + Image.Width]
- push [_height]
- pop [ebx + Image.Height]
- cmp [ebx + Image.Type], Image.bpp8i
- jnz @f
- lea esi, [eax + esi - 256*4]
- mov [ebx + Image.Palette], esi
- jmp .ret
-@@:
- cmp [ebx + Image.Type], Image.bpp1
- jnz @f
- lea esi, [eax + esi - 2*4]
- mov [ebx + Image.Palette], esi
- jmp .ret
-@@:
- cmp [ebx + Image.Type], Image.bpp2i
- jnz @f
- lea esi, [eax + esi - 4*4]
- mov [ebx + Image.Palette], esi
- jmp .ret
-@@:
- cmp [ebx + Image.Type], Image.bpp4i
- jnz .ret
- lea esi, [eax + esi - 16*4]
- mov [ebx + Image.Palette], esi
- jmp .ret
-
- .error:
- xor eax, eax
- .ret:
- pop esi ebx
- ret
-endp
-
-;;================================================================================================;;
-img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
-;;------------------------------------------------------------------------------------------------;;
-;? --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;> --- TBD --- ;;
-;;------------------------------------------------------------------------------------------------;;
-;< --- TBD --- ;;
-;;================================================================================================;;
- cmp [ebx + Image.Type], Image.bpp1
- jz .bpp1.1
- cmp [ebx + Image.Type], Image.bpp2i
- jz .bpp2i.1
- cmp [ebx + Image.Type], Image.bpp4i
- jz .bpp4i.1
- cmp [ebx + Image.Type], Image.bpp8i
- jz .bpp8.1
- cmp [ebx + Image.Type], Image.bpp8g
- jz .bpp8.1
- cmp [ebx + Image.Type], Image.bpp8a
- jz .bpp8a.1
- cmp [ebx + Image.Type], Image.bpp24
- jz .bpp24.1
- add eax, eax
- cmp [ebx + Image.Type], Image.bpp32
- jnz .quit
- add eax, eax
- jmp .quit
-.bpp24.1:
- lea eax, [eax*3]
- jmp .quit
-.bpp1.1:
- add eax, 7
- shr eax, 3
- jmp .quit
-.bpp2i.1:
- add eax, 3
- shr eax, 2
- jmp .quit
-.bpp4i.1:
- add eax, 1
- shr eax, 1
- jmp .quit
-.bpp8a.1:
- shl eax, 1
-.bpp8.1:
-.quit:
- ret
-
-
-;;================================================================================================;;
-;;////////////////////////////////////////////////////////////////////////////////////////////////;;
-;;================================================================================================;;
-;! Below is private data you should never use directly from your code ;;
-;;================================================================================================;;
-;;////////////////////////////////////////////////////////////////////////////////////////////////;;
-;;================================================================================================;;
-
-align 4
-type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4
-img._.do_rgb.handlers:
- dd img._.do_rgb.bpp8i
- 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
- dd img._.do_rgb.bpp1
- dd img._.do_rgb.bpp8g
- dd img._.do_rgb.bpp2i
- dd img._.do_rgb.bpp4i
-
-img.flip.layer.handlers_horz:
- dd img.flip.layer.bpp8ig_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
- dd img.flip.layer.bpp1_horz
- dd img.flip.layer.bpp8ig_horz
- dd img.flip.layer.bpp2i_horz
- dd img.flip.layer.bpp4i_horz
-
-;;================================================================================================;;
-;;////////////////////////////////////////////////////////////////////////////////////////////////;;
-;;================================================================================================;;
-;! Exported functions section ;;
-;;================================================================================================;;
-;;////////////////////////////////////////////////////////////////////////////////////////////////;;
-;;================================================================================================;;
-
-
-align 4
-@EXPORT:
-
-export \
- lib_init , 'lib_init' , \
- 0x00050007 , 'version' , \
- img.is_img , 'img_is_img' , \
- img.info , 'img_info' , \
- img.from_file , 'img_from_file' , \
- img.to_file , 'img_to_file' , \
- img.from_rgb , 'img_from_rgb' , \
- img.to_rgb , 'img_to_rgb' , \
- img.to_rgb2 , 'img_to_rgb2' , \
- img.decode , 'img_decode' , \
- 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.flip.layer , 'img_flip_layer' , \
- img.rotate , 'img_rotate' , \
- img.rotate.layer , 'img_rotate_layer' , \
- img.draw , 'img_draw' , \
- img.scale , 'img_scale' , \
- img.convert , 'img_convert' , \
- img.formats_table, 'img_formats_table'
-
-; import from deflate unpacker
-; is initialized only when PNG loading is requested
-align 16
-@IMPORT:
-
-library archiver, 'archiver.obj'
-import archiver, \
- deflate_unpack2, 'deflate_unpack2',\
- deflateInit2, 'deflateInit2',\
- deflateReset, 'deflateReset',\
- deflate, 'deflate',\
- deflateEnd, 'deflateEnd',\
- calc_crc32, 'calc_crc32'
-
-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
-color_table_2 rd 256
-color_table_3 rd 256
-color_table_4 rd 256
+;;================================================================================================;;
+;;//// libimg.asm //// (c) mike.dld, 2007-2008, (c) diamond, 2009, (c) dunkaist, 2011-2013 ///////;;
+;;================================================================================================;;
+;; ;;
+;; 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 . ;;
+;; ;;
+;;================================================================================================;;
+
+
+format MS COFF
+
+public @EXPORT as 'EXPORTS'
+
+include '../../../../struct.inc'
+include '../../../../proc32.inc'
+include '../../../../macros.inc'
+include '../../../../config.inc'
+;include '../../../../debug.inc'
+purge section,mov,add,sub
+
+include 'libimg.inc'
+
+section '.flat' code readable align 16
+
+include 'bmp/bmp.asm'
+include 'gif/gif.asm'
+include 'jpeg/jpeg.asm'
+include 'png/png.asm'
+include 'tga/tga.asm'
+include 'z80/z80.asm'
+include 'ico_cur/ico_cur.asm'
+include 'pcx/pcx.asm'
+include 'xcf/xcf.asm'
+include 'tiff/tiff.asm'
+include 'pnm/pnm.asm'
+include 'wbmp/wbmp.asm'
+include 'xbm/xbm.asm'
+
+include 'scale.asm'
+include 'convert.asm'
+
+;;================================================================================================;;
+proc lib_init ;///////////////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? Library entry point (called after library load) ;;
+;;------------------------------------------------------------------------------------------------;;
+;> eax = pointer to memory allocation routine ;;
+;> ebx = pointer to memory freeing routine ;;
+;> ecx = pointer to memory reallocation routine ;;
+;> edx = pointer to library loading routine ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 1 (fail) / 0 (ok) (library initialization result) ;;
+;;================================================================================================;;
+ mov [mem.alloc], eax
+ mov [mem.free], ebx
+ mov [mem.realloc], ecx
+ mov [dll.load], edx
+
+ or edx,edx
+ jz @f
+ invoke dll.load, @IMPORT
+ @@:
+
+ 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
+
+;;================================================================================================;;
+proc img.is_img _data, _length ;//////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< --- TBD --- ;;
+;;================================================================================================;;
+ push ebx
+ mov ebx, img.formats_table
+ @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
+ or eax, eax
+ jnz @f
+ add ebx, sizeof.FormatsTableEntry
+ cmp dword[ebx], 0
+ jnz @b
+ xor eax, eax
+ @@: pop ebx
+ ret
+endp
+
+;;================================================================================================;;
+proc img.info _data, _length ;////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< --- TBD --- ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img.from_file _filename ;////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to image ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img.to_file _img, _filename ;////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = false / true ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img.from_rgb _rgb_data ;/////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to image ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img.to_rgb2 _img, _out ;/////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? decodes image data into RGB triplets and stores them where [_out] points to ;;
+;;------------------------------------------------------------------------------------------------;;
+;> [_img] = pointer to source image ;;
+;> [_out] = where to store RGB triplets ;;
+;;------------------------------------------------------------------------------------------------;;
+;< none ;;
+;;================================================================================================;;
+ push esi edi
+ mov esi, [_img]
+ stdcall img._.validate, esi
+ or eax, eax
+ jnz .ret
+ mov edi, [_out]
+ call img._.do_rgb
+.ret:
+ pop edi esi
+ ret
+endp
+
+;;================================================================================================;;
+proc img.to_rgb _img ;////////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? 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 ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to rgb_data (array of [rgb] triplets) ;;
+;;================================================================================================;;
+ push esi edi
+ mov esi, [_img]
+ stdcall img._.validate, esi
+ or eax, eax
+ jnz .error
+
+ mov esi, [_img]
+ mov ecx, [esi + Image.Width]
+ imul ecx, [esi + Image.Height]
+ lea eax, [ecx * 3 + 4 * 3]
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+
+ mov edi, eax
+ push eax
+ mov eax, [esi + Image.Width]
+ stosd
+ mov eax, [esi + Image.Height]
+ stosd
+ call img._.do_rgb
+ pop eax
+ pop edi esi
+ ret
+
+ .error:
+ xor eax, eax
+ pop edi esi
+ ret
+endp
+
+;;================================================================================================;;
+proc img._.do_rgb ;///////////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? decodes [esi + Image.Data] data into RGB triplets and stores them at [edi] ;;
+;;------------------------------------------------------------------------------------------------;;
+;> esi = pointer to source image ;;
+;> edi = pointer to memory to store RGB triplets ;;
+;;------------------------------------------------------------------------------------------------;;
+;< none ;;
+;;================================================================================================;;
+ mov ecx, [esi + Image.Width]
+ imul ecx, [esi + Image.Height]
+ mov eax, [esi + Image.Type]
+ jmp dword [.handlers + (eax-1)*4]
+
+align 16
+.bpp8i:
+; 8 BPP WITH PALETTE -> 24 BPP
+ push ebx
+ mov ebx, [esi + Image.Palette]
+ mov esi, [esi + Image.Data]
+ sub ecx, 1
+ jz .bpp8i.last
+@@:
+ movzx eax, byte [esi]
+ add esi, 1
+ mov eax, [ebx + eax*4]
+ mov [edi], eax
+ add edi, 3
+ sub ecx, 1
+ jnz @b
+.bpp8i.last:
+ movzx eax, byte [esi]
+ mov eax, [ebx + eax*4]
+ mov [edi], ax
+ shr eax, 16
+ mov [edi+2], al
+ pop ebx
+ ret
+
+align 16
+.bpp8g:
+; 8 BPP GRAYSCALE -> 24 BPP
+ mov esi, [esi + Image.Data]
+@@:
+ lodsb
+ mov ah, al
+ stosb
+ stosw
+ dec ecx
+ jnz @b
+ ret
+;
+;align 16
+;.bpp8a: ; considered application layer, may be changed in the future
+;; 8a BPP -> 24 BPP
+; mov esi, [esi + Image.Data]
+;@@:
+; lodsw
+; mov ah, al
+; stosb
+; stosw
+; dec ecx
+; jnz @b
+; 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
+@@:
+ 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]
+ mov esi, [esi + Image.Data]
+ shr ecx, 2
+ rep movsd
+ ret
+
+align 16
+.bpp32:
+; 32 BPP -> 24 BPP
+ mov esi, [esi + Image.Data]
+
+ @@:
+ mov eax, [esi]
+ mov [edi], ax
+ shr eax, 16
+ mov [edi+2], al
+ add esi, 4
+ add edi, 3
+ sub ecx, 1
+ jnz @b
+
+ @@:
+ ret
+
+align 16
+.bpp1:
+ push ebx ebp
+ mov ebp, [esi + Image.Width]
+ mov edx, [esi + Image.Height]
+ shl edx, 16
+ mov ebx, [esi + Image.Palette]
+ mov esi, [esi + Image.Data]
+ .bpp1.pre:
+ mov dx, bp
+ mov ecx, 7
+ .bpp1.begin:
+ xor eax, eax
+ bt [esi], ecx
+ adc eax, 0
+ mov eax, [ebx + eax*4]
+ mov [edi], ax
+ shr eax, 16
+ mov [edi + 2], al
+ add edi, 3
+ dec dx
+ jz .bpp1.end_line
+ dec ecx
+ jns .bpp1.begin
+ mov ecx, 7
+ inc esi
+ jmp .bpp1.begin
+ .bpp1.end_line:
+ sub edx, 0x10000
+ jz .bpp1.quit
+ inc esi
+ jmp .bpp1.pre
+ .bpp1.quit:
+ pop ebp ebx
+ ret
+
+align 16
+.bpp2i:
+ push ebx ebp
+ mov ebp, [esi + Image.Width]
+ mov edx, [esi + Image.Height]
+ shl edx, 16
+ mov ebx, [esi + Image.Palette]
+ mov esi, [esi + Image.Data]
+ .bpp2i.pre:
+ mov dx, bp
+ mov ecx, 3
+ .bpp2i.begin:
+ mov eax, 3
+ shl ecx, 1
+ shl eax, cl
+ and al, [esi]
+ shr eax, cl
+ shr ecx, 1
+ mov eax, [ebx + eax*4]
+ mov [edi], ax
+ shr eax, 16
+ mov [edi + 2], al
+ add edi, 3
+ dec dx
+ jz .bpp2i.end_line
+ dec ecx
+ jns .bpp2i.begin
+ mov ecx, 3
+ inc esi
+ jmp .bpp2i.begin
+ .bpp2i.end_line:
+ sub edx, 0x10000
+ jz .bpp2i.quit
+ inc esi
+ jmp .bpp2i.pre
+ .bpp2i.quit:
+ pop ebp ebx
+ ret
+
+align 16
+.bpp4i:
+ push ebx ebp
+ mov ebp, [esi + Image.Width]
+ mov edx, [esi + Image.Height]
+ shl edx, 16
+ mov ebx, [esi + Image.Palette]
+ mov esi, [esi + Image.Data]
+ .bpp4i.pre:
+ mov dx, bp
+ mov ecx, 1
+ .bpp4i.begin:
+ mov eax, 15
+ shl ecx, 2
+ shl eax, cl
+ and al, [esi]
+ shr eax, cl
+ shr ecx, 2
+ mov eax, [ebx + eax*4]
+ mov [edi], ax
+ shr eax, 16
+ mov [edi + 2], al
+ add edi, 3
+ dec dx
+ jz .bpp4i.end_line
+ dec ecx
+ jns .bpp4i.begin
+ mov ecx, 1
+ inc esi
+ jmp .bpp4i.begin
+ .bpp4i.end_line:
+ sub edx, 0x10000
+ jz .bpp4i.quit
+ inc esi
+ jmp .bpp4i.pre
+ .bpp4i.quit:
+ pop ebp ebx
+ ret
+
+endp
+
+;;================================================================================================;;
+proc img.decode _data, _length, _options ;////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? decodes loaded into memory graphic file ;;
+;;------------------------------------------------------------------------------------------------;;
+;> [_data] = pointer to file in memory ;;
+;> [_length] = size in bytes of memory area pointed to by [_data] ;;
+;> [_options] = 0 / pointer to the structure of additional options ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to image ;;
+;;================================================================================================;;
+ push ebx
+ mov ebx, img.formats_table
+ @@: stdcall [ebx + FormatsTableEntry.Is], [_data], [_length]
+ or eax, eax
+ jnz @f
+ add ebx, sizeof.FormatsTableEntry
+ cmp dword[ebx], eax ;0
+ jnz @b
+ pop ebx
+ ret
+ @@: mov eax, [ebx + FormatsTableEntry.Decode]
+ pop ebx
+ leave
+ jmp eax
+endp
+
+;;================================================================================================;;
+proc img.encode _img, _common, _specific ;////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? encode image to some format ;;
+;;------------------------------------------------------------------------------------------------;;
+;> [_img] = pointer to input image ;;
+;> [_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. 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 ;;
+; 0x04 : delete alpha channel, if any ;;
+; 0x08 : flush alpha channel with 0xff, if any; add it if none ;;
+; 0x03 : byte : reserved, must be 0 ;;
+;> [_specific] = 0 / pointer to the structure of format specific options ;;
+; see .inc for description ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to encoded data ;;
+;< ecx = error code / the size of encoded data ;;
+; 1 : out of memory ;;
+; 2 : format is not supported ;;
+; 3 : specific conditions cannot be satisfied ;;
+; 4 : bit depth cannot be preserved ;;
+;;================================================================================================;;
+ mov ebx, [_img]
+
+ movzx eax, byte[_common]
+ dec eax
+ imul eax, sizeof.FormatsTableEntry
+ add eax, FormatsTableEntry.Capabilities
+ add eax, img.formats_table
+ mov eax, [eax]
+ test eax, 1 ; is encoding to this format supported at all?
+ jnz @f
+ mov ecx, LIBIMG_ERROR_FORMAT
+ jmp .error
+ @@:
+ mov ecx, [ebx + Image.Type]
+ mov edx, 1
+ shl edx, cl
+ test eax, edx
+ jnz .bit_depth_ok
+ test byte[_common+2], LIBIMG_ENCODE_STRICT_BIT_DEPTH
+ jz @f
+ mov ecx, LIBIMG_ERROR_BIT_DEPTH
+ jmp .error
+ @@:
+ mov edx, 1 SHL Image.bpp24
+ test eax, edx
+ jnz @f
+ mov ecx, LIBIMG_ERROR_BIT_DEPTH
+ jmp .error
+ @@:
+ stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], Image.bpp24
+ test eax, eax
+ jnz @f
+ mov ecx, LIBIMG_ERROR_OUT_OF_MEMORY
+ jmp .error
+ @@:
+ push eax
+ stdcall img.to_rgb2, ebx, [eax + Image.Data]
+ pop ebx
+
+ .bit_depth_ok:
+ movzx eax, byte[_common]
+ dec eax
+ imul eax, sizeof.FormatsTableEntry
+ add eax, FormatsTableEntry.Encode
+ add eax, img.formats_table
+ mov eax, [eax]
+ stdcall eax, [_img], [_common], [_specific]
+ push eax ecx
+ cmp ebx, [_img]
+ je @f
+ stdcall img.destroy, ebx
+ @@:
+ pop ecx eax
+ jmp .quit
+
+ .error:
+ xor eax, eax
+ .quit:
+ ret
+endp
+
+;;================================================================================================;;
+proc img.create _width, _height, _type ;//////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? creates an Image structure and initializes some its fields ;;
+;;------------------------------------------------------------------------------------------------;;
+;> [_width] = width of an image in pixels ;;
+;> [_height] = height of an image in pixels ;;
+;> [_type] = one of the Image.bppN constants from libimg.inc ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to image ;;
+;;================================================================================================;;
+ push ecx
+
+ stdcall img._.new
+ or eax, eax
+ jz .error
+
+ mov ecx, [_type]
+ mov [eax + Image.Type], ecx
+
+ push eax
+
+ stdcall img._.resize_data, eax, [_width], [_height]
+ or eax, eax
+ jz .error.2
+
+ pop eax
+ jmp .ret
+
+ .error.2:
+; pop eax
+ stdcall img._.delete; eax
+ xor eax, eax
+
+ .error:
+ .ret:
+ pop ecx
+ ret
+endp
+
+;;================================================================================================;;
+proc img.destroy.layer _img ;/////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? frees memory occupied by an image and all the memory regions its fields point to ;;
+;? for image sequences deletes only one frame and fixes Previous/Next pointers ;;
+;;------------------------------------------------------------------------------------------------;;
+;> [_img] = pointer to image ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 (fail) / 1 (success) ;;
+;;================================================================================================;;
+ 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 ;///////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? frees memory occupied by an image and all the memory regions its fields point to ;;
+;? follows Previous/Next pointers and deletes all the images in sequence ;;
+;;------------------------------------------------------------------------------------------------;;
+;> [_img] = pointer to image ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 (fail) / 1 (success) ;;
+;;================================================================================================;;
+ 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
+
+;;================================================================================================;;
+proc img.count _img ;/////////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? Get number of images in the list (e.g. in animated GIF file) ;;
+;;------------------------------------------------------------------------------------------------;;
+;> _img = pointer to image ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = -1 (fail) / >0 (ok) ;;
+;;================================================================================================;;
+ push ecx edx
+ mov edx, [_img]
+ stdcall img._.validate, edx
+ or eax, eax
+ jnz .error
+
+ @@: mov eax, [edx + Image.Previous]
+ or eax, eax
+ jz @f
+ mov edx, eax
+ jmp @b
+
+ @@: xor ecx, ecx
+ @@: inc ecx
+ mov eax, [edx + Image.Next]
+ or eax, eax
+ jz .exit
+ mov edx, eax
+ jmp @b
+
+ .exit:
+ mov eax, ecx
+ pop edx ecx
+ ret
+
+ .error:
+ or eax, -1
+ pop edx ecx
+ ret
+endp
+
+;;//// image processing //////////////////////////////////////////////////////////////////////////;;
+
+;;================================================================================================;;
+proc img.lock_bits _img, _start_line, _end_line ;/////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to bits ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img.unlock_bits _img, _lock ;////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = false / true ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img.flip.layer _img, _flip_kind ;////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? Flip image layer ;;
+;;------------------------------------------------------------------------------------------------;;
+;> _img = pointer to image ;;
+;> _flip_kind = one of FLIP_* constants ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = false / true ;;
+;;================================================================================================;;
+locals
+ scanline_len dd ?
+endl
+
+ push ebx esi edi
+ mov ebx, [_img]
+ stdcall img._.validate, ebx
+ or eax, eax
+ jnz .error
+
+ mov ecx, [ebx + Image.Height]
+ mov eax, [ebx + Image.Width]
+ call img._.get_scanline_len
+ mov [scanline_len], eax
+
+ test [_flip_kind], FLIP_VERTICAL
+ jz .dont_flip_vert
+
+ imul eax, ecx
+ sub eax, [scanline_len]
+ shr ecx, 1
+ mov esi, [ebx + Image.Data]
+ lea edi, [esi + eax]
+
+ .next_line_vert:
+ push ecx
+
+ mov ecx, [scanline_len]
+ push ecx
+ shr ecx, 2
+ @@:
+ dec ecx
+ js @f
+ mov eax, [esi]
+ xchg eax, [edi]
+ mov [esi], eax
+ add esi, 4
+ add edi, 4
+ jmp @b
+ @@:
+
+ pop ecx
+ and ecx, 3
+ jz .cont_line_vert
+ @@:
+ mov al, [esi]
+ xchg al, [edi]
+ mov [esi], al
+ add esi, 1
+ add edi, 1
+ dec ecx
+ jnz @b
+ .cont_line_vert:
+
+ pop ecx
+ mov eax, [scanline_len]
+ shl eax, 1
+ sub edi, eax
+ dec ecx
+ jnz .next_line_vert
+
+ .dont_flip_vert:
+
+ test [_flip_kind], FLIP_HORIZONTAL
+ jz .exit
+
+ mov ecx, [ebx + Image.Height]
+ mov eax, [ebx + Image.Type]
+ mov esi, [ebx + Image.Data]
+ mov edi, [scanline_len]
+ add edi, esi
+ jmp dword [.handlers_horz + (eax-1)*4]
+
+.bpp32_horz:
+ sub edi, 4
+
+ .next_line_horz:
+ push ecx esi edi
+
+ mov ecx, [scanline_len]
+ shr ecx, 3
+ @@: mov eax, [esi]
+ xchg eax, [edi]
+ mov [esi], eax
+ add esi, 4
+ add edi, -4
+ sub ecx, 1
+ jnz @b
+
+ pop edi esi ecx
+ add esi, [scanline_len]
+ add edi, [scanline_len]
+ dec ecx
+ jnz .next_line_horz
+ jmp .exit
+
+.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
+
+.bpp8ig_horz:
+ dec edi
+ .next_line_horz8ig:
+ push ecx esi edi
+
+ mov ecx, [scanline_len]
+ shr ecx, 1
+ @@: mov al, [esi]
+ mov dl, [edi]
+ mov [edi], al
+ mov [esi], dl
+ add esi, 1
+ sub edi, 1
+ sub ecx, 1
+ jnz @b
+
+ pop edi esi ecx
+ add esi, [scanline_len]
+ add edi, [scanline_len]
+ dec ecx
+ jnz .next_line_horz8ig
+ jmp .exit
+
+.bpp24_horz:
+ sub edi, 3
+ .next_line_horz24:
+ push ecx esi edi
+
+ mov ecx, [ebx + Image.Width]
+ @@:
+ mov al, [esi]
+ mov dl, [edi]
+ mov [edi], al
+ mov [esi], dl
+ mov al, [esi+1]
+ mov dl, [edi+1]
+ mov [edi+1], al
+ mov [esi+1], dl
+ mov al, [esi+2]
+ mov dl, [edi+2]
+ mov [edi+2], al
+ mov [esi+2], dl
+ add esi, 3
+ sub edi, 3
+ sub ecx, 2
+ ja @b
+
+ pop edi esi ecx
+ add esi, [scanline_len]
+ add edi, [scanline_len]
+ dec ecx
+ jnz .next_line_horz24
+ jmp .exit
+
+.bpp1_horz:
+ mov edi, [scanline_len]
+ mov edx, [ebx + Image.Width]
+ and edx, 7
+ neg edx
+ add edx, 8
+ and edx, 7
+.bpp1_horz.begin:
+ push ebx edx esi
+ mov eax, 7
+ add edi, esi
+ sub edi, 1
+ mov ebx, [ebx + Image.Width]
+ shr ebx, 1
+.bpp1_horz.bit:
+ bt [edi], edx
+ jc @f
+ btr [esi], eax
+ jmp .bpp1_horz.right
+ @@:
+ bts [esi], eax
+ .bpp1_horz.right:
+ jnc @f
+ bts [edi], edx
+ jmp .bpp1_horz.bit_done
+ @@:
+ btr [edi], edx
+ .bpp1_horz.bit_done:
+ inc edx
+ and edx, 7
+ jnz @f
+ dec edi
+ @@:
+ dec eax
+ jns @f
+ mov eax, 7
+ inc esi
+ @@:
+ dec ebx
+ jnz .bpp1_horz.bit
+
+ pop esi edx ebx
+ add esi, [scanline_len]
+ mov edi, [scanline_len]
+ dec ecx
+ jnz .bpp1_horz.begin
+ jmp .exit
+
+
+.bpp2i_horz:
+ mov edi, [scanline_len]
+ mov edx, [ebx + Image.Width]
+ and edx, 3
+ neg edx
+ add edx, 4
+ and edx, 3
+.bpp2i_horz.begin:
+ push ebx edx esi
+ mov eax, 3
+ add edi, esi
+ sub edi, 1
+ mov ebx, [ebx + Image.Width]
+ shr ebx, 1
+.bpp2i_horz.pixel:
+ push ebx ecx
+ mov ebx, 3
+ mov ecx, edx
+ shl ebx, cl
+ shl ebx, cl
+ and bl, [edi]
+ shr ebx, cl
+ shr ebx, cl
+ mov bh, 3
+ mov ecx, eax
+ shl ebx, cl
+ shl ebx, cl
+ not bh
+ and bh, [esi]
+ or bl, bh
+ mov bh, [esi]
+ mov [esi], bl
+ shr ebx, 8
+ shr ebx, cl
+ shr ebx, cl
+ and ebx, 3
+ mov bh, 3
+ mov ecx, edx
+ shl ebx, cl
+ shl ebx, cl
+ not bh
+ and bh, [edi]
+ or bl, bh
+ mov [edi], bl
+ pop ecx ebx
+ .bpp2i_horz.pixel_done:
+ inc edx
+ and edx, 3
+ jnz @f
+ dec edi
+ @@:
+ dec eax
+ jns @f
+ mov eax, 3
+ inc esi
+ @@:
+ dec ebx
+ jnz .bpp2i_horz.pixel
+
+ pop esi edx ebx
+ add esi, [scanline_len]
+ mov edi, [scanline_len]
+ dec ecx
+ jnz .bpp2i_horz.begin
+ jmp .exit
+
+
+.bpp4i_horz:
+ mov edi, [scanline_len]
+ mov edx, [ebx + Image.Width]
+ and edx, 1
+ neg edx
+ add edx, 2
+ and edx, 1
+.bpp4i_horz.begin:
+ push ebx edx esi
+ mov eax, 1
+ add edi, esi
+ sub edi, 1
+ mov ebx, [ebx + Image.Width]
+ shr ebx, 1
+.bpp4i_horz.pixel:
+ push ebx ecx
+ mov ebx, 15
+ mov ecx, edx
+ shl ecx, 2
+ shl ebx, cl
+ and bl, [edi]
+ shr ebx, cl
+ mov bh, 15
+ mov ecx, eax
+ shl ecx, 2
+ shl ebx, cl
+ not bh
+ and bh, [esi]
+ or bl, bh
+ mov bh, [esi]
+ mov [esi], bl
+ shr ebx, 8
+ shr ebx, cl
+ and ebx, 15
+ mov bh, 15
+ mov ecx, edx
+ shl ecx, 2
+ shl ebx, cl
+ not bh
+ and bh, [edi]
+ or bl, bh
+ mov [edi], bl
+ pop ecx ebx
+ .bpp4i_horz.pixel_done:
+ inc edx
+ and edx, 1
+ jnz @f
+ dec edi
+ @@:
+ dec eax
+ jns @f
+ mov eax, 1
+ inc esi
+ @@:
+ dec ebx
+ jnz .bpp4i_horz.pixel
+
+ pop esi edx ebx
+ add esi, [scanline_len]
+ mov edi, [scanline_len]
+ dec ecx
+ jnz .bpp4i_horz.begin
+ jmp .exit
+
+
+ .exit:
+ xor eax, eax
+ inc eax
+ pop edi esi ebx
+ ret
+
+ .error:
+ xor eax, eax
+ pop edi esi ebx
+ ret
+endp
+
+;;================================================================================================;;
+proc img.flip _img, _flip_kind ;//////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? 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 ;;
+;;================================================================================================;;
+locals
+ scanline_len_old dd ?
+ scanline_len_new dd ?
+ scanline_pixels_new dd ?
+ line_buffer dd ?
+ pixels_ptr dd ?
+endl
+
+ mov [line_buffer], 0
+
+ push ebx esi edi
+ mov ebx, [_img]
+ stdcall img._.validate, ebx
+ or eax, eax
+ jnz .error
+
+ cmp [_rotate_kind], ROTATE_90_CCW
+ je .rotate_ccw_low
+ cmp [_rotate_kind], ROTATE_90_CW
+ je .rotate_cw_low
+ cmp [_rotate_kind], ROTATE_180
+ je .flip
+ jmp .exit
+
+ .rotate_ccw_low:
+ mov eax, [ebx + Image.Height]
+ mov [scanline_pixels_new], eax
+ call img._.get_scanline_len
+ mov [scanline_len_new], eax
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ mov [line_buffer], eax
+
+ mov eax, [ebx + Image.Width]
+ mov ecx, eax
+ call img._.get_scanline_len
+ mov [scanline_len_old], eax
+
+ mov eax, [scanline_len_new]
+ imul eax, ecx
+ add eax, [ebx + Image.Data]
+ mov [pixels_ptr], eax
+
+ cmp [ebx + Image.Type], Image.bpp1
+ jz .rotate_ccw1
+ cmp [ebx + Image.Type], Image.bpp2i
+ jz .rotate_ccw2i
+ cmp [ebx + Image.Type], Image.bpp4i
+ jz .rotate_ccw4i
+ cmp [ebx + Image.Type], Image.bpp8i
+ jz .rotate_ccw8ig
+ cmp [ebx + Image.Type], Image.bpp8g
+ jz .rotate_ccw8ig
+ 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
+ push ecx
+
+ mov edx, [scanline_len_old]
+ add [scanline_len_old], -4
+
+ mov ecx, [scanline_pixels_new]
+ mov esi, [ebx + Image.Data]
+ mov edi, [line_buffer]
+ @@: mov eax, [esi]
+ stosd
+ add esi, edx
+ dec ecx
+ jnz @b
+
+ mov eax, [scanline_pixels_new]
+ mov edi, [ebx + Image.Data]
+ lea esi, [edi + 4]
+ mov edx, [scanline_len_old]
+ shr edx, 2
+ @@: mov ecx, edx
+ rep movsd
+ add esi, 4
+ dec eax
+ jnz @b
+
+ mov eax, [scanline_len_new]
+ sub [pixels_ptr], eax
+ mov ecx, [scanline_pixels_new]
+ mov esi, [line_buffer]
+ mov edi, [pixels_ptr]
+ rep movsd
+
+ pop ecx
+ jmp .next_column_ccw_low
+
+.rotate_ccw8ig:
+ .next_column_ccw_low8ig:
+ dec ecx
+ js .exchange_dims
+ push ecx
+
+ mov edx, [scanline_len_old]
+ add [scanline_len_old], -1
+
+ mov ecx, [scanline_pixels_new]
+ mov esi, [ebx + Image.Data]
+ mov edi, [line_buffer]
+ @@: mov al, [esi]
+ mov [edi], al
+ add esi, edx
+ add edi, 1
+ sub ecx, 1
+ jnz @b
+
+ mov eax, [scanline_pixels_new]
+ mov edi, [ebx + Image.Data]
+ lea esi, [edi + 1]
+ 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_low8ig
+
+.rotate_ccw24:
+ .next_column_ccw_low24:
+ dec ecx
+ js .exchange_dims
+ push ecx
+
+ mov edx, [scanline_len_old]
+ add [scanline_len_old], -3
+
+ mov ecx, [scanline_pixels_new]
+ mov esi, [ebx + Image.Data]
+ mov edi, [line_buffer]
+ @@: mov al, [esi]
+ mov [edi], al
+ mov al, [esi+1]
+ mov [edi+1], al
+ mov al, [esi+2]
+ mov [edi+2], al
+ add esi, edx
+ add edi, 3
+ sub ecx, 1
+ jnz @b
+
+ mov eax, [scanline_pixels_new]
+ mov edi, [ebx + Image.Data]
+ lea esi, [edi + 3]
+ 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_ccw_low24
+
+.rotate_ccw1:
+ push ecx edx
+
+ mov eax, [ebx + Image.Height]
+ add eax, 7
+ shr eax, 3
+ imul eax, [ebx + Image.Width]
+ push eax ; save new data size
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ push eax ; save pointer to new data
+
+ mov ecx, [ebx + Image.Width]
+ and ecx, 7
+ neg ecx
+ add ecx, 8
+ and ecx, 7
+
+ mov edi, eax
+ mov esi, [ebx + Image.Data]
+ mov eax, 7
+ mov edx, [scanline_len_old]
+ dec edx
+ add esi, edx
+
+ .rotate_ccw1.begin:
+ bt [esi], ecx
+ jc .rotate_ccw1.one
+ .rotate_ccw1.zero:
+ btr [edi], eax
+ jmp @f
+ .rotate_ccw1.one:
+ bts [edi], eax
+ @@:
+ add esi, [scanline_len_old]
+ dec [scanline_pixels_new]
+ jz .rotate_ccw1.end_of_line
+ sub eax, 1
+ adc edi, 0
+ and eax, 7
+ jmp .rotate_ccw1.begin
+ .rotate_ccw1.end_of_line:
+ inc edi
+ mov eax, [ebx + Image.Height]
+ mov [scanline_pixels_new], eax
+ mov eax, 7
+ inc ecx
+ and ecx, 7
+ jz @f
+ mov esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_ccw1.begin
+ @@:
+ dec edx
+ js .rotate_ccw1.quit
+ mov esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_ccw1.begin
+ .rotate_ccw1.quit:
+ pop esi ; get pointer to new data
+ mov edi, [ebx + Image.Data]
+ pop ecx ; get new data size
+ rep movsb
+ invoke mem.free, esi
+ pop edx ecx
+ jmp .exchange_dims
+
+
+.rotate_ccw2i:
+ push ecx edx
+
+ mov eax, [ebx + Image.Height]
+ add eax, 3
+ shr eax, 2
+ imul eax, [ebx + Image.Width]
+ push eax ; save new data size
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ push eax ; save pointer to new data
+
+ mov ecx, [ebx + Image.Width]
+ and ecx, 3
+ neg ecx
+ add ecx, 4
+ and ecx, 3
+
+ mov edi, eax
+ mov esi, [ebx + Image.Data]
+ mov eax, 3
+ mov edx, [scanline_len_old]
+ dec edx
+ add esi, edx
+
+ .rotate_ccw2i.begin:
+ push ebx ecx
+ mov ebx, 3
+ shl ebx, cl
+ shl ebx, cl
+ and bl, [esi]
+ shr ebx, cl
+ shr ebx, cl
+ mov bh, 3
+ mov ecx, eax
+ shl ebx, cl
+ shl ebx, cl
+ not bh
+ and bh, [edi]
+ or bl, bh
+ mov [edi], bl
+ pop ecx ebx
+
+ add esi, [scanline_len_old]
+ dec [scanline_pixels_new]
+ jz .rotate_ccw2i.end_of_line
+ sub eax, 1
+ adc edi, 0
+ and eax, 3
+ jmp .rotate_ccw2i.begin
+ .rotate_ccw2i.end_of_line:
+ inc edi
+ mov eax, 3
+ mov esi, [ebx + Image.Height]
+ mov [scanline_pixels_new], esi
+ inc ecx
+ and ecx, 3
+ jz @f
+ mov esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_ccw2i.begin
+ @@:
+ dec edx
+ js .rotate_ccw2i.quit
+ mov esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_ccw2i.begin
+ .rotate_ccw2i.quit:
+ pop esi ; get pointer to new data
+ mov edi, [ebx + Image.Data]
+ pop ecx ; get new data size
+ rep movsb
+ invoke mem.free, esi
+ pop edx ecx
+ jmp .exchange_dims
+
+
+.rotate_ccw4i:
+ push ecx edx
+
+ mov eax, [ebx + Image.Height]
+ add eax, 1
+ shr eax, 1
+ imul eax, [ebx + Image.Width]
+ push eax ; save new data size
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ push eax ; save pointer to new data
+
+ mov ecx, [ebx + Image.Width]
+ and ecx, 1
+ neg ecx
+ add ecx, 2
+ and ecx, 1
+
+ mov edi, eax
+ mov esi, [ebx + Image.Data]
+ mov eax, 1
+ mov edx, [scanline_len_old]
+ dec edx
+ add esi, edx
+
+ .rotate_ccw4i.begin:
+ push ebx ecx
+ mov ebx, 15
+ shl ecx, 2
+ shl ebx, cl
+ and bl, [esi]
+ shr ebx, cl
+ mov bh, 15
+ mov ecx, eax
+ shl ecx, 2
+ shl ebx, cl
+ not bh
+ and bh, [edi]
+ or bl, bh
+ mov [edi], bl
+ pop ecx ebx
+
+ add esi, [scanline_len_old]
+ dec [scanline_pixels_new]
+ jz .rotate_ccw4i.end_of_line
+ sub eax, 1
+ adc edi, 0
+ and eax, 1
+ jmp .rotate_ccw4i.begin
+ .rotate_ccw4i.end_of_line:
+ inc edi
+ mov eax, 1
+ mov esi, [ebx + Image.Height]
+ mov [scanline_pixels_new], esi
+ inc ecx
+ and ecx, 1
+ jz @f
+ mov esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_ccw4i.begin
+ @@:
+ dec edx
+ js .rotate_ccw4i.quit
+ mov esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_ccw4i.begin
+ .rotate_ccw4i.quit:
+ pop esi ; get pointer to new data
+ mov edi, [ebx + Image.Data]
+ pop ecx ; get new data size
+ rep movsb
+ invoke mem.free, esi
+ pop edx ecx
+ jmp .exchange_dims
+
+
+
+ .rotate_cw_low:
+ mov eax, [ebx + Image.Height]
+ mov [scanline_pixels_new], eax
+ call img._.get_scanline_len
+ mov [scanline_len_new], eax
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ mov [line_buffer], eax
+
+ mov eax, [ebx + Image.Width]
+ mov ecx, eax
+ call img._.get_scanline_len
+ mov [scanline_len_old], eax
+
+ mov eax, [scanline_len_new]
+ imul eax, ecx
+ add eax, [ebx + Image.Data]
+ mov [pixels_ptr], eax
+
+ cmp [ebx + Image.Type], Image.bpp1
+ jz .rotate_cw1
+ cmp [ebx + Image.Type], Image.bpp2i
+ jz .rotate_cw2i
+ cmp [ebx + Image.Type], Image.bpp4i
+ jz .rotate_cw4i
+ cmp [ebx + Image.Type], Image.bpp8i
+ jz .rotate_cw8ig
+ cmp [ebx + Image.Type], Image.bpp8g
+ jz .rotate_cw8ig
+ 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
+ push ecx
+
+ mov edx, [scanline_len_old]
+ add [scanline_len_old], -4
+
+ mov ecx, [scanline_pixels_new]
+ mov esi, [pixels_ptr]
+ add esi, -4
+ mov edi, [line_buffer]
+ @@: mov eax, [esi]
+ stosd
+ sub esi, edx
+ dec ecx
+ jnz @b
+
+ mov eax, [scanline_pixels_new]
+ dec eax
+ mov edi, [ebx + Image.Data]
+ add edi, [scanline_len_old]
+ lea esi, [edi + 4]
+ mov edx, [scanline_len_old]
+ shr edx, 2
+ @@: mov ecx, edx
+ rep movsd
+ add esi, 4
+ dec eax
+ jnz @b
+
+ mov eax, [scanline_len_new]
+ sub [pixels_ptr], eax
+ mov ecx, [scanline_pixels_new]
+ mov esi, [line_buffer]
+ mov edi, [pixels_ptr]
+ rep movsd
+
+ pop ecx
+ jmp .next_column_cw_low
+
+.rotate_cw8ig:
+ .next_column_cw_low8ig:
+ dec ecx
+ js .exchange_dims
+ push ecx
+
+ mov edx, [scanline_len_old]
+ add [scanline_len_old], -1
+
+ mov ecx, [scanline_pixels_new]
+ mov esi, [pixels_ptr]
+ add esi, -1
+ mov edi, [line_buffer]
+ @@: mov al, [esi]
+ mov [edi], al
+ sub esi, edx
+ add edi, 1
+ 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 + 1]
+ 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, 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_low8ig
+
+.rotate_cw24:
+ .next_column_cw_low24:
+ dec ecx
+ js .exchange_dims
+ push ecx
+
+ mov edx, [scanline_len_old]
+ add [scanline_len_old], -3
+
+ mov ecx, [scanline_pixels_new]
+ mov esi, [pixels_ptr]
+ add esi, -3
+ mov edi, [line_buffer]
+ @@: mov al, [esi]
+ mov [edi], al
+ mov al, [esi+1]
+ mov [edi+1], al
+ mov al, [esi+2]
+ mov [edi+2], al
+ sub esi, edx
+ add edi, 3
+ 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 + 3]
+ 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_low24
+
+
+.rotate_cw1:
+ push ecx edx
+
+ mov eax, [ebx + Image.Height]
+ add eax, 7
+ shr eax, 3
+ imul [ebx + Image.Width]
+ push eax ; save new data size
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ push eax ; save pointer to new data
+
+ mov edi, eax
+ mov esi, [ebx + Image.Data]
+ mov eax, [ebx + Image.Height]
+ dec eax
+ imul eax, [scanline_len_old]
+ add esi, eax
+ mov eax, 7
+ mov ecx, 7
+ mov edx, 0
+
+ .rotate_cw1.begin:
+ bt [esi], ecx
+ jc .rotate_cw1.one
+ .rotate_cw1.zero:
+ btr [edi], eax
+ jmp @f
+ .rotate_cw1.one:
+ bts [edi], eax
+ @@:
+ sub esi, [scanline_len_old]
+ dec [scanline_pixels_new]
+ jz .rotate_cw1.end_of_line
+ sub eax, 1
+ adc edi, 0
+ and eax, 7
+ jmp .rotate_cw1.begin
+ .rotate_cw1.end_of_line:
+ inc edi
+ mov eax, [ebx + Image.Height]
+ mov [scanline_pixels_new], eax
+ mov eax, 7
+ dec ecx
+ jns @f
+ mov ecx, 7
+ inc edx
+ cmp edx, [scanline_len_old]
+ je .rotate_cw1.quit
+ @@:
+ mov esi, [ebx + Image.Height]
+ dec esi
+ imul esi, [scanline_len_old]
+ add esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_cw1.begin
+ .rotate_cw1.quit:
+ pop eax ; get pointer to new data
+ mov esi, eax
+ mov edi, [ebx + Image.Data]
+ pop ecx ; get new data size
+ rep movsb
+ invoke mem.free, eax
+ pop edx ecx
+ jmp .exchange_dims
+
+
+.rotate_cw2i:
+ push ecx edx
+
+ mov eax, [ebx + Image.Height]
+ add eax, 3
+ shr eax, 2
+ imul [ebx + Image.Width]
+ push eax ; save new data size
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ push eax ; save pointer to new data
+
+ mov edi, eax
+ mov esi, [ebx + Image.Data]
+ mov eax, [ebx + Image.Height]
+ dec eax
+ imul eax, [scanline_len_old]
+ add esi, eax
+ mov eax, 3
+ mov ecx, 3
+ mov edx, 0
+
+ .rotate_cw2i.begin:
+ push ebx ecx
+ mov ebx, 3
+ shl ebx, cl
+ shl ebx, cl
+ and bl, [esi]
+ shr ebx, cl
+ shr ebx, cl
+ mov bh, 3
+ mov ecx, eax
+ shl ebx, cl
+ shl ebx, cl
+ not bh
+ and bh, [edi]
+ or bl, bh
+ mov [edi], bl
+ pop ecx ebx
+
+ sub esi, [scanline_len_old]
+ dec [scanline_pixels_new]
+ jz .rotate_cw2i.end_of_line
+ sub eax, 1
+ adc edi, 0
+ and eax, 3
+ jmp .rotate_cw2i.begin
+ .rotate_cw2i.end_of_line:
+ inc edi
+ mov eax, [ebx + Image.Height]
+ mov [scanline_pixels_new], eax
+ mov eax, 3
+ dec ecx
+ jns @f
+ mov ecx, 3
+ inc edx
+ cmp edx, [scanline_len_old]
+ je .rotate_cw2i.quit
+ @@:
+ mov esi, [ebx + Image.Height]
+ dec esi
+ imul esi, [scanline_len_old]
+ add esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_cw2i.begin
+ .rotate_cw2i.quit:
+ pop eax ; get pointer to new data
+ mov esi, eax
+ mov edi, [ebx + Image.Data]
+ pop ecx ; get new data size
+ rep movsb
+ invoke mem.free, eax
+ pop edx ecx
+ jmp .exchange_dims
+
+
+.rotate_cw4i:
+ push ecx edx
+
+ mov eax, [ebx + Image.Height]
+ add eax, 1
+ shr eax, 1
+ imul [ebx + Image.Width]
+ push eax ; save new data size
+
+ invoke mem.alloc, eax
+ or eax, eax
+ jz .error
+ push eax ; save pointer to new data
+
+ mov edi, eax
+ mov esi, [ebx + Image.Data]
+ mov eax, [ebx + Image.Height]
+ dec eax
+ imul eax, [scanline_len_old]
+ add esi, eax
+ mov eax, 1
+ mov ecx, 1
+ mov edx, 0
+
+ .rotate_cw4i.begin:
+ push ebx ecx
+ mov ebx, 15
+ shl ecx, 2
+ shl ebx, cl
+ and bl, [esi]
+ shr ebx, cl
+ mov bh, 15
+ mov ecx, eax
+ shl ecx, 2
+ shl ebx, cl
+ not bh
+ and bh, [edi]
+ or bl, bh
+ mov [edi], bl
+ pop ecx ebx
+
+ sub esi, [scanline_len_old]
+ dec [scanline_pixels_new]
+ jz .rotate_cw4i.end_of_line
+ sub eax, 1
+ adc edi, 0
+ and eax, 1
+ jmp .rotate_cw4i.begin
+ .rotate_cw4i.end_of_line:
+ inc edi
+ mov eax, [ebx + Image.Height]
+ mov [scanline_pixels_new], eax
+ mov eax, 1
+ dec ecx
+ jns @f
+ mov ecx, 1
+ inc edx
+ cmp edx, [scanline_len_old]
+ je .rotate_cw4i.quit
+ @@:
+ mov esi, [ebx + Image.Height]
+ dec esi
+ imul esi, [scanline_len_old]
+ add esi, [ebx + Image.Data]
+ add esi, edx
+ jmp .rotate_cw4i.begin
+ .rotate_cw4i.quit:
+ pop eax ; get pointer to new data
+ mov esi, eax
+ mov edi, [ebx + Image.Data]
+ pop ecx ; get new data size
+ rep movsb
+ invoke mem.free, eax
+ pop edx ecx
+ jmp .exchange_dims
+
+
+ .flip:
+ stdcall img.flip.layer, [_img], FLIP_VERTICAL
+ test eax, eax
+ jz .error
+ jmp .exit
+
+ .exchange_dims:
+ push [ebx + Image.Width] [ebx + Image.Height]
+ pop [ebx + Image.Width] [ebx + Image.Height]
+
+ .exit:
+ invoke mem.free, [line_buffer]
+ xor eax, eax
+ inc eax
+ pop edi esi ebx
+ ret
+
+ .error:
+ invoke mem.free, [line_buffer]
+ xor eax, eax
+ pop edi esi ebx
+ 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
+ push eax
+ mov eax, [ebx + Image.Width]
+ imul eax, [_ypos]
+ add eax, [_xpos]
+ call img._.get_scanline_len
+ add eax, [ebx + Image.Data]
+ mov edx, [_x - 2]
+ mov dx, word [_y]
+ mov esi, [ebx + Image.Type]
+ mov esi, [type2bpp + (esi-1)*4]
+ mov edi, [ebx + Image.Palette]
+ xchg eax, ebx
+ pop eax
+ push ebp
+ push 65
+ pop ebp
+ xchg eax, ebp
+ int 40h
+ pop ebp
+.done:
+ pop edi esi ebx
+ ret
+endp
+
+
+align 4
+img.formats_table:
+ .bmp dd LIBIMG_FORMAT_BMP, img.is.bmp, img.decode.bmp, img.encode.bmp, 1 + (1 SHL Image.bpp24) + (1 SHL Image.bpp32)
+ .ico dd LIBIMG_FORMAT_ICO, img.is.ico, img.decode.ico_cur, img.encode.ico, 0
+ .cur dd LIBIMG_FORMAT_CUR, img.is.cur, img.decode.ico_cur, img.encode.cur, 0
+ .gif dd LIBIMG_FORMAT_GIF, img.is.gif, img.decode.gif, img.encode.gif, 0
+ .png dd LIBIMG_FORMAT_PNG, img.is.png, img.decode.png, img.encode.png, 1 + (1 SHL Image.bpp24)
+ .jpg dd LIBIMG_FORMAT_JPEG, img.is.jpg, img.decode.jpg, img.encode.jpg, 0
+ .tga dd LIBIMG_FORMAT_TGA, img.is.tga, img.decode.tga, img.encode.tga, 0
+ .pcx dd LIBIMG_FORMAT_PCX, img.is.pcx, img.decode.pcx, img.encode.pcx, 0
+ .xcf dd LIBIMG_FORMAT_XCF, img.is.xcf, img.decode.xcf, img.encode.xcf, 0
+ .tiff dd LIBIMG_FORMAT_TIFF, img.is.tiff, img.decode.tiff, img.encode.tiff,0
+ .pnm dd LIBIMG_FORMAT_PNM, img.is.pnm, img.decode.pnm, img.encode.pnm, 1 + (1 SHL Image.bpp1) + (1 SHL Image.bpp8g) + (1 SHL Image.bpp24)
+ .wbmp dd LIBIMG_FORMAT_WBMP, img.is.wbmp, img.decode.wbmp, img.encode.wbmp,0
+ .xbm dd LIBIMG_FORMAT_XBM, img.is.xbm, img.decode.xbm, img.encode.xbm, 0
+ .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)
+
+;;================================================================================================;;
+;;////////////////////////////////////////////////////////////////////////////////////////////////;;
+;;================================================================================================;;
+;! Below are private procs you should never call directly from your code ;;
+;;================================================================================================;;
+;;////////////////////////////////////////////////////////////////////////////////////////////////;;
+;;================================================================================================;;
+
+
+;;================================================================================================;;
+proc img._.validate, _img ;///////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< --- TBD --- ;;
+;;================================================================================================;;
+ xor eax, eax
+ ret
+endp
+
+;;================================================================================================;;
+proc img._.new ;//////////////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = 0 / pointer to image ;;
+;;================================================================================================;;
+ invoke mem.alloc, sizeof.Image
+ test eax, eax
+ jz @f
+ push ecx
+ 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
+ pop ecx
+@@:
+ ret
+endp
+
+;;================================================================================================;;
+proc img._.delete _img ;//////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = false / true ;;
+;;================================================================================================;;
+ push edx
+ mov edx, [_img]
+ cmp [edx + Image.Data], 0
+ je @f
+ invoke mem.free, [edx + Image.Data]
+ @@: cmp [edx + Image.Extended], 0
+ je @f
+ invoke mem.free, [edx + Image.Extended]
+ @@: invoke mem.free, edx
+ pop edx
+ ret
+endp
+
+;;================================================================================================;;
+proc img._.resize_data _img, _width, _height ;////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;> --- TBD --- ;;
+;;------------------------------------------------------------------------------------------------;;
+;< --- TBD --- ;;
+;;================================================================================================;;
+ push ebx esi
+ mov ebx, [_img]
+ mov eax, [_height]
+; our memory is limited, [_width]*[_height] must not overflow
+; image with width or height greater than 65535 is most likely bogus
+ cmp word [_width+2], 0
+ jnz .error
+ cmp word [_height+2], 0
+ jnz .error
+ imul eax, [_width]
+ test eax, eax
+ jz .error
+ cmp [ebx + Image.Type], Image.bpp1
+ jz .bpp1
+ cmp [ebx + Image.Type], Image.bpp2i
+ jz .bpp2i
+ cmp [ebx + Image.Type], Image.bpp4i
+ jz .bpp4i
+ cmp [ebx + Image.Type], Image.bpp8i
+ jz .bpp8i
+ cmp [ebx + Image.Type], Image.bpp8g
+ jz .bpp8g
+ cmp [ebx + Image.Type], Image.bpp8a
+ jz .bpp8a
+ cmp [ebx + Image.Type], Image.bpp24
+ jz .bpp24
+.bpp32:
+ shl eax, 2
+ jmp @f
+.bpp24:
+ lea eax, [eax*3]
+ jmp @f
+.bpp8i:
+ add eax, 256*4 ; for palette
+.bpp8g:
+ jmp @f
+.bpp8a:
+ shl eax, 1
+ jmp @f
+.bpp4i:
+ mov eax, [_width]
+ add eax, 1
+ shr eax, 1
+ imul eax, [_height]
+ mov ecx, eax
+ mov eax, [_height]
+ add eax, 1
+ shr eax, 1
+ imul eax, [_width]
+ cmp eax, ecx
+ jge .bpp4i.skip
+ mov eax, ecx
+ .bpp4i.skip:
+ add eax, 16*4 ; for palette
+ jmp @f
+.bpp2i:
+ mov eax, [_width]
+ add eax, 3
+ shr eax, 2
+ imul eax, [_height]
+ mov ecx, eax
+ mov eax, [_height]
+ add eax, 3
+ shr eax, 2
+ imul eax, [_width]
+ cmp eax, ecx
+ jge .bpp2i.skip
+ mov eax, ecx
+ .bpp2i.skip:
+ add eax, 4*4 ; for palette
+ jmp @f
+.bpp1:
+ mov eax, [_width]
+ add eax, 7
+ shr eax, 3
+ imul eax, [_height]
+ mov ecx, eax
+ mov eax, [_height]
+ add eax, 7
+ shr eax, 3
+ imul eax, [_width]
+ cmp eax, ecx
+ jge .bpp1.skip
+ mov eax, ecx
+ .bpp1.skip:
+
+ add eax, 2*4 ; for palette
+@@:
+ mov esi, eax
+ invoke mem.realloc, [ebx + Image.Data], eax
+ or eax, eax
+ jz .error
+
+ mov [ebx + Image.Data], eax
+ push [_width]
+ pop [ebx + Image.Width]
+ push [_height]
+ pop [ebx + Image.Height]
+ cmp [ebx + Image.Type], Image.bpp8i
+ jnz @f
+ lea esi, [eax + esi - 256*4]
+ mov [ebx + Image.Palette], esi
+ jmp .ret
+@@:
+ cmp [ebx + Image.Type], Image.bpp1
+ jnz @f
+ lea esi, [eax + esi - 2*4]
+ mov [ebx + Image.Palette], esi
+ jmp .ret
+@@:
+ cmp [ebx + Image.Type], Image.bpp2i
+ jnz @f
+ lea esi, [eax + esi - 4*4]
+ mov [ebx + Image.Palette], esi
+ jmp .ret
+@@:
+ cmp [ebx + Image.Type], Image.bpp4i
+ jnz .ret
+ lea esi, [eax + esi - 16*4]
+ mov [ebx + Image.Palette], esi
+ jmp .ret
+
+ .error:
+ xor eax, eax
+ .ret:
+ pop esi ebx
+ ret
+endp
+
+;;================================================================================================;;
+img._.get_scanline_len: ;/////////////////////////////////////////////////////////////////////////;;
+;;------------------------------------------------------------------------------------------------;;
+;? Get scanline length of image in bytes ;;
+;;------------------------------------------------------------------------------------------------;;
+;> eax = width of image in pixels ;;
+;> ebx = image ;;
+;;------------------------------------------------------------------------------------------------;;
+;< eax = scanline length in bytes ;;
+;;================================================================================================;;
+ cmp [ebx + Image.Type], Image.bpp1
+ jz .bpp1.1
+ cmp [ebx + Image.Type], Image.bpp2i
+ jz .bpp2i.1
+ cmp [ebx + Image.Type], Image.bpp4i
+ jz .bpp4i.1
+ cmp [ebx + Image.Type], Image.bpp8i
+ jz .bpp8.1
+ cmp [ebx + Image.Type], Image.bpp8g
+ jz .bpp8.1
+ cmp [ebx + Image.Type], Image.bpp8a
+ jz .bpp8a.1
+ cmp [ebx + Image.Type], Image.bpp24
+ jz .bpp24.1
+ add eax, eax
+ cmp [ebx + Image.Type], Image.bpp32
+ jnz .quit
+ add eax, eax
+ jmp .quit
+.bpp24.1:
+ lea eax, [eax*3]
+ jmp .quit
+.bpp1.1:
+ add eax, 7
+ shr eax, 3
+ jmp .quit
+.bpp2i.1:
+ add eax, 3
+ shr eax, 2
+ jmp .quit
+.bpp4i.1:
+ add eax, 1
+ shr eax, 1
+ jmp .quit
+.bpp8a.1:
+ shl eax, 1
+.bpp8.1:
+.quit:
+ ret
+
+
+;;================================================================================================;;
+;;////////////////////////////////////////////////////////////////////////////////////////////////;;
+;;================================================================================================;;
+;! Below is private data you should never use directly from your code ;;
+;;================================================================================================;;
+;;////////////////////////////////////////////////////////////////////////////////////////////////;;
+;;================================================================================================;;
+
+align 4
+type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4
+img._.do_rgb.handlers:
+ dd img._.do_rgb.bpp8i
+ 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
+ dd img._.do_rgb.bpp1
+ dd img._.do_rgb.bpp8g
+ dd img._.do_rgb.bpp2i
+ dd img._.do_rgb.bpp4i
+
+img.flip.layer.handlers_horz:
+ dd img.flip.layer.bpp8ig_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
+ dd img.flip.layer.bpp1_horz
+ dd img.flip.layer.bpp8ig_horz
+ dd img.flip.layer.bpp2i_horz
+ dd img.flip.layer.bpp4i_horz
+
+;;================================================================================================;;
+;;////////////////////////////////////////////////////////////////////////////////////////////////;;
+;;================================================================================================;;
+;! Exported functions section ;;
+;;================================================================================================;;
+;;////////////////////////////////////////////////////////////////////////////////////////////////;;
+;;================================================================================================;;
+
+
+align 4
+@EXPORT:
+
+export \
+ lib_init , 'lib_init' , \
+ 0x00050007 , 'version' , \
+ img.is_img , 'img_is_img' , \
+ img.info , 'img_info' , \
+ img.from_file , 'img_from_file' , \
+ img.to_file , 'img_to_file' , \
+ img.from_rgb , 'img_from_rgb' , \
+ img.to_rgb , 'img_to_rgb' , \
+ img.to_rgb2 , 'img_to_rgb2' , \
+ img.decode , 'img_decode' , \
+ 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.flip.layer , 'img_flip_layer' , \
+ img.rotate , 'img_rotate' , \
+ 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'
+
+; import from deflate unpacker
+; is initialized only when PNG loading is requested
+align 16
+@IMPORT:
+
+library archiver, 'archiver.obj'
+import archiver, \
+ deflate_unpack2, 'deflate_unpack2',\
+ deflateInit2, 'deflateInit2',\
+ deflateReset, 'deflateReset',\
+ deflate, 'deflate',\
+ deflateEnd, 'deflateEnd',\
+ calc_crc32, 'calc_crc32'
+
+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
+color_table_2 rd 256
+color_table_3 rd 256
+color_table_4 rd 256
diff --git a/programs/develop/libraries/libs-dev/libimg/libimg.inc b/programs/develop/libraries/libs-dev/libimg/libimg.inc
index a617f8a171..23f92b4fff 100644
--- a/programs/develop/libraries/libs-dev/libimg/libimg.inc
+++ b/programs/develop/libraries/libs-dev/libimg/libimg.inc
@@ -1,124 +1,127 @@
-;;================================================================================================;;
-;;//// libimg.inc //// (c) mike.dld, 2007-2008, (c) diamond, 2009, (c) dunkaist, 2011-2013 ///////;;
-;;================================================================================================;;
-;; ;;
-;; 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 . ;;
-;; ;;
-;;================================================================================================;;
-
-; list of format id's
-LIBIMG_FORMAT_BMP = 1
-LIBIMG_FORMAT_ICO = 2
-LIBIMG_FORMAT_CUR = 3
-LIBIMG_FORMAT_GIF = 4
-LIBIMG_FORMAT_PNG = 5
-LIBIMG_FORMAT_JPEG = 6
-LIBIMG_FORMAT_TGA = 7
-LIBIMG_FORMAT_PCX = 8
-LIBIMG_FORMAT_XCF = 9
-LIBIMG_FORMAT_TIFF = 10
-LIBIMG_FORMAT_PNM = 11
-LIBIMG_FORMAT_WBMP = 12
-LIBIMG_FORMAT_XBM = 13
-LIBIMG_FORMAT_Z80 = 14
-
-; scale type ; corresponding img.scale params
-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_WIDTH = 5 ; new width ; new height
-LIBIMG_SCALE_FIT_HEIGHT = 6 ; new width ; new height
-LIBIMG_SCALE_FIT_MAX = 7 ; new width ; new height
-
-; interpolation algorithm
-LIBIMG_INTER_NONE = 0 ; use it with LIBIMG_SCALE_INTEGER, LIBIMG_SCALE_TILE, etc
-LIBIMG_INTER_BILINEAR = 1
-;LIBIMG_INTER_BICUBIC = 2
-;LIBIMG_INTER_LANCZOS = 3
-LIBIMG_INTER_DEFAULT = LIBIMG_INTER_BILINEAR
-
-; error codes
-LIBIMG_ERROR_OUT_OF_MEMORY = 1
-LIBIMG_ERROR_FORMAT = 2
-LIBIMG_ERROR_CONDITIONS = 3
-LIBIMG_ERROR_BIT_DEPTH = 4
-LIBIMG_ERROR_ENCODER = 5
-LIBIMG_ERROR_SRC_TYPE = 6
-LIBIMG_ERROR_SCALE = 7
-LIBIMG_ERROR_INTER = 8
-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_BIT_DEPTH = 0x02
-LIBIMG_ENCODE_DELETE_ALPHA = 0x08
-LIBIMG_ENCODE_FLUSH_ALPHA = 0x10
-
-; convert flags
-; TBD
-
-struct FormatsTableEntry
- Format_id dd ?
- Is dd ?
- Decode dd ?
- Encode dd ?
- Capabilities dd ?
-ends
-
-struct Image
- Checksum dd ? ; ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far
- Width dd ?
- Height dd ?
- Next dd ?
- Previous dd ?
- Type dd ? ; one of Image.bppN
- Data dd ?
- Palette dd ? ; used iff Type eq Image.bpp1, Image.bpp2, Image.bpp4 or Image.bpp8i
- 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.bpp8i = 1 ; indexed
-Image.bpp24 = 2
-Image.bpp32 = 3
-Image.bpp15 = 4
-Image.bpp16 = 5
-Image.bpp1 = 6
-Image.bpp8g = 7 ; grayscale
-Image.bpp2i = 8
-Image.bpp4i = 9
-Image.bpp8a = 10 ; grayscale with alpha channel; application layer only!!! kernel doesn't handle this image type, libimg can only create and destroy such images
-
-; bits in Image.Flags
-Image.IsAnimated = 1
-
-struct ImageDecodeOptions
- UsedSize dd ? ; if >=8, the field BackgroundColor is valid, and so on
- BackgroundColor dd ? ; used for transparent images as background
-ends
-
-FLIP_VERTICAL = 0x01
-FLIP_HORIZONTAL = 0x02
-FLIP_BOTH = FLIP_VERTICAL or FLIP_HORIZONTAL
-
-ROTATE_90_CW = 0x01
-ROTATE_180 = 0x02
-ROTATE_270_CW = 0x03
-ROTATE_90_CCW = ROTATE_270_CW
-ROTATE_270_CCW = ROTATE_90_CW
+;;================================================================================================;;
+;;//// libimg.inc //// (c) mike.dld, 2007-2008, (c) diamond, 2009, (c) dunkaist, 2011-2013 ///////;;
+;;================================================================================================;;
+;; ;;
+;; 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 . ;;
+;; ;;
+;;================================================================================================;;
+
+; list of format id's
+LIBIMG_FORMAT_BMP = 1
+LIBIMG_FORMAT_ICO = 2
+LIBIMG_FORMAT_CUR = 3
+LIBIMG_FORMAT_GIF = 4
+LIBIMG_FORMAT_PNG = 5
+LIBIMG_FORMAT_JPEG = 6
+LIBIMG_FORMAT_TGA = 7
+LIBIMG_FORMAT_PCX = 8
+LIBIMG_FORMAT_XCF = 9
+LIBIMG_FORMAT_TIFF = 10
+LIBIMG_FORMAT_PNM = 11
+LIBIMG_FORMAT_WBMP = 12
+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_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
+
+; interpolation algorithm
+LIBIMG_INTER_NONE = 0 ; use it with LIBIMG_SCALE_INTEGER, LIBIMG_SCALE_TILE, etc
+LIBIMG_INTER_BILINEAR = 1
+;LIBIMG_INTER_BICUBIC = 2
+;LIBIMG_INTER_LANCZOS = 3
+LIBIMG_INTER_DEFAULT = LIBIMG_INTER_BILINEAR
+
+; error codes
+LIBIMG_ERROR_OUT_OF_MEMORY = 1
+LIBIMG_ERROR_FORMAT = 2
+LIBIMG_ERROR_CONDITIONS = 3
+LIBIMG_ERROR_BIT_DEPTH = 4
+LIBIMG_ERROR_ENCODER = 5
+LIBIMG_ERROR_SRC_TYPE = 6
+LIBIMG_ERROR_SCALE = 7
+LIBIMG_ERROR_INTER = 8
+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_BIT_DEPTH = 0x02
+;LIBIMG_ENCODE_DELETE_ALPHA = 0x08
+;LIBIMG_ENCODE_FLUSH_ALPHA = 0x10
+
+; convert flags
+; none so far
+
+struct FormatsTableEntry
+ Format_id dd ?
+ Is dd ?
+ Decode dd ?
+ Encode dd ?
+ Capabilities dd ?
+ends
+
+struct Image
+ Checksum dd ? ; ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far
+ Width dd ?
+ Height dd ?
+ Next dd ?
+ Previous dd ?
+ Type dd ? ; one of Image.bppN
+ Data dd ?
+ Palette dd ? ; used iff Type eq Image.bpp1, Image.bpp2, Image.bpp4 or Image.bpp8i
+ 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.bpp8i = 1 ; indexed
+Image.bpp24 = 2
+Image.bpp32 = 3
+Image.bpp15 = 4
+Image.bpp16 = 5
+Image.bpp1 = 6
+Image.bpp8g = 7 ; grayscale
+Image.bpp2i = 8
+Image.bpp4i = 9
+Image.bpp8a = 10 ; grayscale with alpha channel; application layer only!!! kernel doesn't handle this image type, libimg can only create and destroy such images
+
+; bits in Image.Flags
+Image.IsAnimated = 1
+
+struct ImageDecodeOptions
+ UsedSize dd ? ; if >=8, the field BackgroundColor is valid, and so on
+ BackgroundColor dd ? ; used for transparent images as background
+ends
+
+FLIP_VERTICAL = 0x01
+FLIP_HORIZONTAL = 0x02
+FLIP_BOTH = FLIP_VERTICAL or FLIP_HORIZONTAL
+
+ROTATE_90_CW = 0x01
+ROTATE_180 = 0x02
+ROTATE_270_CW = 0x03
+ROTATE_90_CCW = ROTATE_270_CW
+ROTATE_270_CCW = ROTATE_90_CW
diff --git a/programs/develop/libraries/libs-dev/libimg/scale.asm b/programs/develop/libraries/libs-dev/libimg/scale.asm
index cc932e4c2a..f8f3fce470 100644
--- a/programs/develop/libraries/libs-dev/libimg/scale.asm
+++ b/programs/develop/libraries/libs-dev/libimg/scale.asm
@@ -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,685 +110,714 @@ 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 ;;
;;================================================================================================;;
locals
- src_type rd 1
- src_data rd 1
- dst_data rd 1
+ src_type rd 1
+ src_data rd 1
+ dst_data rd 1
- src_width_pixels rd 1
- src_width_bytes rd 1
- src_height_pixels rd 1
+ src_width_pixels rd 1
+ src_width_bytes rd 1
+ src_height_pixels rd 1
- dst_width_pixels rd 1
- dst_width_pixels_inv rd 1
- dst_height_pixels rd 1
- dst_height_pixels_inv rd 1
- dst_width_bytes rd 1
- bytes_per_pixel rd 1
+ dst_width_pixels rd 1
+ dst_width_pixels_inv rd 1
+ dst_height_pixels rd 1
+ dst_height_pixels_inv rd 1
+ dst_width_bytes rd 1
+ bytes_per_pixel rd 1
- crop_width_pixels_m1 rd 1
- crop_height_pixels_m1 rd 1
+ crop_width_pixels_m1 rd 1
+ crop_height_pixels_m1 rd 1
; bilinear
- src_x rd 1
- src_y rd 1
- src_base rd 1
- dst_x rd 1
- dst_y rd 1
- rem_x rd 1
- rem_y rd 1
+ src_x rd 1
+ src_y rd 1
+ src_base rd 1
+ dst_x rd 1
+ dst_y rd 1
+ rem_x rd 1
+ rem_y rd 1
endl
- mov ebx, [_src]
- push [ebx + Image.Width]
- pop [src_width_pixels]
- push [ebx + Image.Height]
- pop [src_height_pixels]
- push [ebx + Image.Type]
- pop [src_type]
- push [ebx + Image.Data]
- pop [src_data]
+ push ebx esi edi
+ mov ebx, [_src]
+ push [ebx + Image.Width]
+ pop [src_width_pixels]
+ push [ebx + Image.Height]
+ pop [src_height_pixels]
+ push [ebx + Image.Type]
+ pop [src_type]
+ push [ebx + Image.Data]
+ pop [src_data]
- mov eax, [src_type]
- mov ecx, [src_width_pixels]
- mov edx, [src_width_pixels]
- imul edx, [_crop_y]
- add edx, [_crop_x]
- cmp eax, Image.bpp32
- jne @f
- mov [bytes_per_pixel], 4
- shl ecx, 2
- shl edx, 2
- jmp .lab1
+ mov eax, [src_type]
+ mov ecx, [src_width_pixels]
+ mov edx, [src_width_pixels]
+ imul edx, [_crop_y]
+ add edx, [_crop_x]
+ cmp eax, Image.bpp32
+ jne @f
+ mov [bytes_per_pixel], 4
+ shl ecx, 2
+ shl edx, 2
+ jmp .lab1
@@:
- cmp eax, Image.bpp24
- jne @f
- mov [bytes_per_pixel], 3
- lea ecx, [ecx*3]
- lea edx, [edx*3]
- jmp .lab1
+ cmp eax, Image.bpp24
+ jne @f
+ mov [bytes_per_pixel], 3
+ lea ecx, [ecx*3]
+ lea edx, [edx*3]
+ jmp .lab1
@@:
- cmp eax, Image.bpp8g
- jne @f
- mov [bytes_per_pixel], 1
- jmp .lab1
+ cmp eax, Image.bpp8g
+ jne @f
+ mov [bytes_per_pixel], 1
+ jmp .lab1
@@:
- mov ecx, LIBIMG_ERROR_BIT_DEPTH
- jmp .error
+ mov ecx, LIBIMG_ERROR_BIT_DEPTH
+ jmp .error
.lab1:
- mov [src_width_bytes], ecx
- add [src_data], edx
+ mov [src_width_bytes], ecx
+ add [src_data], edx
- mov eax, [_scale]
- cmp eax, LIBIMG_SCALE_INTEGER
- je .scale_type.integer
- cmp eax, LIBIMG_SCALE_TILE
- je .scale_type.tile
- cmp eax, LIBIMG_SCALE_FIT_RECT
- je .scale_type.fit_rect
- cmp eax, LIBIMG_SCALE_FIT_WIDTH
- je .scale_type.fit_width
- cmp eax, LIBIMG_SCALE_FIT_HEIGHT
- je .scale_type.fit_height
- cmp eax, LIBIMG_SCALE_FIT_MAX
- je .scale_type.fit_max
- cmp eax, LIBIMG_SCALE_STRETCH
- je .scale_type.stretch
- mov ecx, LIBIMG_ERROR_SCALE
- jmp .error
+ mov eax, [_scale]
+ cmp eax, LIBIMG_SCALE_INTEGER
+ je .scale_type.integer
+ cmp eax, LIBIMG_SCALE_TILE
+ je .scale_type.tile
+ cmp eax, LIBIMG_SCALE_FIT_RECT
+ je .scale_type.fit_rect
+ cmp eax, LIBIMG_SCALE_FIT_WIDTH
+ je .scale_type.fit_width
+ cmp eax, LIBIMG_SCALE_FIT_HEIGHT
+ je .scale_type.fit_height
+ cmp eax, LIBIMG_SCALE_FIT_MAX
+ je .scale_type.fit_max
+ cmp eax, LIBIMG_SCALE_STRETCH
+ je .scale_type.stretch
+ mov ecx, LIBIMG_ERROR_SCALE
+ jmp .error
.scale_type.integer:
- jmp .integer
+ jmp .integer
.scale_type.tile:
- jmp .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
- imul eax, [bytes_per_pixel]
- mov [dst_width_bytes], eax
- mov ecx, [_param2]
- mov [dst_height_pixels], ecx
- jmp .define_inter
+ mov eax, [_param1]
+ mov [dst_width_pixels], eax
+ imul eax, [bytes_per_pixel]
+ mov [dst_width_bytes], eax
+ mov ecx, [_param2]
+ mov [dst_height_pixels], ecx
+ jmp .define_inter
.define_inter:
- mov eax, [_inter]
- cmp eax, LIBIMG_INTER_BILINEAR
- je .bilinear
- mov ecx, LIBIMG_ERROR_INTER
- jmp .error
+ mov eax, [_inter]
+ cmp eax, LIBIMG_INTER_BILINEAR
+ je .bilinear
+ mov ecx, LIBIMG_ERROR_INTER
+ jmp .error
.integer:
- mov eax, [_param1]
- mov ecx, [_crop_width]
- imul ecx, eax
- mov [dst_width_pixels], ecx
- mov edx, [_crop_height]
- imul edx, eax
- mov [dst_height_pixels], edx
+ mov eax, [_param1]
+ mov ecx, [_crop_width]
+ imul ecx, eax
+ mov [dst_width_pixels], ecx
+ mov edx, [_crop_height]
+ imul edx, eax
+ mov [dst_height_pixels], edx
- mov eax, [_dst]
- test eax, eax
- jnz @f
- stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
- test eax, eax
- jz .error
- mov [_dst], eax
+ mov eax, [_dst]
+ test eax, eax
+ jnz @f
+ stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
+ 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
+ mov edi, [eax + Image.Data]
+ mov [dst_data], edi
- mov esi, [src_data]
- mov eax, [src_type]
- cmp eax, Image.bpp8g
- je .integer.bpp8g
- cmp eax, Image.bpp24
- je .integer.bpp24
- cmp eax, Image.bpp32
- je .integer.bpp32
- mov ecx, LIBIMG_ERROR_BIT_DEPTH
- jmp .error
+ mov esi, [src_data]
+ mov eax, [src_type]
+ cmp eax, Image.bpp8g
+ je .integer.bpp8g
+ cmp eax, Image.bpp24
+ je .integer.bpp24
+ cmp eax, Image.bpp32
+ je .integer.bpp32
+ mov ecx, LIBIMG_ERROR_BIT_DEPTH
+ jmp .error
.integer.bpp8g:
- push [dst_width_pixels]
- pop [dst_width_bytes]
- mov ecx, [_param1]
-; cmp ecx, 1
-; je .error
+ push [dst_width_pixels]
+ pop [dst_width_bytes]
+ mov ecx, [_param1]
+; cmp ecx, 1
+; je .error
.integer.bpp8g.common:
- mov edx, ecx
- mov ebx, [_crop_height]
+ mov edx, ecx
+ mov ebx, [_crop_height]
.integer.bpp8g.common.line:
- push ebx
- mov ebx, [_crop_width]
- @@:
- lodsb
- mov ecx, edx
- rep stosb
- dec ebx
- jnz @b
- push esi
- mov esi, edi
- sub esi, [dst_width_bytes]
- mov ecx, edx
- dec ecx
- imul ecx, [dst_width_bytes]
- mov eax, ecx
- shr ecx, 2
- and eax, 0x00000003
- rep movsd
- mov ecx, eax
- rep movsb
- pop esi
- mov eax, [src_width_pixels]
- sub eax, [_crop_width]
- add esi, eax
- pop ebx
- dec ebx
- jnz .integer.bpp8g.common.line
- mov eax, [_dst]
- jmp .quit
+ push ebx
+ mov ebx, [_crop_width]
+ @@:
+ lodsb
+ mov ecx, edx
+ rep stosb
+ dec ebx
+ jnz @b
+ push esi
+ mov esi, edi
+ sub esi, [dst_width_bytes]
+ mov ecx, edx
+ dec ecx
+ imul ecx, [dst_width_bytes]
+ mov eax, ecx
+ shr ecx, 2
+ and eax, 0x00000003
+ rep movsd
+ mov ecx, eax
+ rep movsb
+ pop esi
+ mov eax, [src_width_pixels]
+ sub eax, [_crop_width]
+ add esi, eax
+ pop ebx
+ dec ebx
+ jnz .integer.bpp8g.common.line
+ mov eax, [_dst]
+ jmp .quit
.integer.bpp24:
- mov eax, [dst_width_pixels]
- lea eax, [eax*3]
- mov [dst_width_bytes], eax
- mov ecx, [_param1]
-; cmp ecx, 1
-; je .error
+ mov eax, [dst_width_pixels]
+ lea eax, [eax*3]
+ mov [dst_width_bytes], eax
+ mov ecx, [_param1]
+; cmp ecx, 1
+; je .error
.integer.bpp24.common:
- mov edx, ecx
- mov ebx, [_crop_height]
+ mov edx, ecx
+ mov ebx, [_crop_height]
.integer.bpp24.common.line:
- push ebx
- mov ebx, [_crop_width]
- @@:
- movsw
- movsb
- mov ecx, edx
- push esi
- mov esi, edi
- sub esi, 3
- dec ecx
- lea ecx, [ecx*3]
- rep movsb
- pop esi
- dec ebx
- jnz @b
- push esi
- mov esi, edi
- sub esi, [dst_width_bytes]
- mov ecx, edx
- dec ecx
- imul ecx, [dst_width_bytes]
- mov eax, ecx
- shr ecx, 2
- and eax, 0x00000003
- rep movsd
- mov ecx, eax
- rep movsb
- pop esi
- mov eax, [src_width_pixels]
- sub eax, [_crop_width]
- lea eax, [eax*3]
- add esi, eax
- pop ebx
- dec ebx
- jnz .integer.bpp24.common.line
- mov eax, [_dst]
- jmp .quit
+ push ebx
+ mov ebx, [_crop_width]
+ @@:
+ movsw
+ movsb
+ mov ecx, edx
+ push esi
+ mov esi, edi
+ sub esi, 3
+ dec ecx
+ lea ecx, [ecx*3]
+ rep movsb
+ pop esi
+ dec ebx
+ jnz @b
+ push esi
+ mov esi, edi
+ sub esi, [dst_width_bytes]
+ mov ecx, edx
+ dec ecx
+ imul ecx, [dst_width_bytes]
+ mov eax, ecx
+ shr ecx, 2
+ and eax, 0x00000003
+ rep movsd
+ mov ecx, eax
+ rep movsb
+ pop esi
+ mov eax, [src_width_pixels]
+ sub eax, [_crop_width]
+ lea eax, [eax*3]
+ add esi, eax
+ pop ebx
+ dec ebx
+ jnz .integer.bpp24.common.line
+ mov eax, [_dst]
+ jmp .quit
.integer.bpp32:
- mov eax, [dst_width_pixels]
- shl eax, 2
- mov [dst_width_bytes], eax
- mov ecx, [_param1]
-; cmp ecx, 1
-; je .error
+ mov eax, [dst_width_pixels]
+ shl eax, 2
+ mov [dst_width_bytes], eax
+ mov ecx, [_param1]
+; cmp ecx, 1
+; je .error
.integer.bpp32.common:
- mov edx, ecx
- mov ebx, [_crop_height]
+ mov edx, ecx
+ mov ebx, [_crop_height]
.integer.bpp32.common.line:
- push ebx
- mov ebx, [_crop_width]
- @@:
- lodsd
- mov ecx, edx
- rep stosd
- dec ebx
- jnz @b
- push esi
- mov esi, edi
- sub esi, [dst_width_bytes]
- mov ecx, edx
- dec ecx
- imul ecx, [dst_width_bytes]
- shr ecx, 2
- rep movsd
- pop esi
- mov eax, [src_width_pixels]
- sub eax, [_crop_width]
- shl eax, 2
- add esi, eax
- pop ebx
- dec ebx
- jnz .integer.bpp32.common.line
- mov eax, [_dst]
- jmp .quit
+ push ebx
+ mov ebx, [_crop_width]
+ @@:
+ lodsd
+ mov ecx, edx
+ rep stosd
+ dec ebx
+ jnz @b
+ push esi
+ mov esi, edi
+ sub esi, [dst_width_bytes]
+ mov ecx, edx
+ dec ecx
+ imul ecx, [dst_width_bytes]
+ shr ecx, 2
+ rep movsd
+ pop esi
+ mov eax, [src_width_pixels]
+ sub eax, [_crop_width]
+ shl eax, 2
+ add esi, eax
+ pop ebx
+ dec ebx
+ jnz .integer.bpp32.common.line
+ mov eax, [_dst]
+ jmp .quit
.tile:
- mov eax, [_param1]
- mov [dst_width_pixels], eax
- imul eax, [bytes_per_pixel]
- mov [dst_width_bytes], eax
- mov eax, [_param2]
- mov [dst_height_pixels], eax
+ mov eax, [_param1]
+ mov [dst_width_pixels], eax
+ imul eax, [bytes_per_pixel]
+ mov [dst_width_bytes], eax
+ mov eax, [_param2]
+ mov [dst_height_pixels], eax
- mov eax, [_dst]
- test eax, eax
- jnz @f
- stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
- test eax, eax
- jz .error
- mov [_dst], eax
- @@:
- mov edi, [eax + Image.Data]
- mov [dst_data], edi
+ mov eax, [_dst]
+ test eax, eax
+ jnz @f
+ stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
+ 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
- mov esi, [src_data]
- mov eax, [_crop_height]
- cmp eax, [dst_height_pixels]
- jna @f
- mov eax, [dst_height_pixels]
- @@:
- push eax
- mov ecx, [_crop_width]
- cmp ecx, [dst_width_pixels]
- jna @f
- mov ecx, [dst_width_pixels]
- @@:
- imul ecx, [bytes_per_pixel]
- mov edx, ecx
- @@:
- mov ecx, edx
- rep movsb
+ mov esi, [src_data]
+ mov eax, [_crop_height]
+ cmp eax, [dst_height_pixels]
+ jna @f
+ mov eax, [dst_height_pixels]
+ @@:
+ push eax
+ mov ecx, [_crop_width]
+ cmp ecx, [dst_width_pixels]
+ jna @f
+ mov ecx, [dst_width_pixels]
+ @@:
+ imul ecx, [bytes_per_pixel]
+ mov edx, ecx
+ @@:
+ mov ecx, edx
+ rep movsb
- push esi
- mov esi, edi
- sub esi, edx
- mov ecx, [dst_width_bytes]
- sub ecx, edx
- rep movsb
- pop esi
+ push esi
+ mov esi, edi
+ sub esi, edx
+ mov ecx, [dst_width_bytes]
+ sub ecx, edx
+ rep movsb
+ pop esi
- mov ecx, [src_width_bytes]
- sub ecx, edx
- add esi, ecx
- dec eax
- jnz @b
+ mov ecx, [src_width_bytes]
+ sub ecx, edx
+ add esi, ecx
+ dec eax
+ jnz @b
- pop eax
- mov esi, [dst_data]
- mov ecx, [dst_height_pixels]
- sub ecx, eax
- imul ecx, [dst_width_bytes]
- rep movsb
+ pop eax
+ mov esi, [dst_data]
+ mov ecx, [dst_height_pixels]
+ sub ecx, eax
+ imul ecx, [dst_width_bytes]
+ rep movsb
- mov eax, [_dst]
- jmp .quit
+ mov eax, [_dst]
+ jmp .quit
.bilinear:
- mov eax, [_dst]
- test eax, eax
- jnz @f
- stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
- test eax, eax
- jz .error
- mov [_dst], eax
+ mov eax, [_dst]
+ test eax, eax
+ jnz @f
+ stdcall img.create, [dst_width_pixels], [dst_height_pixels], [src_type]
+ 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
+ mov edi, [eax + Image.Data]
+ mov [dst_data], edi
- push [_crop_width]
- pop [crop_width_pixels_m1]
- sub [crop_width_pixels_m1], 1
- push [_crop_height]
- pop [crop_height_pixels_m1]
- sub [crop_height_pixels_m1], 1
+ push [_crop_width]
+ pop [crop_width_pixels_m1]
+ sub [crop_width_pixels_m1], 1
+ push [_crop_height]
+ pop [crop_height_pixels_m1]
+ sub [crop_height_pixels_m1], 1
- mov eax, 0xffffffff
- xor edx, edx
- div [dst_width_pixels]
- mov [dst_width_pixels_inv], eax
- mov eax, 0xffffffff
- xor edx, edx
- div [dst_height_pixels]
- mov [dst_height_pixels_inv], eax
+ mov eax, 0xffffffff
+ xor edx, edx
+ div [dst_width_pixels]
+ mov [dst_width_pixels_inv], eax
+ mov eax, 0xffffffff
+ xor edx, edx
+ div [dst_height_pixels]
+ mov [dst_height_pixels_inv], eax
- mov eax, [src_type]
- cmp eax, Image.bpp8g
- je .bilinear.bpp8g
- cmp eax, Image.bpp24
- je .bilinear.bpp24
- cmp eax, Image.bpp32
- je .bilinear.bpp32
- mov ecx, LIBIMG_ERROR_BIT_DEPTH
- jmp .error
+ mov eax, [src_type]
+ cmp eax, Image.bpp8g
+ je .bilinear.bpp8g
+ cmp eax, Image.bpp24
+ je .bilinear.bpp24
+ cmp eax, Image.bpp32
+ je .bilinear.bpp32
+ mov ecx, LIBIMG_ERROR_BIT_DEPTH
+ jmp .error
.bilinear.bpp8g:
- mov esi, [src_data]
- mov [dst_y], 0
- mov eax, 0 ; mov eax, [dst_y]
+ mov esi, [src_data]
+ mov [dst_y], 0
+ mov eax, 0 ; mov eax, [dst_y]
.bilinear.bpp8g.line:
- mov esi, [src_data]
- mov [dst_x], 0
- imul eax, [crop_height_pixels_m1]
- xor edx, edx
- div [dst_height_pixels]
- mov [rem_y], edx
- imul eax, [src_width_bytes]
- add esi, eax
- mov [src_base], esi
- mov eax, 0 ; mov eax, [dst_x]
+ mov esi, [src_data]
+ mov [dst_x], 0
+ imul eax, [crop_height_pixels_m1]
+ xor edx, edx
+ div [dst_height_pixels]
+ mov [rem_y], edx
+ imul eax, [src_width_bytes]
+ add esi, eax
+ mov [src_base], esi
+ mov eax, 0 ; mov eax, [dst_x]
.bilinear.bpp8g.pixel:
- mov esi, [src_base]
+ mov esi, [src_base]
- imul eax, [crop_width_pixels_m1]
- xor edx, edx
- div [dst_width_pixels]
- add esi, eax
+ imul eax, [crop_width_pixels_m1]
+ xor edx, edx
+ div [dst_width_pixels]
+ add esi, eax
- mov ax, word[esi]
- add esi, [src_width_pixels]
- mov bx, word[esi]
- mov esi, edx
- movzx edx, ah
- and eax, 0x000000ff
- movzx ecx, bh
- and ebx, 0x000000ff
+ mov ax, word[esi]
+ add esi, [src_width_pixels]
+ mov bx, word[esi]
+ mov esi, edx
+ movzx edx, ah
+ and eax, 0x000000ff
+ movzx ecx, bh
+ and ebx, 0x000000ff
- imul edx, esi
- imul ecx, esi
- neg esi
- add esi, [dst_width_pixels]
- imul eax, esi
- imul ebx, esi
- add eax, edx
- add ebx, ecx
- mov esi, [dst_width_pixels_inv]
- mul esi
- mov ecx, edx
- mov eax, ebx
- mul esi
- mov eax, edx
+ imul edx, esi
+ imul ecx, esi
+ neg esi
+ add esi, [dst_width_pixels]
+ imul eax, esi
+ imul ebx, esi
+ add eax, edx
+ add ebx, ecx
+ mov esi, [dst_width_pixels_inv]
+ mul esi
+ mov ecx, edx
+ mov eax, ebx
+ mul esi
+ mov eax, edx
- mov edx, [rem_y]
- imul eax, edx
- neg edx
- add edx, [dst_height_pixels]
- imul ecx, edx
- add eax, ecx
- mul [dst_height_pixels_inv]
- mov byte[edi], dl
- add edi, 1
+ mov edx, [rem_y]
+ imul eax, edx
+ neg edx
+ add edx, [dst_height_pixels]
+ imul ecx, edx
+ add eax, ecx
+ mul [dst_height_pixels_inv]
+ mov byte[edi], dl
+ add edi, 1
- add [dst_x], 1
- mov eax, [dst_x]
- cmp eax, [dst_width_pixels]
- jne .bilinear.bpp8g.pixel
+ add [dst_x], 1
+ mov eax, [dst_x]
+ cmp eax, [dst_width_pixels]
+ jne .bilinear.bpp8g.pixel
- add [dst_y], 1
- mov eax, [dst_y]
- cmp eax, [dst_height_pixels]
- jne .bilinear.bpp8g.line
+ add [dst_y], 1
+ mov eax, [dst_y]
+ cmp eax, [dst_height_pixels]
+ jne .bilinear.bpp8g.line
- mov eax, [_dst]
- jmp .quit
+ mov eax, [_dst]
+ jmp .quit
.bilinear.bpp24:
- mov esi, [src_data]
- mov [dst_y], 0
- mov eax, 0 ; mov eax, [dst_y]
+ mov esi, [src_data]
+ mov [dst_y], 0
+ mov eax, 0 ; mov eax, [dst_y]
.bilinear.bpp24.line:
- mov esi, [src_data]
- mov [dst_x], 0
- imul eax, [crop_height_pixels_m1]
- xor edx, edx
- div [dst_height_pixels]
- mov [rem_y], edx
- imul eax, [src_width_bytes]
- add esi, eax
- mov [src_base], esi
- mov eax, 0 ; mov eax, [dst_x]
+ mov esi, [src_data]
+ mov [dst_x], 0
+ imul eax, [crop_height_pixels_m1]
+ xor edx, edx
+ div [dst_height_pixels]
+ mov [rem_y], edx
+ imul eax, [src_width_bytes]
+ add esi, eax
+ mov [src_base], esi
+ mov eax, 0 ; mov eax, [dst_x]
.bilinear.bpp24.pixel:
- mov esi, [src_base]
+ mov esi, [src_base]
- imul eax, [crop_width_pixels_m1]
- xor edx, edx
- div [dst_width_pixels]
- lea eax, [eax*3]
- add esi, eax
+ imul eax, [crop_width_pixels_m1]
+ xor edx, edx
+ div [dst_width_pixels]
+ lea eax, [eax*3]
+ add esi, eax
- mov [rem_x], edx
- sub esi, 1
- mov [src_x], esi
+ mov [rem_x], edx
+ sub esi, 1
+ mov [src_x], esi
repeat 3
- mov edx, [rem_x]
- add [src_x], 1
- mov esi, [src_x]
+ mov edx, [rem_x]
+ add [src_x], 1
+ mov esi, [src_x]
- mov al, byte[esi]
- mov ah, byte[esi + 3]
- add esi, [src_width_bytes]
- movzx ebx, byte[esi]
- movzx ecx, byte[esi + 3]
- mov esi, edx
- movzx edx, ah
- and eax, 0x000000ff
+ mov al, byte[esi]
+ mov ah, byte[esi + 3]
+ add esi, [src_width_bytes]
+ movzx ebx, byte[esi]
+ movzx ecx, byte[esi + 3]
+ mov esi, edx
+ movzx edx, ah
+ and eax, 0x000000ff
- imul edx, esi
- imul ecx, esi
- neg esi
- add esi, [dst_width_pixels]
- imul eax, esi
- imul ebx, esi
- add eax, edx
- add ebx, ecx
- mov esi, [dst_width_pixels_inv]
- mul esi
- mov ecx, edx
- mov eax, ebx
- mul esi
- mov eax, edx
+ imul edx, esi
+ imul ecx, esi
+ neg esi
+ add esi, [dst_width_pixels]
+ imul eax, esi
+ imul ebx, esi
+ add eax, edx
+ add ebx, ecx
+ mov esi, [dst_width_pixels_inv]
+ mul esi
+ mov ecx, edx
+ mov eax, ebx
+ mul esi
+ mov eax, edx
- mov edx, [rem_y]
- imul eax, edx
- neg edx
- add edx, [dst_height_pixels]
- imul ecx, edx
- add eax, ecx
- mul [dst_height_pixels_inv]
- mov byte[edi], dl
- add edi, 1
+ mov edx, [rem_y]
+ imul eax, edx
+ neg edx
+ add edx, [dst_height_pixels]
+ imul ecx, edx
+ add eax, ecx
+ mul [dst_height_pixels_inv]
+ mov byte[edi], dl
+ add edi, 1
end repeat
- add [dst_x], 1
- mov eax, [dst_x]
- cmp eax, [dst_width_pixels]
- jne .bilinear.bpp24.pixel
+ add [dst_x], 1
+ mov eax, [dst_x]
+ cmp eax, [dst_width_pixels]
+ jne .bilinear.bpp24.pixel
- add [dst_y], 1
- mov eax, [dst_y]
- cmp eax, [dst_height_pixels]
- jne .bilinear.bpp24.line
+ add [dst_y], 1
+ mov eax, [dst_y]
+ cmp eax, [dst_height_pixels]
+ jne .bilinear.bpp24.line
- mov eax, [_dst]
- jmp .quit
+ mov eax, [_dst]
+ jmp .quit
.bilinear.bpp32:
- mov esi, [src_data]
- mov [dst_y], 0
- mov eax, 0 ; mov eax, [dst_y]
+ mov esi, [src_data]
+ mov [dst_y], 0
+ mov eax, 0 ; mov eax, [dst_y]
.bilinear.bpp32.line:
- mov esi, [src_data]
- mov [dst_x], 0
- imul eax, [crop_height_pixels_m1]
- xor edx, edx
- div [dst_height_pixels]
- mov [rem_y], edx
- imul eax, [src_width_bytes]
- add esi, eax
- mov [src_base], esi
- mov eax, 0 ; mov eax, [dst_x]
+ mov esi, [src_data]
+ mov [dst_x], 0
+ imul eax, [crop_height_pixels_m1]
+ xor edx, edx
+ div [dst_height_pixels]
+ mov [rem_y], edx
+ imul eax, [src_width_bytes]
+ add esi, eax
+ mov [src_base], esi
+ mov eax, 0 ; mov eax, [dst_x]
.bilinear.bpp32.pixel:
- mov esi, [src_base]
+ mov esi, [src_base]
- imul eax, [crop_width_pixels_m1]
- xor edx, edx
- div [dst_width_pixels]
- shl eax, 2
- add esi, eax
+ imul eax, [crop_width_pixels_m1]
+ xor edx, edx
+ div [dst_width_pixels]
+ shl eax, 2
+ add esi, eax
- mov [rem_x], edx
- sub esi, 1
- mov [src_x], esi
+ mov [rem_x], edx
+ sub esi, 1
+ mov [src_x], esi
repeat 4
- mov edx, [rem_x]
- add [src_x], 1
- mov esi, [src_x]
+ mov edx, [rem_x]
+ add [src_x], 1
+ mov esi, [src_x]
- mov al, byte[esi]
- mov ah, byte[esi + 4]
- add esi, [src_width_bytes]
- movzx ebx, byte[esi]
- movzx ecx, byte[esi + 4]
- mov esi, edx
- movzx edx, ah
- and eax, 0x000000ff
+ mov al, byte[esi]
+ mov ah, byte[esi + 4]
+ add esi, [src_width_bytes]
+ movzx ebx, byte[esi]
+ movzx ecx, byte[esi + 4]
+ mov esi, edx
+ movzx edx, ah
+ and eax, 0x000000ff
- imul edx, esi
- imul ecx, esi
- neg esi
- add esi, [dst_width_pixels]
- imul eax, esi
- imul ebx, esi
- add eax, edx
- add ebx, ecx
- mov esi, [dst_width_pixels_inv]
- mul esi
- mov ecx, edx
- mov eax, ebx
- mul esi
- mov eax, edx
+ imul edx, esi
+ imul ecx, esi
+ neg esi
+ add esi, [dst_width_pixels]
+ imul eax, esi
+ imul ebx, esi
+ add eax, edx
+ add ebx, ecx
+ mov esi, [dst_width_pixels_inv]
+ mul esi
+ mov ecx, edx
+ mov eax, ebx
+ mul esi
+ mov eax, edx
- mov edx, [rem_y]
- imul eax, edx
- neg edx
- add edx, [dst_height_pixels]
- imul ecx, edx
- add eax, ecx
- mul [dst_height_pixels_inv]
- mov byte[edi], dl
- add edi, 1
+ mov edx, [rem_y]
+ imul eax, edx
+ neg edx
+ add edx, [dst_height_pixels]
+ imul ecx, edx
+ add eax, ecx
+ mul [dst_height_pixels_inv]
+ mov byte[edi], dl
+ add edi, 1
end repeat
- add [dst_x], 1
- mov eax, [dst_x]
- cmp eax, [dst_width_pixels]
- jne .bilinear.bpp32.pixel
+ add [dst_x], 1
+ mov eax, [dst_x]
+ cmp eax, [dst_width_pixels]
+ jne .bilinear.bpp32.pixel
- add [dst_y], 1
- mov eax, [dst_y]
- cmp eax, [dst_height_pixels]
- jne .bilinear.bpp32.line
+ add [dst_y], 1
+ mov eax, [dst_y]
+ cmp eax, [dst_height_pixels]
+ jne .bilinear.bpp32.line
- mov eax, [_dst]
- jmp .quit
+ mov eax, [_dst]
+ jmp .quit
.error:
- xor eax, eax
+ xor eax, eax
.quit:
- ret
-
+ pop edi esi ebx
+ ret
endp