;;================================================================================================;; ;;//// convert.asm //// (c) dunkaist, 2012 ///////////////////////////////////////////////////////;; ;;================================================================================================;; ;; ;; ;; This file is part of Common development libraries (Libs-Dev). ;; ;; ;; ;; Libs-Dev is free software: you can redistribute it and/or modify it under the terms of the GNU ;; ;; Lesser General Public License as published by the Free Software Foundation, either version 2.1 ;; ;; of the License, or (at your option) any later version. ;; ;; ;; ;; Libs-Dev is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ;; ;; even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; ;; Lesser General Public License for more details. ;; ;; ;; ;; You should have received a copy of the GNU Lesser General Public License along with Libs-Dev. ;; ;; If not, see <http://www.gnu.org/licenses/>. ;; ;; ;; ;;================================================================================================;; ;;================================================================================================;; proc img.convert _src, _dst, _dst_type, _flags, _param ;; ;;------------------------------------------------------------------------------------------------;; ;? scale _image ;; ;;------------------------------------------------------------------------------------------------;; ;> [_src] = pointer to source image ;; ;> [_flags] = see libimg.inc ;; ;> [_dst_type] = the Image.Type of converted image ;; ;> [_dst] = pointer to destination image, if any ;; ;;------------------------------------------------------------------------------------------------;; ;< eax = 0 / pointer to converted image ;; ;< ecx = error code / undefined ;; ;;================================================================================================;; locals width rd 1 height rd 1 endl mov ebx, [_src] mov eax, 1 mov ecx, [_dst_type] shl eax, cl mov ecx, [ebx + Image.Type] test eax, [img.types_table + 4*ecx] jnz @f mov ecx, LIBIMG_ERROR_BIT_DEPTH jmp .error @@: mov eax, [_dst] test eax, eax jnz @f stdcall img.create, [ebx + Image.Width], [ebx + Image.Height], [_dst_type] test eax, eax jz .error mov [_dst], eax @@: mov edi, [eax + Image.Data] mov esi, [ebx + Image.Data] mov eax, [ebx + Image.Type] cmp eax, Image.bpp8i je .bpp8i cmp eax, Image.bpp8g je .bpp8g cmp eax, Image.bpp24 je .bpp24 cmp eax, Image.bpp32 je .bpp32 cmp eax, Image.bpp15 je .bpp15 cmp eax, Image.bpp16 je .bpp16 cmp eax, Image.bpp1 je .bpp1 cmp eax, Image.bpp8a je .bpp8a mov ecx, LIBIMG_ERROR_BIT_DEPTH jmp .error .find_in_table_and_jump: mov ecx, [_dst_type] @@: mov eax, [edx] add edx, 8 cmp eax, ecx jne @b jmp dword[edx - 4] .bpp8i: mov edx, img.convert.bpp8i.table jmp .find_in_table_and_jump .bpp8i_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] mov ebx, [ebx + Image.Palette] 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 mov eax, [_dst] jmp .quit .bpp8g: mov edx, img.convert.bpp8g.table jmp .find_in_table_and_jump .bpp8g_to_bpp1: mov eax, [_dst] mov eax, [eax + Image.Palette] mov dword[eax], 0x00000000 mov dword[eax + 4], 0x00ffffff mov edx, [ebx + Image.Height] .bpp8g_to_bpp1.line: mov ax, 0x0800 mov ecx, [ebx + Image.Width] .bpp8g_to_bpp1.pixel: shl al, 1 cmp byte[esi], 0x7f cmc adc eax, 0 add esi, 1 dec ah jnz @f mov byte[edi], al add edi, 1 mov ax, 0x0800 @@: dec ecx jnz .bpp8g_to_bpp1.pixel cmp ah, 8 je @f mov cl, ah shl al, cl mov byte[edi], al add edi, 1 @@: dec edx jnz .bpp8g_to_bpp1.line mov eax, [_dst] jmp .quit .bpp8g_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] @@: mov al, byte[esi] mov byte[edi + 0], al mov byte[edi + 1], al mov byte[edi + 2], al add esi, 1 add edi, 3 sub ecx, 1 jnz @b mov eax, [_dst] jmp .quit .bpp24: mov edx, img.convert.bpp24.table jmp .find_in_table_and_jump .bpp24_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] lea ecx, [ecx*3] mov edx, ecx shr ecx, 2 rep movsd mov ecx, edx and ecx, 3 rep movsb mov eax, [_dst] jmp .quit .bpp24_to_bpp8g: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] @@: movzx ebx, byte[esi + 0] movzx eax, byte[esi + 1] add ebx, eax movzx eax, byte[esi + 2] add eax, ebx mov ebx, 3 add esi, 3 div bl mov byte[edi], al add edi, 1 sub ecx, 1 jnz @b mov eax, [_dst] jmp .quit .bpp32: mov edx, img.convert.bpp32.table jmp .find_in_table_and_jump .bpp32_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] @@: mov eax, [esi] mov [edi], ax shr eax, 16 mov [edi + 2], al add esi, 4 add edi, 3 sub ecx, 1 jnz @b mov eax, [_dst] jmp .quit .bpp15: mov edx, img.convert.bpp15.table jmp .find_in_table_and_jump .bpp15_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] .bpp15.intel: ; copypasted from do_rgb 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 mov eax, [_dst] jmp .quit .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 .bpp16: mov edx, img.convert.bpp16.table jmp .find_in_table_and_jump .bpp16_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] .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 mov eax, [_dst] jmp .quit .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 .bpp1: mov edx, img.convert.bpp1.table jmp .find_in_table_and_jump .bpp1_to_bpp24: push [ebx + Image.Width] pop [width] push [ebx + Image.Height] pop [height] mov edx, [ebx + Image.Palette] .bpp1_to_bpp24.line: mov ebx, [width] .bpp1_to_bpp24.byte: mov ah, 8 mov al, byte[esi] add esi, 1 .bpp1_to_bpp24.bit: xor ecx, ecx shl al, 1 adc ecx, 0 mov ecx, [edx + 4*ecx] mov word[edi], cx shr ecx, 8 mov byte[edi + 2], ch add edi, 3 sub ebx, 1 jnz @f sub [height], 1 jnz .bpp1_to_bpp24.line jmp .bpp1.done @@: sub ah, 1 jnz .bpp1_to_bpp24.bit jmp .bpp1_to_bpp24.byte .bpp1.done: mov eax, [_dst] jmp .quit .bpp8a: mov edx, img.convert.bpp8a.table jmp .find_in_table_and_jump .bpp8a_to_bpp1: mov eax, [_dst] mov eax, [eax + Image.Palette] mov dword[eax], 0x00000000 mov dword[eax + 4], 0x00ffffff mov edx, [ebx + Image.Height] .bpp8a_to_bpp1.line: mov ax, 0x0800 mov ecx, [ebx + Image.Width] .bpp8a_to_bpp1.pixel: shl al, 1 cmp byte[esi], 0x7f cmc adc eax, 0 add esi, 2 dec ah jnz @f mov byte[edi], al add edi, 1 mov ax, 0x0800 @@: dec ecx jnz .bpp8a_to_bpp1.pixel cmp ah, 8 je @f mov cl, ah shl al, cl mov byte[edi], al add edi, 1 @@: dec edx jnz .bpp8a_to_bpp1.line mov eax, [_dst] jmp .quit .bpp8a_to_bpp24: mov ecx, [ebx + Image.Width] imul ecx, [ebx + Image.Height] @@: mov al, byte[esi] mov byte[edi + 0], al mov byte[edi + 1], al mov byte[edi + 2], al add esi, 2 add edi, 3 sub ecx, 1 jnz @b mov eax, [_dst] jmp .quit .error: xor eax, eax .quit: ret endp img.convert.bpp8i.table: dd Image.bpp24, img.convert.bpp8i_to_bpp24 img.convert.bpp8g.table: dd Image.bpp24, img.convert.bpp8g_to_bpp24 dd Image.bpp1, img.convert.bpp8g_to_bpp1 img.convert.bpp24.table: dd Image.bpp24, img.convert.bpp24_to_bpp24 dd Image.bpp8g, img.convert.bpp24_to_bpp8g img.convert.bpp32.table: dd Image.bpp24, img.convert.bpp32_to_bpp24 img.convert.bpp15.table: dd Image.bpp24, img.convert.bpp15_to_bpp24 img.convert.bpp16.table: dd Image.bpp24, img.convert.bpp16_to_bpp24 img.convert.bpp1.table: dd Image.bpp24, img.convert.bpp1_to_bpp24 img.convert.bpp8a.table: dd Image.bpp24, img.convert.bpp8a_to_bpp24