897 lines
14 KiB
PHP
897 lines
14 KiB
PHP
|
; @RCHER parser and filter routines
|
||
|
; Written in pure assembler by Ivushkin Andrey aka Willow
|
||
|
|
||
|
fhs_local equ 0x04034b50
|
||
|
fhs_central equ 0x02014b50
|
||
|
fhs_end equ 0x06054b50
|
||
|
fhs_enc equ 0x08074b50
|
||
|
|
||
|
SkipASCIIZ:
|
||
|
xor eax,eax
|
||
|
mov ecx,255
|
||
|
mov edi,esi
|
||
|
repne scasb
|
||
|
mov esi,edi
|
||
|
ret
|
||
|
|
||
|
PrintFilename:
|
||
|
pusha
|
||
|
mov esi,edx
|
||
|
mov edi,os_work
|
||
|
mov edx,edi
|
||
|
rep movsb
|
||
|
mov dword[edi],0x00a0d
|
||
|
call DebugPrint
|
||
|
; mcall 10
|
||
|
; mcall 2
|
||
|
popa
|
||
|
ret
|
||
|
|
||
|
|
||
|
; Parse routines:
|
||
|
; out: edx= 0 if all ok, 1 - central dir, 2-EOD
|
||
|
; 50 - encrypted
|
||
|
; 51 - not deflated
|
||
|
; 52 - invalid format
|
||
|
; 53 - dir skipped
|
||
|
; 1 - encrypted
|
||
|
|
||
|
; ****************************************************
|
||
|
ZipParse:
|
||
|
|
||
|
call ResetFile
|
||
|
.nxt:
|
||
|
call ZipCrawl
|
||
|
|
||
|
cmp edx,3
|
||
|
je .ex
|
||
|
cmp edx,1
|
||
|
je .skipinc
|
||
|
if IGNORE_DIRS eq 1
|
||
|
cmp edx,53
|
||
|
jne .skipinc
|
||
|
end if
|
||
|
inc [file_count]
|
||
|
.skipinc:
|
||
|
cmp edx,52
|
||
|
je .er1
|
||
|
cmp edx,50
|
||
|
jne .seek
|
||
|
.er1:
|
||
|
Msg edx
|
||
|
ret
|
||
|
.seek:
|
||
|
add eax,ecx
|
||
|
mov ebx,1
|
||
|
call FileSeek
|
||
|
jmp .nxt
|
||
|
.ex:
|
||
|
Msg 2
|
||
|
mov eax,[file_count]
|
||
|
if ~ SYS eq win
|
||
|
dpd eax
|
||
|
else
|
||
|
pusha
|
||
|
call int2str
|
||
|
mov edx,os_work
|
||
|
call DebugPrint
|
||
|
popa
|
||
|
end if
|
||
|
Newline
|
||
|
ret
|
||
|
|
||
|
ZipFindN:
|
||
|
; ecx - file #
|
||
|
Msg 33
|
||
|
cmp ecx,[file_count]
|
||
|
jae .err
|
||
|
push ecx
|
||
|
call ResetFile
|
||
|
.nxt:
|
||
|
call ZipCrawl
|
||
|
cmp edx,51
|
||
|
je .ok2
|
||
|
.noenc:
|
||
|
test edx,edx
|
||
|
jnz .err
|
||
|
.ok2:
|
||
|
add eax,ecx
|
||
|
cmp dword[esp],0
|
||
|
jz .ok
|
||
|
dec dword[esp]
|
||
|
mov ebx,1
|
||
|
call FileSeek
|
||
|
jmp .nxt
|
||
|
.err:
|
||
|
mov edx,4
|
||
|
jmp .ex
|
||
|
.ok:
|
||
|
pop ecx
|
||
|
sub eax,[esi+18]
|
||
|
add esi,eax
|
||
|
mov edx,5
|
||
|
.ex:
|
||
|
push edx
|
||
|
Msg edx
|
||
|
pop edx
|
||
|
ret
|
||
|
|
||
|
ZipCrawl:
|
||
|
mov edx,52
|
||
|
cmp dword[esi],fhs_central
|
||
|
jne .noc
|
||
|
mov eax,46
|
||
|
movzx ecx,word[esi+28]
|
||
|
add eax,ecx
|
||
|
movzx ecx,word[esi+30]
|
||
|
add eax,ecx
|
||
|
movzx ecx,word[esi+32]
|
||
|
mov edx,1
|
||
|
ret
|
||
|
.noc:
|
||
|
cmp dword[esi],fhs_end
|
||
|
jne .noe
|
||
|
.edx3:
|
||
|
Msg 3
|
||
|
mov edx,3
|
||
|
ret
|
||
|
.noe:
|
||
|
cmp dword[esi],fhs_local
|
||
|
je .loc
|
||
|
cmp dword[esi],fhs_enc
|
||
|
jne .err
|
||
|
mov eax,16
|
||
|
xor ecx,ecx
|
||
|
mov edx,1
|
||
|
ret
|
||
|
.loc:
|
||
|
push word[esi+6]
|
||
|
pop [gpbf]
|
||
|
push dword[esi+14]
|
||
|
pop [CRC_check]
|
||
|
push dword[esi+22]
|
||
|
pop [unp_size]
|
||
|
movzx ecx,word[esi+26]
|
||
|
mov eax,30
|
||
|
lea edx,[esi+eax]
|
||
|
add eax,ecx
|
||
|
if IGNORE_DIRS eq 1
|
||
|
cmp byte[edx+ecx-1],'/'
|
||
|
je .skipdp
|
||
|
end if
|
||
|
call PrintFilename
|
||
|
.skipdp:
|
||
|
movzx ecx,word[esi+28]
|
||
|
add eax,[esi+18]
|
||
|
test [gpbf],1
|
||
|
jz .no_enc
|
||
|
or [Flags],DECRYPT_MODE ; encrypted
|
||
|
mov edx,51
|
||
|
jmp .err
|
||
|
.no_enc:
|
||
|
test word[esi+8],7
|
||
|
rep_err z,50
|
||
|
.ok:
|
||
|
xor edx,edx
|
||
|
.err:
|
||
|
ret
|
||
|
|
||
|
; ***********************************************
|
||
|
GzipParse:
|
||
|
ID1ID2 equ 0x8b1f
|
||
|
FTEXT equ 1b
|
||
|
FHCRC equ 10b
|
||
|
FEXTRA equ 100b
|
||
|
FNAME equ 1000b
|
||
|
FCOMMENT equ 10000b
|
||
|
mov eax,7
|
||
|
mov ebx,2
|
||
|
call FileSeek
|
||
|
push dword[esi]
|
||
|
pop [CRC_check]
|
||
|
push dword[esi+4]
|
||
|
pop [unp_size]
|
||
|
call ResetFile
|
||
|
xor edx,edx
|
||
|
cmp word[esi],ID1ID2
|
||
|
rep_err e, 52, 15
|
||
|
cmp byte[esi+2],8
|
||
|
rep_err e, 52, 50
|
||
|
mov bl,[esi+3] ; bl - FLG
|
||
|
add esi,10 ; esi->extra
|
||
|
test bl,FEXTRA
|
||
|
jz .noextr
|
||
|
movzx eax,word[esi]
|
||
|
lea esi,[esi+eax+2] ; esi->FNAME
|
||
|
.noextr:
|
||
|
test bl,FNAME
|
||
|
jz .nofname
|
||
|
mov edx,esi
|
||
|
call DebugPrint
|
||
|
call SkipASCIIZ
|
||
|
cmp dword[esi-5],'.tar'
|
||
|
jne .nofname
|
||
|
or [Flags],TAR_MODE
|
||
|
.nofname: ; esi->FCOMMENT
|
||
|
test bl,FCOMMENT
|
||
|
jz .nocomm
|
||
|
call SkipASCIIZ
|
||
|
.nocomm: ; esi->HCRC
|
||
|
test bl,FHCRC
|
||
|
jz .noCRC16
|
||
|
add esi,2
|
||
|
.noCRC16:
|
||
|
cmp [unp_size],OUTBUF
|
||
|
jb .sizeok2
|
||
|
Msg 16
|
||
|
mov edx,15
|
||
|
ret
|
||
|
.sizeok2:
|
||
|
xor edx,edx
|
||
|
.err:
|
||
|
ret
|
||
|
|
||
|
PngParse:
|
||
|
ID1 equ 0x474e5089
|
||
|
ID2 equ 0x0a1a0a0d
|
||
|
FDICT equ 100000b
|
||
|
InitIDAT equ 2
|
||
|
mov [IDATcount],InitIDAT
|
||
|
call ResetFile
|
||
|
cmp dword[esi],ID1
|
||
|
rep_err e, 52, 18
|
||
|
cmp dword[esi+4],ID2
|
||
|
rep_err e, 52, 18
|
||
|
add esi,8
|
||
|
cmp dword[esi+4],'IHDR'
|
||
|
rep_err e,52, 18
|
||
|
or [Flags],PNG_MODE
|
||
|
memcpy_esi PNG_info,13,8
|
||
|
mov eax,[PNG_info.Width]
|
||
|
bswap eax
|
||
|
mov [PNG_info.Width],eax
|
||
|
mov eax,[PNG_info.Height]
|
||
|
bswap eax
|
||
|
mov [PNG_info.Height],eax
|
||
|
add esi,25
|
||
|
cmp byte[esi-5],0
|
||
|
rep_err e,52,29
|
||
|
.nxt_sec:
|
||
|
lodsd
|
||
|
bswap eax ; eax - section size
|
||
|
push eax
|
||
|
lodsd
|
||
|
mov edi,Png_ch
|
||
|
mov ecx,(E_ch-Png_ch) / 4
|
||
|
repne scasd
|
||
|
pop eax
|
||
|
mov ebx,[esi-4]
|
||
|
mov edx,os_work
|
||
|
mov [edx],ebx
|
||
|
mov dword[edx+4],0x0a0d
|
||
|
.dp:
|
||
|
sub edi,Png_ch
|
||
|
shr edi,2 ; edi- chunk #
|
||
|
if SHOW_PNG_SEC eq 1
|
||
|
call DebugPrint
|
||
|
end if
|
||
|
cmp edi,1
|
||
|
jne .noend
|
||
|
mov edx,21
|
||
|
jmp .err
|
||
|
.noend:
|
||
|
cmp edi,2
|
||
|
jne .noplte
|
||
|
memcpy_esi PNG_info.Palette,eax
|
||
|
jmp .noidat
|
||
|
.noplte:
|
||
|
cmp edi,3
|
||
|
jne .noidat
|
||
|
mov [IDATsize],eax
|
||
|
cmp [IDATcount],InitIDAT
|
||
|
jne .ex
|
||
|
mov [bits],8
|
||
|
if RBLOCK eq 4
|
||
|
lodsd
|
||
|
else
|
||
|
lodsb
|
||
|
end if
|
||
|
call setcurb
|
||
|
rbits 0,16
|
||
|
test ah,FDICT
|
||
|
jz .ex
|
||
|
rbits 0,32
|
||
|
add [IDATcount],4
|
||
|
jmp .ex
|
||
|
.noidat:
|
||
|
add eax,4
|
||
|
mov ebx,1
|
||
|
call FileSeek
|
||
|
jmp .nxt_sec
|
||
|
.ex:
|
||
|
xor edx,edx
|
||
|
.err:
|
||
|
ret
|
||
|
|
||
|
Png_ch:
|
||
|
dd 'IEND','PLTE','IDAT','????'
|
||
|
E_ch:
|
||
|
|
||
|
ZipDecrypt:
|
||
|
push edi
|
||
|
mov ecx,3
|
||
|
mov edi,Dheader
|
||
|
rep movsd
|
||
|
pop edi
|
||
|
call QueryPwd
|
||
|
jecxz .ex
|
||
|
push esi
|
||
|
mov [DKeys], 305419896
|
||
|
mov [DKeys+4],591751049
|
||
|
mov [DKeys+8],878082192
|
||
|
xor eax,eax
|
||
|
mov esi,Dpassword
|
||
|
.enc_init:
|
||
|
lodsb
|
||
|
call UKeys
|
||
|
loop .enc_init
|
||
|
mov ecx,12
|
||
|
mov esi,Dheader
|
||
|
.dec_header:
|
||
|
call decrypt_byte
|
||
|
xor al,[esi]
|
||
|
call UKeys
|
||
|
mov [esi],al
|
||
|
inc esi
|
||
|
loop .dec_header
|
||
|
mov eax,[CRC_check]
|
||
|
pop esi
|
||
|
.ex:
|
||
|
ret
|
||
|
|
||
|
QueryPwd:
|
||
|
; out: ecx - passwd len
|
||
|
if SYS eq win
|
||
|
Msg 32
|
||
|
invoke ReadConsole,[cons_in],Dpassword,PASSW_LEN,cparam1,NULL
|
||
|
test eax,eax
|
||
|
jnz .inp_ok
|
||
|
xor ecx,ecx
|
||
|
jmp .ex
|
||
|
.inp_ok:
|
||
|
mov ecx,[cparam1]
|
||
|
cmp ecx,PASSW_LEN
|
||
|
je .ex
|
||
|
sub ecx,2
|
||
|
else
|
||
|
end if
|
||
|
.ex:
|
||
|
ret
|
||
|
|
||
|
UKeys:
|
||
|
; in: al - char
|
||
|
pusha
|
||
|
mov edi,134775813
|
||
|
mov ebx,DKeys
|
||
|
mov esi,os_work
|
||
|
mov byte[esi],al
|
||
|
mov ecx,1
|
||
|
push dword[ebx]
|
||
|
pop [CRC32]
|
||
|
call UCRC
|
||
|
push [CRC32]
|
||
|
pop dword[ebx]
|
||
|
mov eax,[ebx]
|
||
|
and eax,0xff
|
||
|
add eax,[ebx+4]
|
||
|
mul edi
|
||
|
inc eax
|
||
|
mov [ebx+4],eax
|
||
|
shr eax,24
|
||
|
mov byte[esi],al
|
||
|
push dword[ebx+8]
|
||
|
pop [CRC32]
|
||
|
call UCRC
|
||
|
push [CRC32]
|
||
|
pop dword[ebx+8]
|
||
|
popa
|
||
|
ret
|
||
|
|
||
|
decrypt_byte:
|
||
|
; out: al
|
||
|
push ebx edx
|
||
|
movzx ebx,word[DKeys+8]
|
||
|
or ebx,2
|
||
|
mov eax,ebx
|
||
|
xor eax,1
|
||
|
mul ebx
|
||
|
shr eax,8
|
||
|
pop edx ebx
|
||
|
ret
|
||
|
|
||
|
setcurb:
|
||
|
; in: eax
|
||
|
test [Flags],DECRYPT_MODE
|
||
|
jz .noenc
|
||
|
push eax
|
||
|
call decrypt_byte
|
||
|
xor al,byte[esp]
|
||
|
add esp,4
|
||
|
call UKeys
|
||
|
.noenc:
|
||
|
mov [cur_byte],eax
|
||
|
ret
|
||
|
|
||
|
TarParse:
|
||
|
call ResetFile
|
||
|
.nxt:
|
||
|
call TarCrawl
|
||
|
; wait
|
||
|
cmp edx,3
|
||
|
je ZipParse.ex
|
||
|
if IGNORE_DIRS eq 1
|
||
|
cmp edx,53
|
||
|
jne .skipinc
|
||
|
end if
|
||
|
inc [file_count]
|
||
|
.skipinc:
|
||
|
add eax,ecx
|
||
|
mov ebx,1
|
||
|
call FileSeek
|
||
|
jmp .nxt
|
||
|
|
||
|
TarFindN:
|
||
|
; in: ecx - file number
|
||
|
; ecx - file #
|
||
|
Msg 33
|
||
|
cmp ecx,[file_count]
|
||
|
jae .err
|
||
|
push ecx
|
||
|
call ResetFile
|
||
|
.nxt:
|
||
|
call TarCrawl
|
||
|
if IGNORE_DIRS eq 1
|
||
|
cmp edx,53
|
||
|
je .seek
|
||
|
end if
|
||
|
test edx,edx
|
||
|
jnz .err
|
||
|
cmp dword[esp],0
|
||
|
jz .ok
|
||
|
dec dword[esp]
|
||
|
.seek:
|
||
|
add eax,ecx
|
||
|
mov ebx,1
|
||
|
call FileSeek
|
||
|
jmp .nxt
|
||
|
.err:
|
||
|
mov edx,4
|
||
|
jmp .ex
|
||
|
.ok:
|
||
|
pop ecx
|
||
|
add esi,eax
|
||
|
mov edx,5
|
||
|
.ex:
|
||
|
Msg edx
|
||
|
ret
|
||
|
|
||
|
TarCrawl:
|
||
|
cmp byte[esi],0
|
||
|
jz ZipCrawl.edx3
|
||
|
push esi
|
||
|
mov ecx,11
|
||
|
add esi,0x7c
|
||
|
call Octal_str
|
||
|
mov esi,[esp]
|
||
|
mov [outfile.size],eax
|
||
|
call SkipASCIIZ
|
||
|
if IGNORE_DIRS eq 1
|
||
|
cmp byte[esi-2],'/'
|
||
|
je .skipdp
|
||
|
end if
|
||
|
mov edx,[esp]
|
||
|
lea ecx,[esi-1]
|
||
|
sub ecx,edx
|
||
|
call PrintFilename
|
||
|
.skipdp:
|
||
|
mov ecx,[outfile.size]
|
||
|
jecxz .zerolen
|
||
|
shr ecx,9
|
||
|
inc ecx
|
||
|
shl ecx,9
|
||
|
.zerolen:
|
||
|
mov eax,512
|
||
|
pop esi
|
||
|
jmp ZipCrawl.ok
|
||
|
|
||
|
Octal_str:
|
||
|
; in: esi - ASCIIZ octal string
|
||
|
; ecx - its length
|
||
|
; out: eax - value
|
||
|
push esi ebx ecx
|
||
|
xor ebx,ebx
|
||
|
xor eax,eax
|
||
|
.jec:
|
||
|
jecxz .zero
|
||
|
cmp byte[esi+ecx-1],' '
|
||
|
jne .lp
|
||
|
dec ecx
|
||
|
jmp .jec
|
||
|
.lp:
|
||
|
lodsb
|
||
|
shl ebx,3
|
||
|
cmp eax,' '
|
||
|
je .space
|
||
|
lea ebx,[ebx+eax-'0']
|
||
|
.space:
|
||
|
loop .lp
|
||
|
mov eax,ebx
|
||
|
.zero:
|
||
|
pop ecx ebx esi
|
||
|
ret
|
||
|
|
||
|
TRAILING_BUF equ 2048
|
||
|
SfxParse:
|
||
|
call ResetFile
|
||
|
cmp word[esi],'MZ'
|
||
|
rep_err e, 34
|
||
|
mov eax,TRAILING_BUF
|
||
|
mov ecx,eax
|
||
|
mov ebx,2
|
||
|
call FileSeek
|
||
|
mov edi,esi
|
||
|
mov al,'P'
|
||
|
.lp:
|
||
|
repne scasb
|
||
|
cmp dword[edi-1],fhs_end
|
||
|
je .end_found
|
||
|
jecxz .err
|
||
|
jmp .lp
|
||
|
.end_found:
|
||
|
dec edi
|
||
|
mov esi,edi
|
||
|
mov eax,[edi+12]
|
||
|
neg eax
|
||
|
mov ebx,1
|
||
|
call FileSeek
|
||
|
push dword[esi+42]
|
||
|
pop [arc_base]
|
||
|
.err:
|
||
|
ret
|
||
|
|
||
|
; Created: May 31, 2005
|
||
|
FiltCall:
|
||
|
dd PngFilter.nofilt,Filt_sub,Filt_up,Filt_av,Filt_paeth,PngFilter.nofilt
|
||
|
PngFilter:
|
||
|
; esi - filtered uncompressed image data
|
||
|
; edi - destination
|
||
|
mov cl,[PNG_info.Color_type]
|
||
|
mov eax,1
|
||
|
cmp cl,3
|
||
|
je .palette
|
||
|
test cl,2
|
||
|
jz .notriple
|
||
|
add eax,2
|
||
|
.notriple:
|
||
|
test cl,4
|
||
|
jz .calc_bpp
|
||
|
inc eax
|
||
|
.calc_bpp:
|
||
|
mul [PNG_info.Bit_depth]
|
||
|
.palette:
|
||
|
mov ecx,eax ; in bits
|
||
|
shr eax,3 ; in bytes
|
||
|
test eax,eax
|
||
|
jnz .noz
|
||
|
inc eax
|
||
|
.noz:
|
||
|
mov [png_bpp],eax
|
||
|
mov eax,[PNG_info.Width]
|
||
|
mov ebp,eax
|
||
|
imul ecx
|
||
|
shr eax,3
|
||
|
test eax,eax
|
||
|
jnz .noz2
|
||
|
inc eax
|
||
|
.noz2:
|
||
|
mov [sline_len],eax ; scanline length
|
||
|
push edi
|
||
|
and [Flags],not 1
|
||
|
mov ecx,[PNG_info.Height]
|
||
|
.scanline:
|
||
|
; Msg 9,1
|
||
|
push ecx
|
||
|
lodsb
|
||
|
movzx eax,al
|
||
|
cmp eax,5
|
||
|
jb .f_ok
|
||
|
mov eax,5
|
||
|
.f_ok:
|
||
|
inc dword[filters+eax*4]
|
||
|
jmp dword[FiltCall+eax*4]
|
||
|
.nofilt:
|
||
|
mov dl,[PNG_info.Color_type]
|
||
|
cmp dl,3
|
||
|
jne .nopalette
|
||
|
lodsb
|
||
|
mov [cur_byte],eax
|
||
|
mov [bits],8
|
||
|
mov ecx,ebp
|
||
|
.pixel:
|
||
|
push ecx
|
||
|
movzx ecx,[PNG_info.Bit_depth]
|
||
|
call rb_png
|
||
|
push esi
|
||
|
lea esi,[eax+eax*2]
|
||
|
add esi,PNG_info.Palette
|
||
|
call PngStore
|
||
|
pop esi
|
||
|
pop ecx
|
||
|
loop .pixel
|
||
|
cmp [bits],8
|
||
|
jne .lp
|
||
|
dec esi
|
||
|
.lp:
|
||
|
pop ecx
|
||
|
loop .sl
|
||
|
jmp .sl2
|
||
|
.sl:
|
||
|
;//
|
||
|
MV equ 1
|
||
|
; mov eax,ecx
|
||
|
; and eax,1 shl MOVE_SLINE_LEV-1
|
||
|
; jnz .scanline
|
||
|
;stop
|
||
|
if MV eq 0
|
||
|
push ecx
|
||
|
mov ecx,edi
|
||
|
sub ecx,esi
|
||
|
sub [outp],esi
|
||
|
mov edi,output
|
||
|
add [outp],edi
|
||
|
rep movsb
|
||
|
mov esi,output
|
||
|
pop ecx
|
||
|
pop eax
|
||
|
push [outp]
|
||
|
end if
|
||
|
;;//
|
||
|
jmp .scanline
|
||
|
.sl2:
|
||
|
;//
|
||
|
; call MoveScanline
|
||
|
sub edi,[outp]
|
||
|
;//
|
||
|
; sub edi,[esp]
|
||
|
pop eax
|
||
|
ret
|
||
|
|
||
|
.nopalette:
|
||
|
test dl,2
|
||
|
jz .notriple1
|
||
|
.__:
|
||
|
mov ecx,[PNG_info.Width]
|
||
|
.RGBcp:
|
||
|
call PngStore
|
||
|
add esi,[png_bpp]
|
||
|
loop .RGBcp
|
||
|
jmp .lp
|
||
|
.notriple1:
|
||
|
test dl,dl
|
||
|
jz .gray
|
||
|
cmp dl,4
|
||
|
jne .__
|
||
|
; Msg 31
|
||
|
; ud2
|
||
|
.gray:
|
||
|
; stop
|
||
|
push ecx
|
||
|
mov ecx,[PNG_info.Width]
|
||
|
mov [bits],8
|
||
|
lodsb
|
||
|
mov [cur_byte],eax
|
||
|
.gray2:
|
||
|
push ecx
|
||
|
movzx ecx,[PNG_info.Bit_depth]
|
||
|
push ecx
|
||
|
call rb_png
|
||
|
pop ecx
|
||
|
cmp ecx,8
|
||
|
jbe .lo
|
||
|
add esi,2
|
||
|
shr eax,8
|
||
|
jmp .stsb
|
||
|
.lo:
|
||
|
neg ecx
|
||
|
add ecx,8
|
||
|
shl eax,cl
|
||
|
.stsb:
|
||
|
mov ecx,3
|
||
|
rep stosb
|
||
|
pop ecx
|
||
|
loop .gray2
|
||
|
dec esi
|
||
|
pop ecx
|
||
|
jmp .lp
|
||
|
|
||
|
Filt_sub:
|
||
|
; dps '-'
|
||
|
mov ecx,[sline_len]
|
||
|
sub ecx,[png_bpp]
|
||
|
push esi edi
|
||
|
mov edi,esi
|
||
|
add edi,[png_bpp]
|
||
|
.scan: ; esi - previous, edi - current
|
||
|
lodsb
|
||
|
add [edi],al
|
||
|
inc edi
|
||
|
loop .scan
|
||
|
|
||
|
pop edi esi
|
||
|
; dps '-'
|
||
|
jmp PngFilter.nofilt
|
||
|
|
||
|
Filt_up:
|
||
|
cmp ecx,[PNG_info.Height]
|
||
|
je PngFilter.nofilt
|
||
|
push esi edi
|
||
|
mov ecx,[sline_len]
|
||
|
mov edi,esi
|
||
|
sub esi,ecx
|
||
|
dec esi
|
||
|
jmp Filt_sub.scan
|
||
|
|
||
|
Filt_av:
|
||
|
pusha
|
||
|
mov ecx,[sline_len]
|
||
|
mov ebp,[PNG_info.Height]
|
||
|
mov edx,[png_bpp] ; edx-raw
|
||
|
neg edx
|
||
|
mov ebx,ecx
|
||
|
sub ebx,[png_bpp]
|
||
|
mov edi,esi
|
||
|
sub esi,ecx
|
||
|
dec esi ; esi-prior
|
||
|
.lpavg:
|
||
|
xor eax,eax
|
||
|
cmp [esp+24h],ebp
|
||
|
je .1stl
|
||
|
movzx eax,byte[esi]
|
||
|
.1stl:
|
||
|
cmp ecx,ebx
|
||
|
ja .leftbad
|
||
|
push ecx
|
||
|
movzx ecx,byte[edi+edx]
|
||
|
add eax,ecx
|
||
|
pop ecx
|
||
|
.leftbad:
|
||
|
shr eax,1
|
||
|
add [edi],al
|
||
|
inc esi
|
||
|
inc edi
|
||
|
loop .lpavg
|
||
|
popa
|
||
|
jmp PngFilter.nofilt
|
||
|
|
||
|
Filt_paeth:
|
||
|
pusha
|
||
|
mov ecx,[sline_len]
|
||
|
mov edx,[png_bpp]
|
||
|
neg edx
|
||
|
lea ebp,[ecx+edx] ; left edge
|
||
|
mov edi,esi
|
||
|
sub esi,ecx
|
||
|
dec esi
|
||
|
.lpaeth:
|
||
|
push ecx
|
||
|
movzx eax,byte[edi+edx]
|
||
|
movzx ebx,byte[esi]
|
||
|
movzx ecx,byte[esi+edx]
|
||
|
push eax
|
||
|
mov eax,[esp+28h]
|
||
|
cmp eax,[PNG_info.Height] ; 1st line
|
||
|
jne .no1stlineok
|
||
|
xor ebx,ebx
|
||
|
xor ecx,ecx
|
||
|
.no1stlineok:
|
||
|
pop eax
|
||
|
cmp [esp],ebp ; ecx
|
||
|
jbe .leftok ; x-bpp>=0
|
||
|
xor eax,eax
|
||
|
xor ecx,ecx
|
||
|
.leftok:
|
||
|
pusha ; eax-28, ebx-16, ecx-24
|
||
|
lea edx,[eax+ebx]
|
||
|
sub edx,ecx ; p=edx
|
||
|
sub eax,edx ; pa := abs(p - a)
|
||
|
jge .eaxp
|
||
|
neg eax
|
||
|
.eaxp:
|
||
|
sub ebx,edx ; pb := abs(p - b)
|
||
|
jge .ebxp
|
||
|
neg ebx
|
||
|
.ebxp:
|
||
|
sub ecx,edx ; pc := abs(p - c)
|
||
|
jge .ecxp
|
||
|
neg ecx
|
||
|
.ecxp:
|
||
|
cmp eax,ebx
|
||
|
ja .noa
|
||
|
cmp eax,ecx
|
||
|
jbe .ex ; pa-min
|
||
|
.noa:
|
||
|
cmp ebx,ecx
|
||
|
ja .nob
|
||
|
mov eax,[esp+16]
|
||
|
jmp .ex2
|
||
|
.nob:
|
||
|
mov eax,[esp+24]
|
||
|
.ex2:
|
||
|
mov [esp+28],eax
|
||
|
.ex:
|
||
|
popa
|
||
|
add [edi],al
|
||
|
inc esi
|
||
|
inc edi
|
||
|
pop ecx
|
||
|
loop .lpaeth
|
||
|
popa
|
||
|
jmp PngFilter.nofilt
|
||
|
|
||
|
rb_png: ; eax-dest; ecx-count
|
||
|
push ecx
|
||
|
xor eax,eax
|
||
|
.shift:
|
||
|
rol byte[cur_byte],1
|
||
|
rcl eax,1
|
||
|
.dec:
|
||
|
dec [bits]
|
||
|
jnz .loop1
|
||
|
.push:
|
||
|
push dword[esi]
|
||
|
pop [cur_byte]
|
||
|
mov [bits],8
|
||
|
inc esi
|
||
|
.loop1:
|
||
|
loop .shift
|
||
|
pop ecx
|
||
|
ret
|
||
|
|
||
|
PngStore:
|
||
|
push esi
|
||
|
cmp [PNG_info.Bit_depth],8
|
||
|
jbe .lo
|
||
|
add esi,3
|
||
|
.lo:
|
||
|
if ~ SYS eq win
|
||
|
mov esi,[esi]
|
||
|
bswap esi
|
||
|
shr esi,8
|
||
|
mov [edi],esi
|
||
|
add edi,3
|
||
|
else
|
||
|
movsw
|
||
|
movsb
|
||
|
end if
|
||
|
pop esi
|
||
|
ret
|
||
|
|
||
|
FiltStats:
|
||
|
pusha
|
||
|
xor ebx,ebx
|
||
|
mov edx,23
|
||
|
mov ecx,6
|
||
|
.lp:
|
||
|
push ecx edx
|
||
|
Msg edx
|
||
|
mov eax,[filters+ebx*4]
|
||
|
DebugPrintDec
|
||
|
pop edx ecx
|
||
|
inc edx
|
||
|
inc ebx
|
||
|
loop .lp
|
||
|
Newline
|
||
|
popa
|
||
|
ret
|
||
|
|