0,0 → 1,615 |
; @RCHER main algorythm |
; Written in pure assembler by Ivushkin Andrey aka Willow |
|
macro get_a _type,_size,c1,c2,c3,c4,c5 |
{ |
get_#_type: |
local .no,.no0,.ex |
push edx |
and [Flags],not 1 |
if _type eq Len |
cmp eax,c4 |
jne .no |
mov eax,c5 |
jmp .ex |
.no: |
end if |
sub eax,c1 |
ja .no0 |
add eax,c2 |
jmp .ex |
.no0: |
add eax,c3 |
push eax |
mov ecx,eax |
shr ecx,_size |
xor eax,eax |
call read_bits |
pop edx |
and edx,1 shl _size-1 |
shl edx,cl |
movzx ecx,[tblH#_type+ecx*2] |
add edx,ecx |
add eax,edx |
.ex: |
or [Flags],1 |
pop edx |
ret |
} |
; ************************* |
|
Deflate: |
mov edi,[outp] |
.init: |
mov [bits],8 |
lodsb |
call setcurb |
.blkbegin: |
and [lastblk],0 |
and [Flags],not 1 |
rbits 0,1 |
test eax,eax |
je .nolast |
mov [lastblk],1 |
.nolast: |
rbits 0,2 |
cmp eax,10b |
je .DynHuff |
cmp eax,01b |
je .static |
test eax,eax |
jnz .errorID |
Msg 30 |
movzx ecx,[bits] |
call read_bits |
movzx ecx,word[esi-1] |
add esi,3 |
rep movsb |
jmp .check_last |
.errorID: |
Msg 6 |
ret |
; Static Huffman |
.static: |
if SHOW_METH eq 1 |
Msg 20 |
end if |
mov edi,[outp] |
or [Flags],1 |
.next: |
rbits 0,7 |
; stop |
cmp eax,0x17 |
ja .no7 |
add eax,256 |
cmp eax,256 |
jne .noend |
.check_last: |
mov [outp],edi |
cmp [lastblk],1 |
je .ex |
jmp .blkbegin |
.noend: |
call get_Len |
mov ebx,eax |
rbits 0,5 |
call get_Dist |
neg eax |
push esi |
lea esi,[edi+eax] |
mov ecx,ebx |
rep movsb |
pop esi |
jmp .next |
.no7: |
rbits eax,1 |
cmp eax,0xc8 |
jb .no9 |
rbits eax,1 |
sub eax,0xd0 |
jmp .no81 |
.no9: |
cmp eax,0xc0 |
jb .no81 |
add eax,0x58 |
jmp .noend |
.no81: |
sub eax,0x30 |
stosb |
jmp .next |
.ex: |
ret |
; ************* dynamic Huffman ************ |
|
.DynHuff: |
; dps '##' |
if SHOW_METH eq 1 |
Msg 19 |
end if |
pusha |
xor eax,eax |
mov ecx,(area-bl_count) / 4 |
mov edi,bl_count |
rep stosd |
popa |
|
; max_len=0 |
and [max_len],0 |
rbits 0,5 |
; hlit-257 |
add eax,257 |
mov [hlit],ax |
rbits 0,5 |
; hdist-1 |
inc eax |
mov [hdist],al |
rbits 0,4 |
; hclen-4 |
add eax,4 |
mov [hclen],al |
mov ecx,eax |
push edi |
mov edi,tmp_clit |
; read code lengths for code lengths |
.alphloop: |
push ecx |
rbits 0,3 |
stosb |
pop ecx |
loop .alphloop |
; sort code lengths for code lengths |
push esi |
movzx ecx,[hclen] |
xor eax,eax |
mov edi,tmp_clit |
mov esi,tblSort |
.sortloop: |
lodsb |
movzx bx,byte[edi] |
mov [sorted_clit+eax*2],bx |
inc edi |
loop .sortloop |
pop esi edi |
.generate: |
mov ecx,19 |
mov ebx,calph |
mov edx,seql |
mov eax,sorted_clit |
call Huffc |
and [tblCount],0 |
or [Flags],1 |
mov edi,Lit_c |
mov ebp,sorted_clit |
.again: |
cmp edi,output+OUTBUF |
jb ._ok |
Msg 16 |
jmp .ex |
._ok: |
mov edx,seql |
mov ebx,calph |
call get_code |
call ExpLen |
cmp [hlit],ax |
ja .again |
if SHOW_CHARS eq 1 |
mov edi,Lit_c |
call Show_codes |
end if |
mov edi,Dist_c |
and [tblCount],0 |
.again2: |
mov ebx,calph |
|
call get_code |
call ExpLen |
cmp [hdist],al |
ja .again2 |
movzx ecx,[hlit] |
mov ebx,Literal |
mov edx,seql |
mov eax,Lit_c |
call Huffc |
movzx ecx,[hdist] |
mov ebx,Distance |
mov edx,seqd |
mov eax,Dist_c |
call Huffc |
|
push [hlit] |
pop [tblLen] |
mov ebp,Lit_c |
mov edx,seql |
mov ebx,Literal |
mov edi,[outp] |
and [tblCount],0 |
.again3: ; <------------ |
call get_code |
cmp eax,256 |
je .check_last |
ja .dist |
stosb |
jmp .again3 |
.dist: |
call get_Len |
push eax ebx edx ebp |
mov ecx,32 |
mov ebp,Dist_c |
mov edx,seqd |
mov ebx,Distance |
mov [tblLen],32 |
call get_code |
call get_Dist |
push [hlit] |
pop [tblLen] |
neg eax |
pop ebp edx ebx ecx |
push esi |
lea esi,[edi+eax] |
rep movsb |
pop esi |
jmp .again3 |
|
; ****************************************** |
Huffc: |
; EBX - dest array, ECX - length, EDX - br_seq dest, EAX - source array |
push esi edi eax ecx |
mov edi,bl_count |
xor eax,eax |
mov ecx,BITS |
rep stosw |
pop ecx |
mov esi,[esp] |
mov [tblLen],cx |
mov [max_len],ax |
; Count the number of codes for each code length |
.cnt_loop: |
lodsw |
cmp [max_len],ax |
jae .skip |
mov [max_len],ax |
.skip: |
inc byte[bl_count+eax] |
loop .cnt_loop |
movzx ecx,[max_len] |
xor eax,eax |
and [bl_count],al |
xor esi,esi ; edx - bits |
mov edi,next_code+2 |
push ebx |
; Find the numerical value of the smallest code for each code length |
.nc_loop: |
movzx bx,byte[bl_count+esi] |
add ax,bx |
shl ax,1 |
stosw |
inc esi |
loop .nc_loop |
pop ebx |
; clear table |
movzx ecx,[tblLen] |
xor eax,eax |
dec eax |
mov edi,ebx |
rep stosw |
inc eax |
movzx ecx,[tblLen] |
mov esi,[esp] |
mov edi,ebx |
; Assign numerical values to all codes |
.loop3: |
lodsw |
test eax,eax |
jz .lp |
push [next_code+eax*2] |
pop word[edi] |
inc [next_code+eax*2] |
.lp: |
add edi,2 |
loop .loop3 |
; Clear all codes |
xor eax,eax |
mov edi,edx |
movzx ecx,[max_len] |
mov [edi-1],al |
; Prepare read bit sequences |
.rebiloop: |
inc eax |
cmp [bl_count+eax],0 |
jz .sk |
stosb |
inc byte[edx-1] |
.sk: |
loop .rebiloop |
movzx ecx,byte[edx-1] |
dec ecx |
jecxz .noreb2 |
.reb2loop: |
mov al,[edx+ecx-1] |
sub [edx+ecx],al |
loop .reb2loop |
.noreb2: |
pop eax edi esi |
ret |
|
; ****************************************** |
|
; get Codes of variable sizes |
get_code: |
; EDX - br_seq, EBX - source table, EBP - codelength table |
push edx edi |
xor eax,eax |
movzx ecx,byte[edx-1] |
mov [codel],ax |
.rb3: |
push ecx |
movzx ecx,byte[edx] |
add [codel],cx |
call read_bits |
movzx ecx,[tblLen] |
inc ecx |
mov edi,ebx |
.scas: |
repne scasw |
jecxz .notfound |
push edi ecx |
sub edi,ebx |
sub edi,2 |
mov cx,[codel] |
cmp cx,[ds:ebp+edi] |
jne .notfound2 |
mov eax,edi |
shr eax,1 |
add esp,12 |
.pp: |
pop edi edx |
ret |
.notfound2: |
pop ecx |
pop edi |
jmp .scas |
.notfound: |
pop ecx |
inc edx |
loop .rb3 |
Msg 7 |
jmp .pp |
|
codel dw ? |
; ****************************************** |
ExpLen: |
cmp eax,16 |
jae .noliteral |
inc [tblCount] |
stosw |
jmp .nomatch |
.noliteral: |
and [Flags],not 1 |
mov ebx,3 |
cmp eax,17 |
jae .code1718 |
mov ecx,2 |
xor eax,eax |
call read_bits |
lea ecx,[eax+ebx] |
mov ax,[edi-2] |
.cc: |
add [tblCount],cx |
rep stosw |
or [Flags],1 |
jmp .nomatch |
.code1718: |
jne .code18 |
mov ecx,3 |
.cc2: |
xor eax,eax |
call read_bits |
lea ecx,[eax+ebx] |
xor eax,eax |
jmp .cc |
.code18: |
mov ebx,11 |
mov ecx,7 |
jmp .cc2 |
.nomatch: |
mov ax,[tblCount] |
ret |
get_a Len,2,256+8,10,3,285,258 |
get_a Dist,1,3,4,1 |
|
|
; ****************************************** |
read_bits: ; eax-dest; ecx-count |
push edx ecx |
.shift: |
if RBLOCK eq 4 |
ror [cur_byte],1 |
else |
ror byte[cur_byte],1 |
end if |
pushf |
test [Flags],1 |
je .noh1 |
popf |
rcl eax,1 |
jmp .dec |
.noh1: |
popf |
rcr eax,1 |
.dec: |
dec [bits] |
jnz .loop1 |
.push: |
push eax |
mov eax,[esi] |
call setcurb |
pop eax |
if RBLOCK eq 1 |
inc esi |
inc [IDATcount] |
else |
inc esi |
inc [IDATcount] |
end if |
cmp esi,area+INBUF-BSIZE |
jbe .ok |
pusha |
if SHOW_RBLOCK eq 1 |
Msg 9 |
end if |
mov eax,0 |
mov ebx,1 |
call FileSeek |
mov [esp+4],esi |
popa |
.ok: |
test [Flags],PNG_MODE |
jz .idatok |
mov edx,[IDATcount] |
cmp edx,[IDATsize] |
jbe .idatok |
pusha |
lodsd |
call PngParse.nxt_sec |
mov [IDATcount],1 |
mov [esp+4],esi |
mov [esp+20],edx |
popa |
cmp edx,21 |
jne .idatok |
mov eax,256 |
pop ecx |
jmp .exx |
.idatok: |
|
mov [bits],8 |
.loop1: |
loop .shift2 |
jmp .popc |
.shift2: |
jmp .shift |
.popc: |
pop ecx |
test [Flags],1 |
jne .exx |
.noh2: |
rol eax,cl |
.exx: |
pop edx |
ret |
|
if SHOW_CHARS eq 1 |
Show_codes: |
pusha |
movzx ecx,[tblLen] |
mov ecx,256 |
xor eax,eax |
.lp2: |
mov [braces+1],al |
push eax ecx |
invoke StrFormat,eax,strbuf,20 |
invoke WriteConsole,[cons],strbuf,16,param1,NULL |
invoke WriteConsole,[cons],braces,6,param1,NULL |
mov eax,[esp+4] |
movzx eax,word[edi+eax*2] |
test eax,eax |
jz .skip |
invoke WriteConsole,[cons],exist,6,param1,NULL |
.skip: |
invoke WriteConsole,[cons],braces+6,2,param1,NULL |
pop ecx eax |
inc eax |
loop .lp |
jmp .ex |
.lp: |
jmp .lp2 |
.ex: |
popa |
ret |
|
cons dd ? |
param1 dd ? |
braces db '( ) = ',0xa, 0xd |
strbuf rb 20 |
exist db 'exists' |
end if |
|
makeCRC: |
pusha |
Msg 8 |
mov edi,CRC32table |
add edi,255*4 |
std |
mov ecx,255 |
mov ebx,0xedb88320 |
.m1: |
mov eax,ecx |
push ecx |
mov ecx,8 |
.m2: |
shr eax,1 |
jnc .m3 |
xor eax,ebx |
.m3: |
loop .m2 |
pop ecx |
stosd |
loop .m1 |
popa |
cld |
ret |
|
UCRC: |
; in: esi - data to calculate CRC |
; ecx - its length |
; [CRC32] - previous CRC32 |
; out: [CRC32]- partial CRC32 (no pre- & post-conditioning!) |
pusha |
cmp dword[CRC32table+4],0x77073096 |
je .tbl_rdy |
call makeCRC |
.tbl_rdy: |
mov eax,[CRC32] |
not eax |
.m1: |
movzx ebx,al |
shr eax,8 |
xor bl,[esi] |
xor eax,[CRC32table+ebx*4] |
inc esi |
loop .m1 |
not eax |
mov [CRC32],eax |
popa |
ret |
|
UAdler: |
; in: esi - data to calculate CRC |
; ecx - its length |
; [Adler32] - previous Adler32 |
; out: [Adler32]- partial Adler32 |
pusha |
mov ebp,65521 |
movzx ebx,word[Adler32] ; s1-ebx |
movzx edi,word[Adler32+2] ; s2-edi |
.m1: |
movzx eax,byte[esi] |
add eax,ebx |
xor edx,edx |
div ebp |
mov ebx,edx |
lea eax,[edi+ebx] |
xor edx,edx |
div ebp |
mov edi,edx |
inc esi |
loop .m1 |
shl edi,16 |
add edi,ebx |
mov [Adler32],edi |
popa |
ret |
|
tblSort db 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 |
tblHLen dw 7,11,19,35,67,131 |
tblHDist dw 3,5,9,17,33,65,129,257,513,1025,2049,4097,8193,16385 |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |