forked from KolibriOS/kolibrios
libimg: tiff: Don't rely on EOI tag at the end of the strip.
Reference implementation (libtiff) has a workaround: precalculate data size of the strip and don't rely on EOI tag of specific bit length. This allow to read some invalid TIFF LZW images by my old scanner. git-svn-id: svn://kolibrios.org@7735 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
de8ecf4c59
commit
a0a18277da
@ -139,7 +139,6 @@ locals
|
|||||||
img_data dd ? ; raw bytes
|
img_data dd ? ; raw bytes
|
||||||
img dd ? ; Image pointer
|
img dd ? ; Image pointer
|
||||||
endl
|
endl
|
||||||
DEBUGF 2, 'img.from_file: %s\n', [_filename]
|
|
||||||
push ebx
|
push ebx
|
||||||
mov [img], 0
|
mov [img], 0
|
||||||
invoke file.open, [_filename], O_READ
|
invoke file.open, [_filename], O_READ
|
||||||
@ -2744,7 +2743,7 @@ img._.get_scanline_len: ;///////////////////////////////////////////////////////
|
|||||||
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
||||||
;;================================================================================================;;
|
;;================================================================================================;;
|
||||||
|
|
||||||
include_debug_strings
|
;include_debug_strings
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4
|
type2bpp dd 8, 24, 32, 15, 16, 1, 9, 2, 4
|
||||||
|
@ -78,7 +78,7 @@ locals
|
|||||||
retvalue rd 1 ; 0 (error) or pointer to image
|
retvalue rd 1 ; 0 (error) or pointer to image
|
||||||
endl
|
endl
|
||||||
|
|
||||||
push ebx edx esi edi
|
push ebx esi edi
|
||||||
|
|
||||||
mov esi, [_data]
|
mov esi, [_data]
|
||||||
lodsw
|
lodsw
|
||||||
@ -89,17 +89,22 @@ endl
|
|||||||
lodsw_
|
lodsw_
|
||||||
lodsd_
|
lodsd_
|
||||||
@@:
|
@@:
|
||||||
|
; push eax
|
||||||
stdcall tiff._.parse_IFD, [_data], eax, [_endianness]
|
stdcall tiff._.parse_IFD, [_data], eax, [_endianness]
|
||||||
mov ebx, eax
|
; pop esi
|
||||||
mov [retvalue], eax
|
; mov ebx, eax
|
||||||
lodsd_
|
; mov [retvalue], eax
|
||||||
test eax, eax
|
; xor eax, eax
|
||||||
|
; lodsw_
|
||||||
|
; shl eax, 2
|
||||||
|
; lea eax, [eax*3]
|
||||||
|
; add esi, eax
|
||||||
|
; lodsd_
|
||||||
|
; test eax, eax
|
||||||
; jnz @b
|
; jnz @b
|
||||||
|
; .quit:
|
||||||
|
; mov eax, [retvalue]
|
||||||
.quit:
|
pop edi esi ebx
|
||||||
mov eax, [retvalue]
|
|
||||||
pop edi esi edx ebx
|
|
||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
@ -362,6 +367,7 @@ endl
|
|||||||
add edi, 2
|
add edi, 2
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz @b
|
jnz @b
|
||||||
|
jmp .post.predictor
|
||||||
|
|
||||||
.post.rgba_bgra:
|
.post.rgba_bgra:
|
||||||
cmp [ebx + tiff_extra.samples_per_pixel], 4
|
cmp [ebx + tiff_extra.samples_per_pixel], 4
|
||||||
@ -379,6 +385,7 @@ endl
|
|||||||
add esi, 1
|
add esi, 1
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz @b
|
jnz @b
|
||||||
|
jmp .post.predictor
|
||||||
|
|
||||||
.post.bpp8a_to_bpp8g:
|
.post.bpp8a_to_bpp8g:
|
||||||
mov eax, [retvalue]
|
mov eax, [retvalue]
|
||||||
@ -840,38 +847,29 @@ endl
|
|||||||
ret
|
ret
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
struct lzw_ctx
|
||||||
|
bits_left dd ? ; in current byte (pointed to by [esi])
|
||||||
|
cur_shift dd ? ; 9 -- 12
|
||||||
|
shift_counter dd ? ; how many shifts of current length remained
|
||||||
|
table dd ?
|
||||||
|
last_table_entry dd ? ; zero based
|
||||||
|
next_table_entry dd ? ; where to place new entry
|
||||||
|
strip_len dd ?
|
||||||
|
old_code dd ?
|
||||||
|
ends
|
||||||
|
|
||||||
proc tiff._.decompress.lzw _image
|
proc tiff._.lzw_get_code
|
||||||
locals
|
mov edx, [ebx+lzw_ctx.cur_shift]
|
||||||
cur_shift rd 1 ; 9 -- 12
|
|
||||||
shift_counter rd 1 ; how many shifts of current length remained
|
|
||||||
bits_left rd 1 ; in current byte ( pointed to by [esi] )
|
|
||||||
table rd 1
|
|
||||||
table_size rd 1 ; the number of entries
|
|
||||||
old_code rd 1
|
|
||||||
next_table_entry rd 1 ; where to place new entry
|
|
||||||
endl
|
|
||||||
push ebx ecx edx esi
|
|
||||||
|
|
||||||
mov [table], 0
|
|
||||||
mov [bits_left], 8
|
|
||||||
mov [cur_shift], 9
|
|
||||||
|
|
||||||
.begin:
|
|
||||||
|
|
||||||
; .getnextcode:
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
mov edx, [cur_shift]
|
|
||||||
|
|
||||||
lodsb
|
lodsb
|
||||||
mov ecx, [bits_left]
|
mov ecx, [ebx+lzw_ctx.bits_left]
|
||||||
mov ch, cl
|
mov ch, cl
|
||||||
neg cl
|
neg cl
|
||||||
add cl, 8
|
add cl, 8
|
||||||
shl al, cl
|
shl al, cl
|
||||||
mov cl, ch
|
mov cl, ch
|
||||||
shl eax, cl
|
shl eax, cl
|
||||||
sub edx, [bits_left]
|
sub edx, [ebx+lzw_ctx.bits_left]
|
||||||
; second_byte
|
; second_byte
|
||||||
cmp edx, 8
|
cmp edx, 8
|
||||||
je .enough_zero
|
je .enough_zero
|
||||||
@ -879,9 +877,9 @@ endl
|
|||||||
sub edx, 8
|
sub edx, 8
|
||||||
lodsb
|
lodsb
|
||||||
shl eax, 8
|
shl eax, 8
|
||||||
jmp .third_byte
|
jmp .enough_nonzero
|
||||||
.enough_zero:
|
.enough_zero:
|
||||||
mov [bits_left], 8
|
mov [ebx+lzw_ctx.bits_left], 8
|
||||||
lodsb
|
lodsb
|
||||||
jmp .code_done
|
jmp .code_done
|
||||||
.enough_nonzero:
|
.enough_nonzero:
|
||||||
@ -889,183 +887,130 @@ endl
|
|||||||
neg edx
|
neg edx
|
||||||
add edx, 8
|
add edx, 8
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
mov [bits_left], edx
|
mov [ebx+lzw_ctx.bits_left], edx
|
||||||
shr eax, cl
|
|
||||||
jmp .code_done
|
|
||||||
.third_byte:
|
|
||||||
mov al, byte[esi]
|
|
||||||
neg edx
|
|
||||||
add edx, 8
|
|
||||||
mov ecx, edx
|
|
||||||
mov [bits_left], edx
|
|
||||||
shr eax, cl
|
shr eax, cl
|
||||||
.code_done:
|
.code_done:
|
||||||
|
dec [ebx+lzw_ctx.shift_counter]
|
||||||
|
jnz @f
|
||||||
|
mov ecx, [ebx+lzw_ctx.cur_shift]
|
||||||
|
add [ebx+lzw_ctx.cur_shift], 1
|
||||||
|
mov edx, 1
|
||||||
|
shl edx, cl
|
||||||
|
mov [ebx+lzw_ctx.shift_counter], edx
|
||||||
|
@@:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc tiff._.add_string_to_table uses esi
|
||||||
|
mov esi, [ebx+lzw_ctx.table]
|
||||||
|
lea esi, [esi + eax*8 + 256]
|
||||||
|
mov ecx, dword[esi+4]
|
||||||
|
|
||||||
mov ebx, eax
|
mov edx, [ebx+lzw_ctx.next_table_entry]
|
||||||
cmp ebx, 0x101 ; end of information
|
mov [edx], edi
|
||||||
je .quit
|
lea eax, [ecx + 1]
|
||||||
cmp ebx, 0x100 ; clear code
|
mov [edx + 4], eax
|
||||||
jne .no_clear_code
|
add [ebx+lzw_ctx.next_table_entry], 8
|
||||||
|
add [ebx+lzw_ctx.last_table_entry], 1
|
||||||
|
|
||||||
cmp [table], 0
|
mov esi, [esi]
|
||||||
|
cmp ecx, [ebx+lzw_ctx.strip_len]
|
||||||
|
cmovg ecx, [ebx+lzw_ctx.strip_len]
|
||||||
|
sub [ebx+lzw_ctx.strip_len], ecx
|
||||||
|
rep movsb
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc tiff._.init_code_table
|
||||||
|
cmp [ebx+lzw_ctx.table], 0
|
||||||
jne @f
|
jne @f
|
||||||
invoke mem.alloc, 256 + 63488 ; 256 + (2^8 + 2^9 + 2^10 + 2^11 + 2^12)*(4+4)
|
invoke mem.alloc, 256 + 63488 ; 256 + (2^8 + 2^9 + 2^10 + 2^11 + 2^12)*(4+4)
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .quit
|
jz .quit
|
||||||
mov [table], eax
|
mov [ebx+lzw_ctx.table], eax
|
||||||
@@:
|
@@:
|
||||||
mov eax, [table]
|
mov eax, [ebx+lzw_ctx.table]
|
||||||
mov [next_table_entry], eax
|
mov [ebx+lzw_ctx.next_table_entry], eax
|
||||||
add [next_table_entry], 256 + (256*8) + 2*8
|
add [ebx+lzw_ctx.next_table_entry], 256 + (256*8) + 2*8
|
||||||
mov [cur_shift], 9
|
mov [ebx+lzw_ctx.cur_shift], 9
|
||||||
mov [shift_counter], 256-3 ; clear code, end of information, why -3?
|
mov [ebx+lzw_ctx.shift_counter], 256-2 ; clear code, end of information
|
||||||
mov [table_size], 257
|
mov [ebx+lzw_ctx.last_table_entry], 257 ; 0--255, clear, eoi
|
||||||
|
|
||||||
push edi
|
push edi
|
||||||
mov ecx, 256
|
mov ecx, 256
|
||||||
mov edi, [table]
|
mov edi, [ebx+lzw_ctx.table]
|
||||||
mov ebx, edi
|
mov edx, edi
|
||||||
add edi, 256
|
add edi, 256
|
||||||
mov eax, 0
|
mov eax, 0
|
||||||
@@:
|
@@:
|
||||||
mov byte[ebx], al
|
mov byte[edx], al
|
||||||
mov [edi], ebx
|
mov [edi], edx
|
||||||
add edi, 4
|
add edi, 4
|
||||||
add ebx, 1
|
add edx, 1
|
||||||
add eax, 1
|
add eax, 1
|
||||||
mov [edi], dword 1
|
mov [edi], dword 1
|
||||||
add edi, 4
|
add edi, 4
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz @b
|
jnz @b
|
||||||
pop edi
|
pop edi
|
||||||
; .getnextcode:
|
.quit:
|
||||||
xor eax, eax
|
ret
|
||||||
mov edx, [cur_shift]
|
endp
|
||||||
|
|
||||||
lodsb
|
proc tiff._.decompress.lzw _image
|
||||||
mov ecx, [bits_left]
|
locals
|
||||||
mov ch, cl
|
ctx lzw_ctx
|
||||||
neg cl
|
endl
|
||||||
add cl, 8
|
push ebx ecx edx esi
|
||||||
shl al, cl
|
mov ecx, [ebx+tiff_extra.rows_per_strip]
|
||||||
mov cl, ch
|
mov ebx, [_image]
|
||||||
shl eax, cl
|
mov eax, [ebx+Image.Width]
|
||||||
sub edx, [bits_left]
|
call img._.get_scanline_len
|
||||||
; second_byte
|
imul eax, ecx
|
||||||
cmp edx, 8
|
|
||||||
je .enough_zero2
|
|
||||||
jb .enough_nonzero2
|
|
||||||
sub edx, 8
|
|
||||||
lodsb
|
|
||||||
shl eax, 8
|
|
||||||
jmp .third_byte2
|
|
||||||
.enough_zero2:
|
|
||||||
mov [bits_left], 8
|
|
||||||
lodsb
|
|
||||||
jmp .code_done2
|
|
||||||
.enough_nonzero2:
|
|
||||||
mov al, byte[esi]
|
|
||||||
neg edx
|
|
||||||
add edx, 8
|
|
||||||
mov ecx, edx
|
|
||||||
mov [bits_left], edx
|
|
||||||
shr eax, cl
|
|
||||||
jmp .code_done2
|
|
||||||
.third_byte2:
|
|
||||||
mov al, byte[esi]
|
|
||||||
neg edx
|
|
||||||
add edx, 8
|
|
||||||
mov ecx, edx
|
|
||||||
mov [bits_left], edx
|
|
||||||
shr eax, cl
|
|
||||||
.code_done2:
|
|
||||||
|
|
||||||
|
lea ebx, [ctx]
|
||||||
|
mov [ctx.strip_len], eax
|
||||||
|
mov [ctx.table], 0
|
||||||
|
mov [ctx.bits_left], 8
|
||||||
|
mov [ctx.cur_shift], 9
|
||||||
|
|
||||||
mov [old_code], eax
|
.begin:
|
||||||
|
cmp [ctx.strip_len], 0
|
||||||
|
jle .quit
|
||||||
|
stdcall tiff._.lzw_get_code
|
||||||
cmp eax, 0x101 ; end of information
|
cmp eax, 0x101 ; end of information
|
||||||
je .quit
|
je .quit
|
||||||
|
cmp eax, 0x100 ; clear code
|
||||||
|
jne .no_clear_code
|
||||||
|
call tiff._.init_code_table
|
||||||
|
|
||||||
push esi
|
; getnextcode
|
||||||
mov esi, [table]
|
call tiff._.lzw_get_code
|
||||||
lea esi, [esi + eax*8 + 256]
|
mov [ctx.old_code], eax
|
||||||
mov ecx, dword[esi+4]
|
cmp eax, 0x101 ; end of information
|
||||||
|
je .quit
|
||||||
mov edx, [next_table_entry]
|
call tiff._.add_string_to_table
|
||||||
mov [edx], edi
|
|
||||||
lea eax, [ecx + 1]
|
|
||||||
mov [edx + 4], eax
|
|
||||||
add [next_table_entry], 8
|
|
||||||
|
|
||||||
mov esi, [esi]
|
|
||||||
rep movsb
|
|
||||||
pop esi
|
|
||||||
jmp .begin
|
jmp .begin
|
||||||
.no_clear_code:
|
.no_clear_code:
|
||||||
cmp eax, [table_size]
|
cmp eax, [ctx.last_table_entry]
|
||||||
ja .not_in_table
|
ja .not_in_table
|
||||||
mov [old_code], eax
|
mov [ctx.old_code], eax
|
||||||
push esi
|
call tiff._.add_string_to_table
|
||||||
mov esi, [table]
|
|
||||||
lea esi, [esi + eax*8 + 256]
|
|
||||||
mov ecx, dword[esi + 4]
|
|
||||||
|
|
||||||
mov edx, [next_table_entry]
|
|
||||||
mov [edx], edi
|
|
||||||
lea eax, [ecx + 1]
|
|
||||||
mov [edx + 4], eax
|
|
||||||
add [next_table_entry], 8
|
|
||||||
add [table_size], 1
|
|
||||||
|
|
||||||
mov esi, [esi]
|
|
||||||
rep movsb
|
|
||||||
pop esi
|
|
||||||
|
|
||||||
dec [shift_counter]
|
|
||||||
jnz @f
|
|
||||||
mov ecx, [cur_shift]
|
|
||||||
add [cur_shift], 1
|
|
||||||
mov edx, 1
|
|
||||||
shl edx, cl
|
|
||||||
mov [shift_counter], edx
|
|
||||||
@@:
|
|
||||||
jmp .begin
|
jmp .begin
|
||||||
|
|
||||||
.not_in_table:
|
.not_in_table:
|
||||||
xchg eax, [old_code]
|
xchg eax, [ctx.old_code]
|
||||||
push esi
|
call tiff._.add_string_to_table
|
||||||
mov esi, [table]
|
cmp [ctx.strip_len], 0
|
||||||
lea esi, [esi + eax*8 + 256]
|
jle @f
|
||||||
mov ecx, dword[esi+4]
|
dec [ctx.strip_len]
|
||||||
|
|
||||||
mov edx, [next_table_entry]
|
|
||||||
mov [edx], edi
|
|
||||||
lea eax, [ecx + 2]
|
|
||||||
mov [edx + 4], eax
|
|
||||||
add [next_table_entry], 8
|
|
||||||
add [table_size], 1
|
|
||||||
|
|
||||||
mov esi, [esi]
|
|
||||||
mov al, [esi]
|
|
||||||
rep movsb
|
|
||||||
mov byte[edi], al
|
mov byte[edi], al
|
||||||
add edi, 1
|
add edi, 1
|
||||||
pop esi
|
|
||||||
|
|
||||||
dec [shift_counter]
|
|
||||||
jnz @f
|
|
||||||
mov ecx, [cur_shift]
|
|
||||||
add [cur_shift], 1
|
|
||||||
mov edx, 1
|
|
||||||
shl edx, cl
|
|
||||||
mov [shift_counter], edx
|
|
||||||
@@:
|
@@:
|
||||||
jmp .begin
|
jmp .begin
|
||||||
|
|
||||||
.quit:
|
.quit:
|
||||||
cmp [table], 0
|
cmp [ctx.table], 0
|
||||||
je @f
|
je @f
|
||||||
invoke mem.free, [table]
|
invoke mem.free, [ctx.table]
|
||||||
@@:
|
@@:
|
||||||
pop esi edx ecx ebx
|
pop esi edx ecx ebx
|
||||||
ret
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user