kolibrios/programs/archer/trunk/parser.inc

897 lines
14 KiB
PHP
Raw Normal View History

; @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