281 lines
11 KiB
NASM
281 lines
11 KiB
NASM
|
;;================================================================================================;;
|
||
|
;;//// xbm.asm //// (c) dunkaist, 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 <http://www.gnu.org/licenses/>. ;;
|
||
|
;; ;;
|
||
|
;;================================================================================================;;
|
||
|
|
||
|
;;================================================================================================;;
|
||
|
proc img.is.xbm _data, _length ;//////////////////////////////////////////////////////////////////;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;? Determine if raw data could be decoded (is in xbm format) ;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;> _data = raw data as read from file/stream ;;
|
||
|
;> _length = data length ;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;< eax = false / true ;;
|
||
|
;;================================================================================================;;
|
||
|
|
||
|
push ebx ecx esi edi
|
||
|
xor eax, eax
|
||
|
|
||
|
mov edi, [_data]
|
||
|
mov ecx, 4 ; BOM
|
||
|
mov al, '#'
|
||
|
repne scasb
|
||
|
jne .is_not_xbm
|
||
|
dec edi
|
||
|
mov esi, str_define
|
||
|
mov ecx, str_define.size
|
||
|
repe cmpsb
|
||
|
jne .is_not_xbm
|
||
|
mov esi, edi
|
||
|
call xbm._.skip_whitespace
|
||
|
mov edx, esi
|
||
|
call xbm._.wait_whitespace
|
||
|
mov ebx, esi
|
||
|
sub ebx, edx
|
||
|
sub ebx, 5
|
||
|
cmp word[esi - 6], '_w'
|
||
|
jne .is_not_xbm
|
||
|
cmp dword[esi - 4], 'idth'
|
||
|
jne .is_not_xbm
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.wait_whitespace
|
||
|
call xbm._.skip_whitespace
|
||
|
mov edi, str_define
|
||
|
mov ecx, str_define.size
|
||
|
repe cmpsb
|
||
|
jne .is_not_xbm
|
||
|
call xbm._.skip_whitespace
|
||
|
mov edi, edx
|
||
|
mov ecx, ebx
|
||
|
repe cmpsb
|
||
|
jne .is_not_xbm
|
||
|
cmp dword[esi], 'heig'
|
||
|
jne .is_not_xbm
|
||
|
cmp word[esi + 4], 'ht'
|
||
|
jne .is_not_xbm
|
||
|
|
||
|
.is_xbm:
|
||
|
pop edi esi ecx ebx
|
||
|
xor eax, eax
|
||
|
inc eax
|
||
|
ret
|
||
|
.is_not_xbm:
|
||
|
pop edi esi ecx ebx
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
;;================================================================================================;;
|
||
|
proc img.decode.xbm _data, _length, _options ;////////////////////////////////////////////////////;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;? Decode data into image if it contains correctly formed raw data in xbm format ;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;> _data = raw data as read from file/stream ;;
|
||
|
;> _length = data length ;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;< eax = 0 (error) or pointer to image ;;
|
||
|
;;================================================================================================;;
|
||
|
locals
|
||
|
width rd 1
|
||
|
height rd 1
|
||
|
counter rd 1
|
||
|
retvalue rd 1 ; 0 (error) or pointer to image
|
||
|
endl
|
||
|
|
||
|
pusha
|
||
|
|
||
|
mov esi, [_data]
|
||
|
add esi, 5
|
||
|
call xbm._.wait_whitespace
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.wait_whitespace
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.read_number
|
||
|
mov [width], eax
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.wait_whitespace
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.wait_whitespace
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.read_number
|
||
|
mov [height], eax
|
||
|
stdcall img.create, [width], [height], Image.bpp1
|
||
|
test eax, eax
|
||
|
jz .quit
|
||
|
mov [retvalue], eax
|
||
|
|
||
|
mov edi, [_data]
|
||
|
mov ecx, [_length]
|
||
|
mov eax, '{'
|
||
|
repne scasb
|
||
|
mov esi, edi
|
||
|
|
||
|
mov ebx, [retvalue]
|
||
|
mov eax, [ebx + Image.Palette]
|
||
|
mov dword[eax], 0xffffffff
|
||
|
mov dword[eax + 4], 0xff000000
|
||
|
mov ecx, [ebx + Image.Width]
|
||
|
add ecx, 7
|
||
|
shr ecx, 3
|
||
|
imul ecx, [ebx + Image.Height]
|
||
|
mov [counter], ecx
|
||
|
mov edi, [ebx + Image.Data]
|
||
|
@@:
|
||
|
call xbm._.skip_whitespace
|
||
|
call xbm._.read_number
|
||
|
mov cl, al
|
||
|
and eax, 0x0f
|
||
|
mov al, byte[reverse_bits + eax]
|
||
|
shl eax, 4
|
||
|
mov edx, eax
|
||
|
mov al, cl
|
||
|
shr eax, 4
|
||
|
mov al, byte[reverse_bits + eax]
|
||
|
or eax, edx
|
||
|
mov byte[edi], al
|
||
|
add edi, 1
|
||
|
sub [counter], 1
|
||
|
jnz @b
|
||
|
.quit:
|
||
|
popa
|
||
|
mov eax, [retvalue]
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
;;================================================================================================;;
|
||
|
proc img.encode.xbm _img, _common, _specific ;////////////////////////////////////////////////////;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;? Encode image into raw data in xbm format ;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;> [_img] = pointer to image ;;
|
||
|
;> [_common] = format independent options ;;
|
||
|
;> [_specific] = 0 / pointer to the structure of format specific options ;;
|
||
|
;;------------------------------------------------------------------------------------------------;;
|
||
|
;< eax = 0 / pointer to encoded data ;;
|
||
|
;< ecx = error code / the size of encoded data ;;
|
||
|
;;================================================================================================;;
|
||
|
xor eax, eax
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
;;================================================================================================;;
|
||
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
||
|
;;================================================================================================;;
|
||
|
;! Below are private procs you should never call directly from your code ;;
|
||
|
;;================================================================================================;;
|
||
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
||
|
;;================================================================================================;;
|
||
|
proc xbm._.skip_whitespace
|
||
|
.next_byte:
|
||
|
movzx eax, byte[esi]
|
||
|
cmp eax, 0x20
|
||
|
jne @f
|
||
|
add esi, 1
|
||
|
jmp .next_byte
|
||
|
@@:
|
||
|
cmp eax, 0x09
|
||
|
jne @f
|
||
|
add esi, 1
|
||
|
jmp .next_byte
|
||
|
@@:
|
||
|
cmp eax, 0x0a
|
||
|
jne @f
|
||
|
add esi, 1
|
||
|
jmp .next_byte
|
||
|
@@:
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
proc xbm._.wait_whitespace
|
||
|
@@:
|
||
|
movzx eax, byte[esi]
|
||
|
cmp eax, 0x20
|
||
|
je @f
|
||
|
cmp eax, 0x09
|
||
|
je @f
|
||
|
cmp eax, 0x0a
|
||
|
je @f
|
||
|
add esi, 1
|
||
|
jmp @b
|
||
|
@@:
|
||
|
ret
|
||
|
endp
|
||
|
|
||
|
|
||
|
proc xbm._.read_number
|
||
|
xor eax, eax
|
||
|
mov ecx, eax
|
||
|
mov al, byte[esi]
|
||
|
add esi, 1
|
||
|
sub al, 0x30
|
||
|
test al, al
|
||
|
jz .octal_or_hex
|
||
|
.decimal:
|
||
|
mov ebx, 10
|
||
|
imul ecx, ebx
|
||
|
add ecx, eax
|
||
|
mov al, byte[esi]
|
||
|
add esi, 1
|
||
|
sub al, 0x30
|
||
|
cmp al, 10
|
||
|
jb .decimal
|
||
|
jmp .done
|
||
|
.octal_or_hex:
|
||
|
mov al, byte[esi]
|
||
|
add esi, 1
|
||
|
sub al, 0x30
|
||
|
cmp al, 'x' - 0x30
|
||
|
je .hex
|
||
|
.octal:
|
||
|
jmp .done
|
||
|
.hex:
|
||
|
mov al, byte[esi]
|
||
|
add esi, 1
|
||
|
sub al, 0x30
|
||
|
jc .done
|
||
|
cmp al, 9
|
||
|
jna @f
|
||
|
sub al, 0x30 - 9
|
||
|
jc .done
|
||
|
cmp al, 15
|
||
|
ja .done
|
||
|
@@:
|
||
|
shl ecx, 4
|
||
|
add ecx, eax
|
||
|
jmp .hex
|
||
|
.done:
|
||
|
mov eax, ecx
|
||
|
ret
|
||
|
endp
|
||
|
;;================================================================================================;;
|
||
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
||
|
;;================================================================================================;;
|
||
|
;! Below is private data you should never use directly from your code ;;
|
||
|
;;================================================================================================;;
|
||
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
||
|
;;================================================================================================;;
|
||
|
reverse_bits db 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
|
||
|
sz str_define , '#define'
|
||
|
sz str__width , '_width'
|
||
|
sz str__height , '_height'
|
||
|
|