kolibrios-fun/programs/other/kpack/trunk/packpoc.inc

484 lines
8.2 KiB
PHP
Raw Normal View History

;*********************************************************************
pack:
call displogo_and_readfile
jz inopened
;---------------------------------------------------------------------
infileerr:
call return_memory
mov esi,errload_str
push errload_len
pop ecx
jmp write_string
;---------------------------------------------------------------------
inopened:
mov ebx,[insize]
test ebx,ebx
jz infileerr
; maximum memory requests: 2*insize + 2*(maxoutsize+400h) + worksize
xor esi,esi
add esi,ebx
mov [inbuftmp],esi
add esi,ebx
mov [outfile],esi
mov [outfile1],esi
mov [outfilebest],esi
mov ecx,ebx
shr ecx,3
add ecx,ebx
add ecx,400h
add esi,ecx
mov [outfile2],esi
add esi,ecx
mov [workmem],esi
add ecx,ebx
add ecx,ecx
; LZMA requires 0x448000 + dictsize*9.5 bytes for workmem,
and [lzma_dictsize],0
push ecx
mov eax,ebx
dec eax
bsr ecx,eax
inc ecx
cmp ecx,28
jb @f
mov cl,28
;--------------------------------------
@@:
mov edx,ecx
xor eax,eax
inc eax
shl eax,cl
imul eax,19
shr eax,1
add eax,448000h
pop ecx
add ecx,eax
mcall 68,12
mov [infile],eax
add [inbuftmp],eax
add [outfile],eax
add [outfile1],eax
add [outfilebest],eax
add [outfile2],eax
add [workmem],eax
;--------------------------------------
; try to use smaller dictionary
;meml0:
; cmp edx,4
; jbe memf1
;
; dec edx
; xor eax,eax
; inc eax
; mov ecx,edx
; shl eax,cl
; imul eax,19
; shr eax,1
; add eax,509000h
; pop ecx
; push ecx
; add ecx,eax
; mcall 64
; test eax,eax
; jnz meml0
;--------------------------------------
; ok, say warning and continue
; mov [lzma_dictsize],edx
; mov esi,lzma_memsmall_str
; push lzma_memsmall_len
; pop ecx
; call write_string
; jmp mem_ok
;---------------------------------------------------------------------
;memf1:
; mov esi,nomem_str
; push nomem_len
; pop ecx
; jmp write_string
;---------------------------------------------------------------------
mem_ok:
mov eax,[insize]
mov ebx,fn70block
mov [ebx],byte 0
mov [ebx+12],eax
mov esi,[infile]
mov [ebx+16],esi
mcall 70
test eax,eax
jnz infileerr
mov eax,[outfile]
mov [eax],dword 'KPCK'
mov ecx,[insize]
mov [eax+4],dword ecx
mov edi,eax
; set LZMA dictionary size
mov eax,[lzma_dictsize]
test eax,eax
js no_lzma_setds
jnz lzma_setds
mov ecx,[insize]
dec ecx
bsr eax,ecx
inc eax
cmp eax,28
jb lzma_setds
mov eax,28
;--------------------------------------
lzma_setds:
push eax
call lzma_set_dict_size
;--------------------------------------
no_lzma_setds:
call tell_compress_mess
mov esi,[outfile1]
mov edi,[outfile2]
movsd
movsd
movsd
call pack_lzma
mov [outsize],eax
mov eax,[outfile]
mov [outfilebest],eax
mov [method],use_lzma
;--------------------------------------
@@:
call preprocess_calltrick
test eax,eax
jz noct1
call set_outfile
call pack_lzma
add eax,5
cmp eax,[outsize]
jae @f
mov [outsize],eax
mov eax,[outfile]
mov [outfilebest],eax
mov [method],use_lzma or use_calltrick1
;--------------------------------------
@@:
noct1:
call set_outfile
push [ctn]
mov al,[cti]
push eax
call preprocess_calltrick2
test eax,eax
jz noct2
call set_outfile
call pack_lzma
add eax,5
cmp eax,[outsize]
jae @f
mov [outsize],eax
mov eax,[outfile]
mov [outfilebest],eax
mov [method],use_lzma or use_calltrick2
pop ecx
pop ecx
push [ctn]
mov al,[cti]
push eax
;--------------------------------------
@@:
noct2:
pop eax
mov [cti],al
pop [ctn]
add [outsize],12
mov eax,[outsize]
cmp eax,[insize]
jb packed_ok
mov esi,too_big_str
push too_big_len
pop ecx
jmp write_string
;---------------------------------------------------------------------
packed_ok:
; set header
movzx eax,[method]
mov edi,[outfilebest]
mov [edi+8],eax
test al,use_calltrick1 or use_calltrick2
jz @f
mov ecx,[outsize]
add ecx,edi
mov eax,[ctn]
mov [ecx-5],eax
mov al,[cti]
mov [ecx-1],al
;--------------------------------------
@@:
mov eax,[outsize]
mov ecx,100
mul ecx
div [insize]
aam
xchg al,ah
add ax,'00'
mov [ratio],ax
mov esi,done_str
push done_len
pop ecx
call write_string
;--------------------------------------
; save output file
saveout:
mov esi,outname
call get_full_name
mov ebx,fn70block
mov [ebx],byte 2
mov eax,[outfilebest]
mov ecx,[outsize]
mov [ebx+12],ecx
mov [ebx+16],eax
mcall 70
test eax,eax
jz @f
;--------------------------------------
outerr:
mov esi,outfileerr_str
push outfileerr_len
pop ecx
jmp write_string
;---------------------------------------------------------------------
@@:
xor eax,eax
mov ebx,fn70block
mov [ebx],byte 6
mov [ebx+4],eax
mov [ebx+8],eax
mov [ebx+12],eax
mov [ebx+16],dword file_attr
mcall 70
call return_memory
ret
;---------------------------------------------------------------------
set_outfile:
mov eax,[outfilebest]
xor eax,[outfile1]
xor eax,[outfile2]
mov [outfile],eax
ret
;---------------------------------------------------------------------
pack_calltrick_fail:
xor eax,eax
mov [ctn],0
ret
;---------------------------------------------------------------------
preprocess_calltrick:
; input preprocessing
xor eax,eax
mov edi,ct1
mov ecx,256/4
push edi
rep stosd
pop edi
mov ecx,[insize]
mov esi,[infile]
xchg eax,edx
mov ebx,[inbuftmp]
;--------------------------------------
input_pre:
lodsb
sub al,0E8h
cmp al,1
ja input_pre_cont
cmp ecx,5
jb input_pre_done
lodsd
add eax,esi
sub eax,[infile]
cmp eax,[insize]
jae xxx
cmp eax,1000000h
jae xxx
sub ecx,4
; bswap is not supported on i386
xchg al,ah
ror eax,16
xchg al,ah
mov [esi-4],eax
inc edx
mov [ebx],esi
add ebx,4
jmp input_pre_cont
;---------------------------------------------------------------------
xxx:
sub esi,4
movzx eax,byte [esi]
mov [eax+edi],byte 1
;--------------------------------------
input_pre_cont:
loop input_pre
;--------------------------------------
input_pre_done:
mov [ctn],edx
xor eax,eax
mov ecx,256
repnz scasb
jnz pack_calltrick_fail
not cl
mov [cti],cl
@@:
cmp ebx,[inbuftmp]
jz @f
sub ebx,4
mov eax,[ebx]
mov [eax-4],cl
jmp @b
;---------------------------------------------------------------------
@@:
mov al,1
ret
;---------------------------------------------------------------------
pack_lzma:
mov eax,[outfile]
add eax,11
push [workmem] ;workmem
push [insize] ;length
push eax ;destination
push [infile] ;source
call lzma_compress
mov ecx,[outfile]
mov edx,[ecx+12]
xchg dl,dh
ror edx,16
xchg dl,dh
mov [ecx+12],edx
dec eax
ret
;---------------------------------------------------------------------
preprocess_calltrick2:
; restore input
mov esi,[infile]
mov ecx,[ctn]
jecxz pc2l2
;--------------------------------------
pc2l1:
lodsb
sub al,0E8h
cmp al,1
ja pc2l1
mov al,[cti]
cmp [esi],al
jnz pc2l1
lodsd
shr ax,8
ror eax,16
xchg al,ah
sub eax,esi
add eax,[infile]
mov [esi-4],eax
loop pc2l1
;--------------------------------------
pc2l2:
; input preprocessing
mov edi,ct1
xor eax,eax
push edi
mov ecx,256/4
rep stosd
pop edi
mov ecx,[insize]
mov esi,[infile]
mov ebx,[inbuftmp]
xchg eax,edx
;--------------------------------------
input_pre2:
lodsb
;--------------------------------------
@@:
cmp al,0Fh
jnz ip1
dec ecx
jz input_pre_done2
lodsb
cmp al,80h
jb @b
cmp al,90h
jb @f
;--------------------------------------
ip1:
sub al,0E8h
cmp al,1
ja input_pre_cont2
;--------------------------------------
@@:
cmp ecx,5
jb input_pre_done2
lodsd
add eax,esi
sub eax,[infile]
cmp eax,[insize]
jae xxx2
cmp eax,1000000h
jae xxx2
sub ecx,4
xchg al,ah
rol eax,16
xchg al,ah
mov [esi-4],eax
inc edx
mov [ebx],esi
add ebx,4
jmp input_pre_cont2
;---------------------------------------------------------------------
xxx2: sub esi,4
movzx eax,byte [esi]
mov [eax+edi],byte 1
;--------------------------------------
input_pre_cont2:
loop input_pre2
;--------------------------------------
input_pre_done2:
mov [ctn],edx
xor eax,eax
mov ecx,256
repnz scasb
jnz pack_calltrick_fail
not cl
mov [cti],cl
;--------------------------------------
@@:
cmp ebx,[inbuftmp]
jz @f
sub ebx,4
mov eax,[ebx]
mov [eax-4],cl
jmp @b
;---------------------------------------------------------------------
@@:
mov al,1
ret
;*********************************************************************