forked from KolibriOS/kolibrios
libimg: Improve support of transparent PNG images.
* Support grayscale images with alpha channel. * Support rgb images with transparent color. * Process 'tRNS' chunk (simple transparency). Transparent png images were already supported for color type 6, which is RGBA. Now indexed images (color type 3) can also have transparency via 'tRNS' chunk data. git-svn-id: svn://kolibrios.org@8449 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
045e0dbdd2
commit
459cb3ec5b
@ -633,6 +633,22 @@ proc img._.convert.bpp8a_to_bpp24 _src, _dst
|
|||||||
endp
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
proc img._.convert.bpp8a_to_bpp32 _src, _dst
|
||||||
|
mov ecx, [ebx + Image.Width]
|
||||||
|
imul ecx, [ebx + Image.Height]
|
||||||
|
@@:
|
||||||
|
lodsw
|
||||||
|
shl eax, 8
|
||||||
|
mov al, ah
|
||||||
|
shl eax, 8
|
||||||
|
mov al, ah
|
||||||
|
stosd
|
||||||
|
dec ecx
|
||||||
|
jnz @b
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
img.convert.bpp8i.table:
|
img.convert.bpp8i.table:
|
||||||
dd Image.bpp24, img._.convert.bpp8i_to_bpp24
|
dd Image.bpp24, img._.convert.bpp8i_to_bpp24
|
||||||
dd Image.bpp32, img._.convert.bpp8i_to_bpp32
|
dd Image.bpp32, img._.convert.bpp8i_to_bpp32
|
||||||
@ -665,6 +681,7 @@ img.convert.bpp4i.table:
|
|||||||
dd 0
|
dd 0
|
||||||
img.convert.bpp8a.table:
|
img.convert.bpp8a.table:
|
||||||
dd Image.bpp24, img._.convert.bpp8a_to_bpp24
|
dd Image.bpp24, img._.convert.bpp8a_to_bpp24
|
||||||
|
dd Image.bpp32, img._.convert.bpp8a_to_bpp32
|
||||||
dd 0
|
dd 0
|
||||||
|
|
||||||
img.convert.table:
|
img.convert.table:
|
||||||
|
@ -56,12 +56,13 @@ img.decode.png:
|
|||||||
xor eax, eax ; .image = 0
|
xor eax, eax ; .image = 0
|
||||||
pushad
|
pushad
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
.localsize = 29*4
|
.localsize = 30*4
|
||||||
virtual at ebp - .localsize
|
virtual at ebp - .localsize
|
||||||
.width dd ?
|
.width dd ?
|
||||||
.height dd ?
|
.height dd ?
|
||||||
.bit_depth dd ?
|
.bit_depth dd ?
|
||||||
.color_type dd ?
|
.color_type dd ?
|
||||||
|
.transparent_color dd ?
|
||||||
.bytes_per_pixel dd ?
|
.bytes_per_pixel dd ?
|
||||||
.scanline_len dd ?
|
.scanline_len dd ?
|
||||||
.bits_per_pixel dd ?
|
.bits_per_pixel dd ?
|
||||||
@ -158,6 +159,8 @@ end virtual
|
|||||||
jz .iend
|
jz .iend
|
||||||
cmp eax, 'PLTE'
|
cmp eax, 'PLTE'
|
||||||
jz .palette
|
jz .palette
|
||||||
|
cmp eax, 'tRNS'
|
||||||
|
jz .transparency
|
||||||
; unrecognized chunk, ignore
|
; unrecognized chunk, ignore
|
||||||
lea esi, [esi+ecx+4]
|
lea esi, [esi+ecx+4]
|
||||||
pop ecx
|
pop ecx
|
||||||
@ -233,14 +236,17 @@ end virtual
|
|||||||
add eax, 7
|
add eax, 7
|
||||||
shr eax, 3
|
shr eax, 3
|
||||||
mov [.bytes_per_pixel], eax
|
mov [.bytes_per_pixel], eax
|
||||||
|
mov [.transparent_color], 0
|
||||||
; allocate image
|
; allocate image
|
||||||
push Image.bpp24
|
movi eax, Image.bpp32
|
||||||
pop eax
|
|
||||||
cmp [.color_type], 2
|
cmp [.color_type], 2
|
||||||
jz @f
|
jz @f
|
||||||
mov al, Image.bpp32
|
mov al, Image.bpp32
|
||||||
cmp [.color_type], 6
|
cmp [.color_type], 6
|
||||||
jz @f
|
jz @f
|
||||||
|
mov al, Image.bpp8a
|
||||||
|
cmp [.color_type], 4
|
||||||
|
jz @f
|
||||||
mov al, Image.bpp8i
|
mov al, Image.bpp8i
|
||||||
@@:
|
@@:
|
||||||
stdcall img.create, [.width], [.height], eax
|
stdcall img.create, [.width], [.height], eax
|
||||||
@ -288,11 +294,73 @@ end virtual
|
|||||||
lodsd
|
lodsd
|
||||||
dec esi
|
dec esi
|
||||||
bswap eax
|
bswap eax
|
||||||
shr eax, 8
|
mov al, 0xff
|
||||||
|
ror eax, 8
|
||||||
stosd
|
stosd
|
||||||
jmp .next_chunk
|
jmp .next_chunk
|
||||||
|
; convert 16 bit sample to 8 bit sample
|
||||||
|
macro convert_16_to_8
|
||||||
|
{
|
||||||
|
local .l1,.l2
|
||||||
|
xor ah, 0x80
|
||||||
|
js .l1
|
||||||
|
cmp al, ah
|
||||||
|
adc al, 0
|
||||||
|
jmp .l2
|
||||||
|
.l1:
|
||||||
|
cmp ah, al
|
||||||
|
sbb al, 0
|
||||||
|
.l2:
|
||||||
|
}
|
||||||
|
; tRNS chunk
|
||||||
|
.transparency:
|
||||||
|
mov eax, [.image]
|
||||||
|
test eax, eax
|
||||||
|
jz .invalid_chunk
|
||||||
|
cmp [.color_type], 2 ; rgb
|
||||||
|
jz .transparency_rgb
|
||||||
|
cmp [.color_type], 3 ; indexed
|
||||||
|
jz .transparency_indexed
|
||||||
|
add esi, ecx
|
||||||
|
jmp .next_chunk
|
||||||
|
.transparency_rgb:
|
||||||
|
cmp [.bit_depth], 16
|
||||||
|
jz .transparency_rgb16
|
||||||
|
lodsw
|
||||||
|
shl eax, 8
|
||||||
|
lodsw
|
||||||
|
shl eax, 8
|
||||||
|
lodsw
|
||||||
|
mov al, 0xff
|
||||||
|
ror eax, 8
|
||||||
|
mov [.transparent_color], eax
|
||||||
|
jmp .next_chunk
|
||||||
|
.transparency_rgb16:
|
||||||
|
lodsw
|
||||||
|
convert_16_to_8
|
||||||
|
shl ax, 8
|
||||||
|
shl eax, 8
|
||||||
|
lodsw
|
||||||
|
convert_16_to_8
|
||||||
|
shl ax, 8
|
||||||
|
shl eax, 8
|
||||||
|
lodsw
|
||||||
|
convert_16_to_8
|
||||||
|
shl ax, 8
|
||||||
|
mov al, 0xff
|
||||||
|
ror eax, 8
|
||||||
|
mov [.transparent_color], eax
|
||||||
|
jmp .next_chunk
|
||||||
|
.transparency_indexed:
|
||||||
|
mov edi, [eax + Image.Palette]
|
||||||
|
@@:
|
||||||
|
add edi, 3
|
||||||
|
movsb
|
||||||
|
loop @b
|
||||||
|
jmp .next_chunk
|
||||||
.idat:
|
.idat:
|
||||||
jecxz .next_chunk
|
test ecx, ecx
|
||||||
|
jz .next_chunk
|
||||||
cmp [.idat_read], 0
|
cmp [.idat_read], 0
|
||||||
jnz @f
|
jnz @f
|
||||||
lodsb
|
lodsb
|
||||||
@ -654,22 +722,6 @@ macro init_block
|
|||||||
init_block
|
init_block
|
||||||
lea eax, [edi+eax*4]
|
lea eax, [edi+eax*4]
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
; convert 16 bit sample to 8 bit sample
|
|
||||||
macro convert_16_to_8
|
|
||||||
{
|
|
||||||
local .l1,.l2
|
|
||||||
xor ah, 0x80
|
|
||||||
js .l1
|
|
||||||
cmp al, ah
|
|
||||||
adc al, 0
|
|
||||||
jmp .l2
|
|
||||||
.l1:
|
|
||||||
cmp ah, al
|
|
||||||
sbb al, 0
|
|
||||||
.l2:
|
|
||||||
}
|
|
||||||
|
|
||||||
.rgb_alpha2_16bit.innloop1:
|
.rgb_alpha2_16bit.innloop1:
|
||||||
push edi
|
push edi
|
||||||
mov ecx, ebx
|
mov ecx, ebx
|
||||||
@ -872,20 +924,21 @@ local .l1
|
|||||||
mov [.i], ecx
|
mov [.i], ecx
|
||||||
.rgb2.extloop:
|
.rgb2.extloop:
|
||||||
init_block
|
init_block
|
||||||
lea eax, [eax*3]
|
lea eax, [edi+eax*4]
|
||||||
add eax, edi
|
|
||||||
push eax
|
push eax
|
||||||
.rgb2.innloop1:
|
.rgb2.innloop1:
|
||||||
push edi
|
push edi
|
||||||
mov ecx, ebx
|
mov ecx, ebx
|
||||||
.rgb2.innloop2:
|
.rgb2.innloop2:
|
||||||
mov al, [esi+2]
|
mov eax, [esi]
|
||||||
mov [edi], al
|
bswap eax
|
||||||
mov al, [esi+1]
|
mov al, 0xff
|
||||||
mov [edi+1], al
|
ror eax, 8
|
||||||
mov al, [esi]
|
cmp eax, [.transparent_color]
|
||||||
mov [edi+2], al
|
jnz @f
|
||||||
add edi, 3
|
and eax, 0x00ffffff
|
||||||
|
@@:
|
||||||
|
stosd
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz .rgb2.innloop2
|
jnz .rgb2.innloop2
|
||||||
pop edi
|
pop edi
|
||||||
@ -947,7 +1000,6 @@ local .l1
|
|||||||
ja .rgb2_16bit
|
ja .rgb2_16bit
|
||||||
jmp .convert_done
|
jmp .convert_done
|
||||||
.grayscale_alpha2:
|
.grayscale_alpha2:
|
||||||
call .create_grayscale_palette
|
|
||||||
cmp [.bit_depth], 16
|
cmp [.bit_depth], 16
|
||||||
jz .grayscale_alpha2_16bit
|
jz .grayscale_alpha2_16bit
|
||||||
.grayscale_alpha2.next:
|
.grayscale_alpha2.next:
|
||||||
@ -961,11 +1013,29 @@ local .l1
|
|||||||
mov [.i], ecx
|
mov [.i], ecx
|
||||||
.grayscale_alpha2.extloop:
|
.grayscale_alpha2.extloop:
|
||||||
init_block
|
init_block
|
||||||
|
add eax, eax
|
||||||
add eax, edi
|
add eax, edi
|
||||||
push eax
|
push eax
|
||||||
mov al, [esi]
|
lodsw
|
||||||
add esi, 2
|
macro block_word_innerloop extloop
|
||||||
block_byte_innerloop .grayscale_alpha2.extloop
|
{
|
||||||
|
local .l1
|
||||||
|
.l1:
|
||||||
|
mov ecx, ebx
|
||||||
|
rep stosw
|
||||||
|
sub edi, ebx
|
||||||
|
add edi, [.row_distance]
|
||||||
|
dec edx
|
||||||
|
jnz .l1
|
||||||
|
pop edi ebx
|
||||||
|
mov eax, [.col_increment]
|
||||||
|
sub [.i], eax
|
||||||
|
ja extloop
|
||||||
|
add edi, [.col_distance]
|
||||||
|
mov eax, [.row_increment]
|
||||||
|
sub [.j], eax
|
||||||
|
}
|
||||||
|
block_word_innerloop .grayscale_alpha2.extloop
|
||||||
ja .grayscale_alpha2.next
|
ja .grayscale_alpha2.next
|
||||||
jmp .convert_done
|
jmp .convert_done
|
||||||
.grayscale_alpha2_16bit:
|
.grayscale_alpha2_16bit:
|
||||||
@ -979,12 +1049,17 @@ local .l1
|
|||||||
mov [.i], ecx
|
mov [.i], ecx
|
||||||
.grayscale_alpha2_16bit.extloop:
|
.grayscale_alpha2_16bit.extloop:
|
||||||
init_block
|
init_block
|
||||||
|
add eax, eax
|
||||||
add eax, edi
|
add eax, edi
|
||||||
push eax
|
push eax
|
||||||
mov ax, [esi]
|
lodsw
|
||||||
add esi, 4
|
|
||||||
convert_16_to_8
|
convert_16_to_8
|
||||||
block_byte_innerloop .grayscale_alpha2_16bit.extloop
|
mov ecx, eax
|
||||||
|
lodsw
|
||||||
|
convert_16_to_8
|
||||||
|
mov ah, cl
|
||||||
|
xchg al, ah
|
||||||
|
block_word_innerloop .grayscale_alpha2_16bit.extloop
|
||||||
ja .grayscale_alpha2_16bit
|
ja .grayscale_alpha2_16bit
|
||||||
.convert_done:
|
.convert_done:
|
||||||
; next interlace pass
|
; next interlace pass
|
||||||
@ -1070,7 +1145,7 @@ local .l1
|
|||||||
jz .graypal_common
|
jz .graypal_common
|
||||||
mov edx, 0xFFFFFF
|
mov edx, 0xFFFFFF
|
||||||
.graypal_common:
|
.graypal_common:
|
||||||
xor eax, eax
|
mov eax, 0xff000000
|
||||||
@@:
|
@@:
|
||||||
stosd
|
stosd
|
||||||
add eax, edx
|
add eax, edx
|
||||||
|
Loading…
Reference in New Issue
Block a user