0,0 → 1,585 |
;;================================================================================================;; |
;;//// 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 |