libimg: 1bpp (monochrome) images support,

pcx.asm now uses 1bpp functions too, pcx code optimization


git-svn-id: svn://kolibrios.org@1593 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Ivan Baravy 2010-08-25 14:59:27 +00:00
parent ce4a26a80d
commit 23b7fbd318
3 changed files with 438 additions and 248 deletions

View File

@ -503,6 +503,46 @@ align 16
@@:
ret
align 16
.bpp1:
push ebx edx
mov ebx, esi
mov esi, [ebx + Image.Data]
mov ecx, [ebx + Image.Height]
.bpp1.pre:
mov edx, [ebx + Image.Width]
mov eax, 7
.bpp1.begin:
push ecx esi
xor cx, cx
bt [esi], eax
setc cl
mov esi, [ebx + Image.Palette]
jcxz @f
add esi, 4
@@:
mov ecx, 3
cld
rep movsb
pop esi ecx
dec edx
jz .bpp1.end_line
dec eax
jns .bpp1.begin
mov eax, 7
inc esi
jmp .bpp1.begin
.bpp1.end_line:
dec ecx
jz .bpp1.quit
inc esi
jmp .bpp1.pre
.bpp1.quit:
pop edx ebx
ret
endp
;;================================================================================================;;
@ -891,6 +931,61 @@ endl
add edi, [scanline_len]
dec ecx
jnz .next_line_horz24
jmp .exit
.bpp1_horz:
push eax edx
mov edi, [scanline_len]
mov edx, [ebx+Image.Width]
and edx, 0x07
neg dl
add dl, 8
and dl, 0x07 ; clear if cl=8
.bpp1_horz.begin:
push ebx ecx edx esi
mov eax, 7
add edi, esi
sub edi, 1
mov ebx, [ebx+Image.Width]
shr ebx, 1
.bpp1_horz.flip_line:
xor ecx, ecx
bt [esi], eax
setc cl
bt [edi], edx
jc .bpp1_horz.one
.bpp1_horz.zero:
btr [esi], eax
jmp @f
.bpp1_horz.one:
bts [esi], eax
@@:
jecxz .bpp1_horz.reset
.bpp1_horz.set:
bts [edi], edx
jmp @f
.bpp1_horz.reset:
btr [edi], edx
@@:
inc edx
and edx, 0x07
jnz @f
dec edi
@@:
dec eax
jns @f
mov eax, 7
inc esi
@@:
dec ebx
jnz .bpp1_horz.flip_line
pop esi edx ecx ebx
add esi, [scanline_len]
mov edi, [scanline_len]
dec ecx
jnz .bpp1_horz.begin
pop edx eax
.exit:
xor eax, eax
@ -990,6 +1085,8 @@ endl
add eax, [ebx + Image.Data]
mov [pixels_ptr], eax
cmp [ebx + Image.Type], Image.bpp1
jz .rotate_ccw1
cmp [ebx + Image.Type], Image.bpp8
jz .rotate_ccw8
cmp [ebx + Image.Type], Image.bpp24
@ -1182,6 +1279,83 @@ endl
pop ecx
jmp .next_column_ccw_low24
.rotate_ccw1:
push ecx edx
mov eax, [ebx+Image.Height]
add eax, 7
shr eax, 3
mul word[ebx+Image.Width]
shl eax, 16
shrd eax, edx, 16
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, 0x07
neg cl
add cl, 8
and cl, 0x07 ; clear if cl=8
mov esi, eax
mov edi, [ebx+Image.Data]
mov eax, 7
mov edx, [scanline_len_old]
dec edx
add edi, edx
.rotate_ccw1.begin:
bt [edi], ecx
jc .rotate_ccw1.one
.rotate_ccw1.zero:
btr [esi], eax
jmp @f
.rotate_ccw1.one:
bts [esi], eax
@@:
add edi, [scanline_len_old]
dec [scanline_pixels_new]
jz .rotate_ccw1.end_of_line
dec eax
jns .rotate_ccw1.begin
mov eax, 7
inc esi
jmp .rotate_ccw1.begin
.rotate_ccw1.end_of_line:
inc esi
mov eax, 7
mov edi, [ebx+Image.Height]
mov [scanline_pixels_new], edi
inc ecx
and cl, 0x07
jz @f
mov edi, [ebx+Image.Data]
add edi, edx
jmp .rotate_ccw1.begin
@@:
dec edx
js .rotate_ccw1.quit
mov edi, [ebx+Image.Data]
add edi, edx
jmp .rotate_ccw1.begin
.rotate_ccw1.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_cw_low:
mov eax, [ebx + Image.Height]
mov [scanline_pixels_new], eax
@ -1203,6 +1377,8 @@ endl
add eax, [ebx + Image.Data]
mov [pixels_ptr], eax
cmp [ebx + Image.Type], Image.bpp1
jz .rotate_cw1
cmp [ebx + Image.Type], Image.bpp8
jz .rotate_cw8
cmp [ebx + Image.Type], Image.bpp24
@ -1405,6 +1581,93 @@ endl
pop ecx
jmp .next_column_cw_low24
.rotate_cw1:
push ecx edx
mov eax, [ebx+Image.Height]
add eax, 7
shr eax, 3
mul word[ebx+Image.Width]
shl eax, 16
shrd eax, edx, 16
push eax ; save new data size
invoke mem.alloc, eax
or eax, eax
jz .error
push eax ; save pointer to new data
mov ecx, 7
mov edx, [ebx+Image.Width]
mov [pixels_ptr], edx ; we don't use pixels_ptr as it do other procedures, we save there [ebx+Image.Width]
mov esi, eax
mov edi, [ebx+Image.Data]
mov eax, [ebx+Image.Height]
dec eax
mul [scanline_len_old]
add edi, eax
mov eax, 7
mov edx, 0
.rotate_cw1.begin:
bt [edi], ecx
jc .rotate_cw1.one
.rotate_cw1.zero:
btr [esi], eax
jmp @f
.rotate_cw1.one:
bts [esi], eax
@@:
sub edi, [scanline_len_old]
dec [scanline_pixels_new]
jz .rotate_cw1.end_of_line
dec eax
jns .rotate_cw1.begin
mov eax, 7
inc esi
jmp .rotate_cw1.begin
.rotate_cw1.end_of_line:
dec [pixels_ptr]
jz .rotate_cw1.quit
inc esi
mov eax, [ebx+Image.Height]
mov [scanline_pixels_new], eax
mov eax, 7
dec ecx
js @f
mov edi, [ebx+Image.Height]
dec edi
imul edi, [scanline_len_old]
add edi, [ebx+Image.Data]
add edi, edx
jmp .rotate_cw1.begin
@@:
mov ecx, 7
inc edx
cmp edx, [scanline_len_old]
je .rotate_cw1.quit
mov edi, [ebx+Image.Height]
dec edi
imul edi, [scanline_len_old]
add edi, [ebx+Image.Data]
add edi, 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
.flip:
jmp .exit
@ -1613,6 +1876,8 @@ proc img._.resize_data _img, _width, _height ;//////////////////////////////////
; do not allow images which require too many memory
cmp eax, 4000000h
jae .error
cmp [ebx + Image.Type], Image.bpp1
jz .bpp1
cmp [ebx + Image.Type], Image.bpp8
jz .bpp8
cmp [ebx + Image.Type], Image.bpp24
@ -1625,6 +1890,34 @@ proc img._.resize_data _img, _width, _height ;//////////////////////////////////
jmp @f
.bpp8:
add eax, 256*4 ; for palette
jmp @f
.bpp1:
mov eax, [_width]
add eax, 7
shr eax, 3
mul word[_height]
shl eax, 16
mov ax, dx
ror eax, 16
push ebx
mov ebx, eax
mov eax, [_height]
add eax, 7
shr eax, 3
mul word[_width]
shl eax, 16
mov ax, dx
ror eax, 16
cmp eax, ebx
jge .bpp1.skip
mov eax, ebx
.bpp1.skip:
pop ebx
add eax, 2*4 ; for palette
@@:
mov esi, eax
invoke mem.realloc, [ebx + Image.Data], eax
@ -1637,10 +1930,16 @@ proc img._.resize_data _img, _width, _height ;//////////////////////////////////
push [_height]
pop [ebx + Image.Height]
cmp [ebx + Image.Type], Image.bpp8
jnz .ret
jnz @f
lea esi, [eax + esi - 256*4]
mov [ebx + Image.Palette], esi
jmp .ret
@@:
cmp [ebx + Image.Type], Image.bpp1
jnz .ret
lea esi, [eax + esi - 2*4]
mov [ebx + Image.Palette], esi
jmp .ret
.error:
xor eax, eax
@ -1658,19 +1957,25 @@ img._.get_scanline_len: ;///////////////////////////////////////////////////////
;;------------------------------------------------------------------------------------------------;;
;< --- TBD --- ;;
;;================================================================================================;;
cmp [ebx + Image.Type], Image.bpp1
jz .bpp1.1
cmp [ebx + Image.Type], Image.bpp8
jz .bpp8.1
cmp [ebx + Image.Type], Image.bpp24
jz .bpp24.1
add eax, eax
cmp [ebx + Image.Type], Image.bpp32
jnz @f
jnz .quit
add eax, eax
jmp @f
jmp .quit
.bpp24.1:
lea eax, [eax*3]
jmp .quit
.bpp1.1:
add eax, 7
shr eax, 3
.bpp8.1:
@@:
.quit:
ret
@ -1697,13 +2002,14 @@ img._.formats_table:
dd 0
align 4
type2bpp dd 8, 24, 32, 15, 16
type2bpp dd 8, 24, 32, 15, 16, 1
img._.do_rgb.handlers:
dd img._.do_rgb.bpp8
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
img.flip.layer.handlers_horz:
dd img.flip.layer.bpp8_horz
@ -1711,6 +2017,7 @@ img.flip.layer.handlers_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
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;

View File

@ -45,6 +45,7 @@ Image.bpp24 = 2
Image.bpp32 = 3
Image.bpp15 = 4
Image.bpp16 = 5
Image.bpp1 = 6
; bits in Image.Flags
Image.IsAnimated = 1

View File

@ -73,38 +73,26 @@ proc img.decode.pcx _data, _length, _options ;//////////////////////////////////
;< eax = 0 (error) or pointer to image ;;
;;================================================================================================;;
locals
; IMGwidth dd ?
; IMGheight dd ?
; IMGbpp dd ?
buf rb 1
nplanes rd 1
xsize rw 1
ysize rw 1
stxsize rw 1
stysize rw 1
bpl rw 1
total_bpl rd 1
total_bpl_tmp rd 1
line_begin rd 1
retvalue rd 1
retvalue rd 1 ; 0 (error) or pointer to image
endl
pusha
mov esi, [_data]
cmp [esi+pcx_header.bpp], 1
jz monochrome
cmp byte[esi+pcx_header.nplanes], 3
jnz indexed
_24bit:
xor eax, eax
mov al, byte[esi+pcx_header.nplanes]
movzx eax, byte[esi+pcx_header.nplanes]
mov [nplanes], eax
mul word[esi+pcx_header.bpl]
mov bx, word[esi+pcx_header.bpl]
mov [bpl], bx
mul bx
shl eax, 16
mov ax, dx
ror eax, 16
mov [total_bpl], eax
movzx eax, word[esi+pcx_header.xmax]
@ -117,6 +105,15 @@ endl
sub bx, word[esi+pcx_header.ymin]
mov [ysize], bx
cmp [esi+pcx_header.bpp], 1
jz .monochrome
cmp byte[esi+pcx_header.nplanes], 3
jnz .indexed
._24bit:
stdcall img.create, eax, ebx, Image.bpp24
mov [retvalue], eax
test eax, eax
@ -134,107 +131,107 @@ endl
mov esi, [_data]
add esi, 128
mov edi, [retvalue]
mov edi, [edi+Image.Data]
; mov edi, [retvalue]
mov edi, [eax+Image.Data]
add edi, 2
mov [line_begin], edi
mov ebx, [total_bpl]
.begin:
mov eax, [_data]
mov ax, word[eax+pcx_header.bpl]
.decode:
mov dl, byte[esi]
inc esi
mov [buf], dl
and dl, 0xC0
cmp dl, 0xC0
jne @f
mov dl, byte[buf]
and dl, 0x3F
mov dh, [esi]
inc esi
.write_sequence:
mov [edi], dh
._24bit.begin:
mov ax, word[bpl]
._24bit.decode:
call get_byte
._24bit.write_sequence:
mov [edi], dl
dec ax
dec ebx
add edi, [nplanes]
dec dl
test dl, dl
jnz .write_sequence
dec dh
jnz ._24bit.write_sequence
test ax, ax
jz .end_color_line
jmp .decode
@@:
mov dl, byte[buf]
mov [edi], dl
add edi, [nplanes]
dec ebx
dec ax
jz .end_color_line
jmp .decode
jz ._24bit.end_color_line
jmp ._24bit.decode
.end_color_line:
._24bit.end_color_line:
test ebx, ebx
jz .end_full_line
jz ._24bit.end_full_line
dec [line_begin]
mov edi, [line_begin]
jmp .begin
jmp ._24bit.begin
.end_full_line:
._24bit.end_full_line:
dec word[ysize]
jz .quit
mov ebx, [total_bpl]
add edi, 2
mov [line_begin], edi
jmp .begin
jmp ._24bit.begin
.quit:
popa
mov eax, [retvalue]
ret
indexed:
xor eax, eax
mov al, byte[esi+pcx_header.nplanes]
mov [nplanes], eax
mul word[esi+pcx_header.bpl]
mov [total_bpl], eax
movzx eax, word[esi+pcx_header.xmax]
inc ax
sub ax, word[esi+pcx_header.xmin]
mov [xsize], ax
movzx ebx, word[esi+pcx_header.ymax]
inc bx
sub bx, word[esi+pcx_header.ymin]
mov [ysize], bx
.indexed:
stdcall img.create, eax, ebx, Image.bpp8
mov [retvalue], eax
test eax, eax
jz .quit
movzx ebx, [xsize]
movzx ecx, [ysize]
mov edx, [eax+Image.Data]
rol ebx, 16
or ebx, ecx
xor ebx, [edx]
mov [eax+Image.Checksum], ebx
mov esi, [_data]
add esi, [_length]
sub esi, 768
mov edi, [eax+Image.Palette]
mov ecx, 256
mov cx, 256
@@:
mov ebx, [esi]
and ebx, 0x00ffffff
bswap ebx
shr ebx, 8
mov [edi], ebx
add edi, 4
add esi, 3
dec ecx
dec cx
jnz @b
mov esi, [_data]
add esi, 128
; mov edi, [retvalue]
mov edi, [eax+Image.Data]
.indexed.begin:
mov ax, word[bpl]
.indexed.decode:
call get_byte
.indexed.write_sequence:
mov [edi], dl
inc edi
dec ax
dec dh
jnz .indexed.write_sequence
test ax, ax
jz .indexed.end_line
jmp .indexed.decode
.indexed.end_line:
dec word[ysize]
jz .quit
jmp .indexed.begin
.monochrome:
stdcall img.create, eax, ebx, Image.bpp1
mov [retvalue], eax
test eax, eax
jz .quit
movzx ebx, [xsize]
movzx ecx, [ysize]
mov edx, [eax+Image.Data]
@ -244,175 +241,42 @@ endl
xor ebx, [edx]
mov [eax+Image.Checksum], ebx
mov esi, [_data]
add esi, 128
mov edi, [retvalue]
mov edi, [edi+Image.Data]
.begin:
mov eax, [_data]
mov ax, word[eax+pcx_header.bpl]
.decode:
mov dl, byte[esi]
inc esi
mov [buf], dl
and dl, 0xC0
cmp dl, 0xC0
jne @f
mov dl, [buf]
and dl, 0x3F
mov dh, [esi]
inc esi
.write_sequence:
mov [edi], dh
inc edi
dec ax
dec dl
jnz .write_sequence
test ax, ax
jz .end_line
jmp .decode
@@:
mov dl, byte[buf]
mov [edi], dl
inc edi
dec ax
jz .end_line
jmp .decode
.end_line:
dec word[ysize]
jz .quit
jmp .begin
.quit:
popa
mov eax, [retvalue]
ret
monochrome:
xor eax, eax
mov ax, word[esi+pcx_header.bpl]
mov [total_bpl], eax
movzx eax, word[esi+pcx_header.xmax]
inc ax
sub ax, word[esi+pcx_header.xmin]
mov [xsize], ax
movzx ebx, word[esi+pcx_header.ymax]
inc bx
sub bx, word[esi+pcx_header.ymin]
mov [ysize], bx
stdcall img.create, eax, ebx, Image.bpp8
mov [retvalue], eax
test eax, eax
jz .quit
mov edi, [eax+Image.Palette]
mov [edi], dword 0x00000000
mov [edi+4], dword 0x00ffffff
movzx ebx, [xsize]
movzx ecx, [ysize]
mov edx, [eax+Image.Data]
rol ebx, 16
or ebx, ecx
xor ebx, [edx]
mov [eax+Image.Checksum], ebx
mov esi, [_data]
add esi, 128
mov edi, [retvalue]
mov edi, [edi+Image.Data]
; mov edi, [retvalue]
mov edi, [eax+Image.Data]
.begin:
mov eax, [total_bpl]
mov [total_bpl_tmp], eax
.monochrome.begin:
mov ebx, [total_bpl]
mov ax, [xsize]
.decode:
mov dh, byte[esi]
inc esi
mov [buf], dh
and dh, 0xC0
cmp dh, 0xC0
je .cycle1
mov dh, 1
mov dl, [buf]
jmp .exit1
.cycle1:
mov dh, [buf]
and dh, 0x3F
mov dl, byte[esi]
inc esi
.exit1:
push eax
xor eax, eax
mov al, dh
sub [total_bpl_tmp], eax
pop eax
.write_sequence:
mov ecx, 7
.go:
bt edx, ecx
jnc @f
mov [edi], byte 0x01
jmp .later
@@:
mov [edi], byte 0x00
.later:
.monochrome.decode:
call get_byte
.monochrome.write_sequence:
mov [edi], dl
inc edi
dec ax
jnz .lol
@@:
cmp [total_bpl_tmp], 0
cmp ax, 8
jng .monochrome.is_last_byte_in_line
sub ax, 8
dec dh
jnz .monochrome.write_sequence
jmp .monochrome.decode
.monochrome.is_last_byte_in_line:
test ebx, ebx
jng @f
mov dh, byte[esi]
inc esi
mov [buf], dh
and dh, 0xC0
cmp dh, 0xC0
je .cycle2
mov dh, 1
mov dl, [buf]
jmp .exit2
.cycle2:
mov dh, [buf]
and dh, 0x3F
mov dl, byte[esi]
inc esi
.exit2:
push eax
xor eax, eax
mov al, dh
sub [total_bpl_tmp], eax
pop eax
jmp @b
call get_byte
jmp .monochrome.is_last_byte_in_line
@@:
dec word[ysize]
jnz .begin
jnz .monochrome.begin
jmp .quit
.lol:
dec ecx
cmp ecx, -1
jne .go
dec dh
jnz .write_sequence
jmp .decode
.quit:
popa
@ -445,7 +309,25 @@ endp
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
proc get_byte
mov dh, byte[esi]
inc esi
cmp dh, 0xC0
jnb .cycle1
mov dl, dh
mov dh, 1
jmp .exit1
.cycle1:
and dh, 0x3F
mov dl, byte[esi]
inc esi
.exit1:
movzx ecx, dh
sub ebx, ecx
ret
endp
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;