libimg: pcx: unpack scanlines, not color planes

git-svn-id: svn://kolibrios.org@3499 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Ivan Baravy 2013-05-10 12:28:39 +00:00
parent b3ade66ab3
commit a524093376
6 changed files with 507 additions and 130 deletions

View File

@ -45,6 +45,7 @@ include 'xcf/xcf.asm'
include 'tiff/tiff.asm' include 'tiff/tiff.asm'
include 'pnm/pnm.asm' include 'pnm/pnm.asm'
include 'wbmp/wbmp.asm' include 'wbmp/wbmp.asm'
include 'xbm/xbm.asm'
include 'scale.asm' include 'scale.asm'
include 'convert.asm' include 'convert.asm'
@ -1926,6 +1927,7 @@ img.formats_table:
.tiff dd LIBIMG_FORMAT_TIFF, img.is.tiff, img.decode.tiff, img.encode.tiff,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) .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 .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 .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 dd 0
@ -2161,7 +2163,7 @@ img._.get_scanline_len: ;///////////////////////////////////////////////////////
;;================================================================================================;; ;;================================================================================================;;
align 4 align 4
type2bpp dd 8, 24, 32, 15, 16, 1, 9 ;,16 type2bpp dd 8, 24, 32, 15, 16, 1, 9;, 2, 4
img._.do_rgb.handlers: img._.do_rgb.handlers:
dd img._.do_rgb.bpp8i dd img._.do_rgb.bpp8i
dd img._.do_rgb.bpp24 dd img._.do_rgb.bpp24

View File

@ -30,7 +30,8 @@ LIBIMG_FORMAT_XCF = 9
LIBIMG_FORMAT_TIFF = 10 LIBIMG_FORMAT_TIFF = 10
LIBIMG_FORMAT_PNM = 11 LIBIMG_FORMAT_PNM = 11
LIBIMG_FORMAT_WBMP = 12 LIBIMG_FORMAT_WBMP = 12
LIBIMG_FORMAT_Z80 = 13 LIBIMG_FORMAT_XBM = 13
LIBIMG_FORMAT_Z80 = 14
; scale type ; corresponding img.scale params ; scale type ; corresponding img.scale params
LIBIMG_SCALE_INTEGER = 1 ; scale factor ; reserved 0 LIBIMG_SCALE_INTEGER = 1 ; scale factor ; reserved 0
@ -78,14 +79,14 @@ struct FormatsTableEntry
ends ends
struct Image struct Image
Checksum dd ? ; ((Width ROL 16) OR Height) XOR Data[0] Checksum dd ? ; ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far
Width dd ? Width dd ?
Height dd ? Height dd ?
Next dd ? Next dd ?
Previous dd ? Previous dd ?
Type dd ? ; one of Image.bppN Type dd ? ; one of Image.bppN
Data dd ? Data dd ?
Palette dd ? ; used iff Type eq Image.bpp8 or Image.bpp1 Palette dd ? ; used iff Type eq Image.bpp1, Image.bpp2, Image.bpp4 or Image.bpp8i
Extended dd ? Extended dd ?
Flags dd ? ; bitfield Flags dd ? ; bitfield
Delay dd ? ; used iff Image.IsAnimated is set in Flags Delay dd ? ; used iff Image.IsAnimated is set in Flags
@ -101,8 +102,8 @@ Image.bpp16 = 5
Image.bpp1 = 6 Image.bpp1 = 6
Image.bpp8g = 7 ; grayscale Image.bpp8g = 7 ; grayscale
Image.bpp8a = 8 ; grayscale with alpha channel; application layer only!!! kernel doesn't handle this image type, libimg can only create and destroy such images Image.bpp8a = 8 ; grayscale with alpha channel; application layer only!!! kernel doesn't handle this image type, libimg can only create and destroy such images
;Image.bpp4 = 9 ;Image.bpp2 = 9
;Image.bpp2 = 10 ;Image.bpp4 = 10
; bits in Image.Flags ; bits in Image.Flags
Image.IsAnimated = 1 Image.IsAnimated = 1

View File

@ -1,5 +1,5 @@
;;================================================================================================;; ;;================================================================================================;;
;;//// pcx.asm //// (c) dunkaist, 2010,2012 //////////////////////////////////////////////////////;; ;;//// pcx.asm //// (c) dunkaist, 2010,2012-2013 /////////////////////////////////////////////////;;
;;================================================================================================;; ;;================================================================================================;;
;; ;; ;; ;;
;; This file is part of Common development libraries (Libs-Dev). ;; ;; This file is part of Common development libraries (Libs-Dev). ;;
@ -30,33 +30,27 @@ proc img.is.pcx _data, _length ;////////////////////////////////////////////////
;< eax = false / true ;; ;< eax = false / true ;;
;;================================================================================================;; ;;================================================================================================;;
push ecx edi push edi
xor eax, eax xor eax, eax
mov edi, [_data] mov edi, [_data]
cmp byte[edi + pcx_header.magic_number], 0x0A mov ecx, [edi]
jne .is_not_pcx shl ecx, 8
cmp byte[edi + pcx_header.version], 5 cmp ecx, 0x01050a00
jne .is_not_pcx
cmp byte[edi + pcx_header.encoding], 1
jne .is_not_pcx jne .is_not_pcx
cmp byte[edi + pcx_header.reserved], 0 cmp byte[edi + pcx_header.reserved], 0
jne .is_not_pcx jne .is_not_pcx
add edi, pcx_header.filler add edi, pcx_header.filler
xor al, al mov ecx, 58/2
mov ecx, 58 repe scasw
cld jne .is_not_pcx
repe scasb
test ecx, ecx
jnz .is_not_pcx
.is_pcx: .is_pcx:
inc eax inc eax
.is_not_pcx: .is_not_pcx:
pop edi ecx pop edi
ret ret
endp endp
@ -72,12 +66,13 @@ proc img.decode.pcx _data, _length, _options ;//////////////////////////////////
;< eax = 0 (error) or pointer to image ;; ;< eax = 0 (error) or pointer to image ;;
;;================================================================================================;; ;;================================================================================================;;
locals locals
nplanes rd 1 num_planes rd 1
xsize rd 1 width rd 1
ysize rd 1 height rd 1
bpl rd 1 bp_plane rd 1
total_bpl rd 1 bp_scanline rd 1
line_begin rd 1 line_begin rd 1
cur_scanline rd 1
retvalue rd 1 ; 0 (error) or pointer to image retvalue rd 1 ; 0 (error) or pointer to image
endl endl
@ -85,21 +80,21 @@ endl
mov esi, [_data] mov esi, [_data]
movzx eax, byte[esi + pcx_header.nplanes] movzx eax, byte[esi + pcx_header.nplanes]
mov [nplanes], eax mov [num_planes], eax
movzx ebx, word[esi + pcx_header.bpl] movzx ebx, word[esi + pcx_header.bpl]
mov [bpl], ebx mov [bp_plane], ebx
imul eax, ebx imul eax, ebx
mov [total_bpl], eax mov [bp_scanline], eax
movzx eax, word[esi + pcx_header.xmax] movzx eax, word[esi + pcx_header.xmax]
sub ax, word[esi + pcx_header.xmin] sub ax, word[esi + pcx_header.xmin]
inc eax inc eax
mov [xsize], eax mov [width], eax
movzx ebx, word[esi + pcx_header.ymax] movzx ebx, word[esi + pcx_header.ymax]
sub bx, word[esi + pcx_header.ymin] sub bx, word[esi + pcx_header.ymin]
inc ebx inc ebx
mov [ysize], ebx mov [height], ebx
cmp [esi + pcx_header.bpp], 1 cmp [esi + pcx_header.bpp], 1
jz .monochrome jz .monochrome
@ -108,56 +103,36 @@ endl
.24bit: .24bit:
stdcall img.create, [bp_plane], 1, Image.bpp24
mov [cur_scanline], eax
test eax, eax
jz .quit
stdcall img.create, eax, ebx, Image.bpp24 stdcall img.create, [width], [height], Image.bpp24
mov [retvalue], eax mov [retvalue], eax
test eax, eax test eax, eax
jz .quit jz .quit
mov esi, [_data] mov esi, [_data]
add esi, 128 ; skip header add esi, sizeof.pcx_header
mov edi, [eax + Image.Data] mov edx, [eax + Image.Data]
add edi, 2
mov [line_begin], edi
.24bit.scanline: .24bit.scanline:
mov ebx, [total_bpl] mov edi, [cur_scanline]
.24bit.color_line: mov ebx, [bp_scanline]
mov edx, [bpl] @@:
.24bit.next_byte:
call pcx._.get_byte call pcx._.get_byte
sub edx, ecx rep stosb
@@: test ebx, ebx
mov [edi], al jnz @b
add edi, [nplanes] stdcall pcx._.scanline_unpack, [width], [cur_scanline], [num_planes]
dec ecx dec [height]
jnz @b jnz .24bit.scanline
jmp .quit
test edx, edx
jnz .24bit.next_byte
.24bit.end_color_line:
test ebx, ebx
jz .24bit.end_full_line
dec [line_begin]
mov edi, [line_begin]
jmp .24bit.color_line
.24bit.end_full_line:
dec [ysize]
jz .quit
add edi, 2
bt [xsize], 0
jnc @f
sub edi, 3
@@:
mov [line_begin], edi
jmp .24bit.scanline
.indexed: .indexed:
stdcall img.create, [width], [height], Image.bpp8i
stdcall img.create, eax, ebx, Image.bpp8i
mov [retvalue], eax mov [retvalue], eax
test eax, eax test eax, eax
jz .quit jz .quit
@ -165,42 +140,40 @@ endl
mov ebx, eax mov ebx, eax
mov esi, [_data] mov esi, [_data]
add esi, [_length] add esi, [_length]
sub esi, 768 sub esi, 256*3 ; rgb triplets
mov edi, [eax + Image.Palette] mov edi, [eax + Image.Palette]
mov ecx, 256 mov ecx, 256
xor eax, eax mov eax, 0x0000ff00
@@: @@:
lodsw mov al, [esi + 0]
xchg al, ah mov [edi + 2], ax
shl eax, 8 mov al, [esi + 1]
lodsb mov [edi + 1], al
stosd mov al, [esi + 2]
mov [edi + 0], al
add esi, 3
add edi, 4
dec ecx dec ecx
jnz @b jnz @b
mov esi, [_data] mov esi, [_data]
add esi, 128 add esi, sizeof.pcx_header
mov edi, [ebx + Image.Data] mov edi, [ebx + Image.Data]
.indexed.line: .indexed.scanline:
mov ebx, [total_bpl] mov ebx, [bp_scanline]
.indexed.next_byte:
call pcx._.get_byte
@@: @@:
stosb call pcx._.get_byte
dec ecx rep stosb
jnz @b
test ebx, ebx test ebx, ebx
jnz .indexed.next_byte jnz @b
dec [height]
dec [ysize] jnz .indexed.scanline
jnz .indexed.line
jmp .quit jmp .quit
.monochrome: .monochrome:
stdcall img.create, [width], [height], Image.bpp1
stdcall img.create, eax, ebx, Image.bpp1
mov [retvalue], eax mov [retvalue], eax
test eax, eax test eax, eax
jz .quit jz .quit
@ -210,25 +183,20 @@ endl
mov [edi + 4], dword 0xffffffff mov [edi + 4], dword 0xffffffff
mov esi, [_data] mov esi, [_data]
add esi, 128 add esi, sizeof.pcx_header
mov edi, [eax + Image.Data] mov edi, [eax + Image.Data]
.monochrome.scanline:
.monochrome.line: mov ebx, [bp_scanline]
mov ebx, [total_bpl]
.monochrome.next_byte:
call pcx._.get_byte
@@: @@:
stosb call pcx._.get_byte
dec ecx rep stosb
jnz @b
test ebx, ebx test ebx, ebx
jnz .monochrome.next_byte jnz @b
dec [ysize] dec [height]
jnz .monochrome.line jnz .monochrome.scanline
; jmp .quit ; jmp .quit
.quit: .quit:
popa popa
mov eax, [retvalue] mov eax, [retvalue]
@ -262,20 +230,47 @@ endp
;;================================================================================================;; ;;================================================================================================;;
proc pcx._.get_byte proc pcx._.get_byte
xor ecx, ecx mov ecx, 1
xor eax, eax
lodsb lodsb
cmp al, 0xC0 cmp eax, 0xc0
setb cl jb @f
jb .done and eax, 0x3f
and al, 0x3F mov ecx, eax
mov cl, al
lodsb lodsb
.done: @@:
sub ebx, ecx sub ebx, ecx
ret ret
endp endp
proc pcx._.scanline_unpack _width, _scanline, _num_planes
push esi
mov esi, [_scanline]
mov ebx, [_num_planes]
dec ebx
.plane:
mov ecx, [_width]
mov edi, edx
add edi, ebx
@@:
mov al, [esi]
mov [edi], al
add esi, 1
add edi, [_num_planes]
dec ecx
jnz @b
bt dword[_width], 0
adc esi, 0
dec ebx
jns .plane
mov edx, edi
pop esi
ret
endp
;;================================================================================================;; ;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;; ;;================================================================================================;;

View File

@ -193,21 +193,25 @@ endl
push esi ; fixme!! push esi ; fixme!!
mov ecx, [edx + Image.Type] mov ecx, [edx + Image.Type]
dec ecx cmp ecx, Image.bpp8i
jz .bpp8i je .bpp8i
dec ecx cmp ecx, Image.bpp24
jz .bpp24 je .bpp24
dec ecx cmp ecx, Image.bpp32
jz .bpp32 je .bpp32
dec ecx cmp ecx, Image.bpp16
dec ecx ; tiff doesn't handle 15bpp images je .bpp16
jz .bpp16 cmp ecx, Image.bpp1
dec ecx je .bpp1
jz .bpp1 cmp ecx, Image.bpp8g
dec ecx je .bpp8g
jz .bpp8g cmp ecx, Image.bpp8a
dec ecx je .bpp8a
jz .bpp8a ; cmp ecx, Image.bpp2
; je .bpp2
; cmp ecx, Image.bpp4
; je .bpp4
jmp .quit
;error report!! ;error report!!
.bpp1: .bpp1:
@ -224,6 +228,9 @@ endl
mov [edi + 4], dword 0x00000000 mov [edi + 4], dword 0x00000000
jmp .common jmp .common
.bpp2:
jmp .common
.bpp4: .bpp4:
jmp .common jmp .common
@ -351,6 +358,9 @@ endl
.decoded: .decoded:
cmp [ebx + tiff_extra.planar_configuration], TIFF.PLANAR.PLANAR
jne .post.rgb_bgr
stdcall tiff._.planar_to_separate, [retvalue]
.post.rgb_bgr: .post.rgb_bgr:
cmp [ebx + tiff_extra.samples_per_pixel], 3 cmp [ebx + tiff_extra.samples_per_pixel], 3
jne .post.rgba_bgra jne .post.rgba_bgra
@ -617,6 +627,21 @@ proc tiff._.parse_IFDE _data, _endianness
mov [ebx + tiff_extra.strip_byte_counts], eax mov [ebx + tiff_extra.strip_byte_counts], eax
jmp .quit jmp .quit
.tag_11c: ; Planar configuration
cmp ax, TIFF.IFDE_TYPE.SHORT
jne @f
lodsd
xor eax, eax
lodsw_
mov [ebx + tiff_extra.planar_configuration], eax
;debug_print 'planar_configuration: '
;debug_print_dec eax
;newline
lodsw
@@:
jmp .quit
.tag_13d: ; Predictor .tag_13d: ; Predictor
cmp ax, TIFF.IFDE_TYPE.SHORT cmp ax, TIFF.IFDE_TYPE.SHORT
jne @f jne @f
@ -710,17 +735,16 @@ endp
proc tiff._.decompress.packbits _image proc tiff._.decompress.packbits _image
push ebx ecx edx esi push edx
mov edx, ecx mov edx, ecx
.decode: .decode:
lodsb lodsb
dec edx dec edx
cmp al, 0x7f
jbe .different
cmp al, 0x80 cmp al, 0x80
jne .identical jb .different
jg .identical
test edx, edx test edx, edx
jz .quit jz .quit
jmp .decode jmp .decode
@ -745,7 +769,7 @@ proc tiff._.decompress.packbits _image
jnz .decode jnz .decode
.quit: .quit:
pop esi edx ecx ebx pop edx
ret ret
endp endp
@ -1167,6 +1191,75 @@ proc tiff._.pack_8a _img
ret ret
endp endp
proc tiff._.planar_to_separate _img
locals
pixels rd 1
tmp_image rd 1
channels rd 1
channel_padding rd 1
endl
pushad
mov ebx, [_img]
mov ecx, [ebx + Image.Width]
imul ecx, [ebx + Image.Height]
mov [pixels], ecx
cmp [ebx + Image.Type], Image.bpp24
je .bpp24
cmp [ebx + Image.Type], Image.bpp32
je .bpp32
; cmp [ebx + Image.Type], Image.bpp4
; je .bpp4
jmp .quit
.bpp24:
mov [channels], 3
mov [channel_padding], 2
lea eax, [ecx*3]
jmp .proceed
.bpp32:
mov [channels], 4
mov [channel_padding], 3
shl eax, 2
jmp .proceed
.bpp4:
mov [channels], 3
mov [channel_padding], 2
shr eax, 1
jmp .proceed
.proceed:
invoke mem.alloc, eax
test eax, eax
jz .quit
mov [tmp_image], eax
.channel:
mov esi, [ebx + Image.Data]
mov edi, [tmp_image]
mov ecx, [pixels]
mov eax, [channel_padding]
inc eax
sub eax, [channels]
add edi, eax
mov eax, [channels]
dec eax
imul eax, [pixels]
add esi, eax
@@:
lodsb
stosb
add edi, [channel_padding]
dec ecx
jnz @b
dec [channels]
jnz .channel
.quit:
mov eax, [tmp_image]
xchg [ebx + Image.Data], eax
invoke mem.free, eax
popad
ret
endp
;;================================================================================================;; ;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;; ;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;; ;;================================================================================================;;
@ -1184,6 +1277,7 @@ tiff.IFDE_tag_table.begin:
.tag_115: dd 0x0115, tiff._.parse_IFDE.tag_115 ; samples per pixel .tag_115: dd 0x0115, tiff._.parse_IFDE.tag_115 ; samples per pixel
.tag_116: dd 0x0116, tiff._.parse_IFDE.tag_116 ; rows per strip .tag_116: dd 0x0116, tiff._.parse_IFDE.tag_116 ; rows per strip
.tag_117: dd 0x0117, tiff._.parse_IFDE.tag_117 ; strip byte counts .tag_117: dd 0x0117, tiff._.parse_IFDE.tag_117 ; strip byte counts
.tag_11c: dd 0x011c, tiff._.parse_IFDE.tag_11c ; planar configuration
.tag_13d: dd 0x013d, tiff._.parse_IFDE.tag_13d ; predictor .tag_13d: dd 0x013d, tiff._.parse_IFDE.tag_13d ; predictor
.tag_140: dd 0x0140, tiff._.parse_IFDE.tag_140 ; color map .tag_140: dd 0x0140, tiff._.parse_IFDE.tag_140 ; color map
.tag_152: dd 0x0152, tiff._.parse_IFDE.tag_152 ; extra samples .tag_152: dd 0x0152, tiff._.parse_IFDE.tag_152 ; extra samples

View File

@ -23,6 +23,7 @@ struct tiff_header
first_IFD rd 1 first_IFD rd 1
ends ends
struct tiff_extra struct tiff_extra
image_width rd 1 ; SHORT or LONG image_width rd 1 ; SHORT or LONG
image_height rd 1 ; SHORT or LONG image_height rd 1 ; SHORT or LONG
@ -38,6 +39,7 @@ struct tiff_extra
strip_byte_counts_length rd 1 strip_byte_counts_length rd 1
palette rd 1 ; SHORT palette rd 1 ; SHORT
palette_size rd 1 ; in colors, not samples palette_size rd 1 ; in colors, not samples
planar_configuration rd 1 ; SHORT
extra_samples rd 1 ; pointer to array of SHORTs extra_samples rd 1 ; pointer to array of SHORTs
extra_samples_number rd 1 extra_samples_number rd 1
predictor rd 1 ; SHORT predictor rd 1 ; SHORT
@ -87,6 +89,9 @@ TIFF.PHOTOMETRIC.CMYK = 5
TIFF.PHOTOMETRIC.YCbCr = 6 TIFF.PHOTOMETRIC.YCbCr = 6
TIFF.PHOTOMETRIC.CIELAB = 8 TIFF.PHOTOMETRIC.CIELAB = 8
TIFF.PLANAR.CHUNKY = 1
TIFF.PLANAR.PLANAR = 2
macro lodsw_ macro lodsw_
{ {

View File

@ -0,0 +1,280 @@
;;================================================================================================;;
;;//// 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'