Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5097 → Rev 5098

/programs/other/kpack/kerpack_linux/Makefile
0,0 → 1,21
CFLAGS=-O3
all: kpack kerpack
kpack: kpack64.o LZMAEncoder-kpack.o MatchFinder.o RangeCoder.o
gcc -nostartfiles -o kpack kpack64.o LZMAEncoder-kpack.o MatchFinder.o RangeCoder.o
kpack64.o: kpack64.asm
fasm kpack64.asm kpack64.o
kerpack: kerpack64.o LZMAEncoder-kerpack.o MatchFinder.o RangeCoder.o
gcc -nostartfiles -o kerpack kerpack64.o LZMAEncoder-kerpack.o MatchFinder.o RangeCoder.o
kerpack64.o: kerpack64.asm
fasm kerpack64.asm kerpack64.o
LZMAEncoder-kpack.o: lzma_c/LZMAEncoder.c lzma_c/LZMAEncoder.h lzma_c/MatchFinder.h lzma_c/lzma.h lzma_c/RangeCoder.h lzma_c/RangeCoderBit.h lzma_c/RangeCoderBitTree.h lzma_c/common.h
gcc -c $(CFLAGS) -o LZMAEncoder-kpack.o lzma_c/LZMAEncoder.c
LZMAEncoder-kerpack.o: lzma_c/LZMAEncoder.c lzma_c/LZMAEncoder.h lzma_c/MatchFinder.h lzma_c/lzma.h lzma_c/RangeCoder.h lzma_c/RangeCoderBit.h lzma_c/RangeCoderBitTree.h lzma_c/common.h
gcc -c -DFOR_KERPACK $(CFLAGS) -o LZMAEncoder-kerpack.o lzma_c/LZMAEncoder.c
MatchFinder.o: lzma_c/MatchFinder.c lzma_c/MatchFinder.h lzma_c/common.h
gcc -c $(CFLAGS) -o MatchFinder.o lzma_c/MatchFinder.c
RangeCoder.o: lzma_c/RangeCoder.c lzma_c/RangeCoder.h lzma_c/RangeCoderBit.h lzma_c/RangeCoderBitTree.h lzma_c/lzma.h lzma_c/common.h
gcc -c $(CFLAGS) -o RangeCoder.o lzma_c/RangeCoder.c
 
clean:
rm *.o kpack kerpack
/programs/other/kpack/kerpack_linux/calltrick2.asm
0,0 → 1,32
pop esi
push esi
loader_patch4:
mov ecx, 0 ; will be patched: number of calltrick entries
ctrloop:
lodsb
@@:
cmp al, 0xF
jnz .f
lodsb
cmp al, 80h
jb @b
cmp al, 90h
jb @f
.f:
sub al, 0E8h
cmp al, 1
ja ctrloop
@@:
cmp byte [esi], 0 ; will be patched: code in calltrick entries
loader_patch5:
jnz ctrloop
lodsd
; "bswap eax" is not supported on i386
; mov al,0/bswap eax = 4 bytes, following instructions = 9 bytes
shr ax, 8
ror eax, 16
xchg al, ah
sub eax, esi
add eax, [esp]
mov [esi-4], eax
loop ctrloop
/programs/other/kpack/kerpack_linux/kerpack64.asm
0,0 → 1,460
;freebsd = 1 ;uncomment for FreeBSD-specific changes
 
format ELF64
public _start
.data? fix section ".bss" writeable align 4
.data fix section ".data" writeable align 4
.const fix section ".const" align 4
.code fix section ".text" executable align 16
offset fix
ptr fix
struc label type {
label . type }
 
extrn lzma_compress
extrn lzma_set_dict_size
 
.data?
infilename dq ?
outfilename dq ?
infile dq ?
outfile dq ?
inptr dq ?
workmem dq ?
insize dd ?
outsize dd ?
lzma_dictsize dd ?
indelta dd ?
strucstat rq 18
 
if defined freebsd
st_atime_offset = 24
st_mtime_offset = 40
st_birthtime_offset = 104
st_size_offset = 72
else
st_atime_offset = 72
st_mtime_offset = 88
;st_birthtime_offset not defined
st_size_offset = 48
end if
 
public environ
environ dq ?
public __progname
__progname dq ?
ct1 db 256 dup (?)
ctn dd ?
cti db ?
 
.const
usage_str db 'Written by diamond in 2006, 2007 specially for KolibriOS',13,10
db 'LZMA compression library is copyright (c) 1999-2005 by Igor Pavlov',13,10
db 13,10
db 'Usage: kerpack <infile> [<outfile>]',13,10
usage_len = $ - offset usage_str
errload_str db 'Cannot load input file',13,10
errload_len = $ - offset errload_str
outfileerr_str db 'Cannot save output file',13,10
outfileerr_len = $ - offset outfileerr_str
nomem_str db 'No memory',13,10
nomem_len = $ - offset nomem_str
too_big_str db 'failed, output is greater than input.',13,10
too_big_len = $ - too_big_str
compressing_str db 'Compressing ... '
compressing_len = $ - compressing_str
 
.data
done_str db 'OK! Compression ratio: '
ratio dw '00'
db '%',13,10,13,10
done_len = $ - done_str
 
use_lzma = 1
 
use_no_calltrick = 0
use_calltrick1 = 40h
use_calltrick2 = 80h
 
method db 1
 
.code
; Write string from [rsi] of rdx bytes.
write_string:
; 1. Align stack on 16 bytes.
push rdi
; 2. Set rdi to 1 = descriptor for stdout.
xor edi, edi
inc edi
; 3. Do system call.
call write
; 4. Restore stack and return.
pop rdi
ret
 
; Write string from [rsi] of rdx bytes and exit. Note that main code jumps (not calls) here,
; so we should not align the stack.
write_exit:
; 1. Call prev func.
call write_string
; 2. Do system call for exit.
; Note that this can be used as independent proc jumped (not called) to.
doexit:
xor edi, edi
inc edi
call exit
 
; Main procedure.
_start:
; 1. Parse command line.
; Linux: [rsp] = argc, rsp+8 = argv
; FreeBSD: [rdi] = argc, rdi+8 = argv
; 1a. Load argc and argv to registers,
; skip first argument (which is always program name)
if defined freebsd
mov ecx, [rdi] ; ecx = argc
add rdi, 16 ; rdi = &argv[1]
else
mov ecx, [rsp] ; ecx = argc
lea rdi, [rsp+16] ; rdi = &argv[1]
end if
; 1b. Test for first filename parameter. If no, goto step 2.
call get_file_name
jz usage
; 1c. We got input file name, save it.
; Assume that output file name is the same; if no, we will rewrite it in step 1d.
mov [infilename], rax
mov [outfilename], rax
; 1d. Test for second filename parameter. If yes, rewrite assumption in step 1c and check that there are no 3rd parameter.
call get_file_name
jz @f
mov [outfilename], rax
call get_file_name
jnz usage
@@:
; 1e. Parsing is done, process to step 3.
jmp short cont
; 2. No arguments or too many arguments given; write message and exit.
usage:
push usage_len
pop rdx
mov rsi, offset usage_str
jmp write_exit
cont:
; 4. Load the input file.
; 4a. Do system call for stat - get file times and file size.
mov rdi, [infilename]
mov rsi, offset strucstat
mov r13, rsi
call stat
; 4b. Test result; if not 0 (0 is OK), goto 4e.
test rax, rax
jnz short infileerr
; 4c. Do system call for open.
mov rdi, [infilename]
mov rsi, offset open_mode
call fopen
; 4d. Test result; if not NULL, goto 4f.
test rax, rax
jnz short inopened
infileerr:
; 4e. Say error and abort.
push errload_len
pop rdx
mov rsi, offset errload_str
jmp write_exit
inopened:
mov r12, rax
; 4f. Check that the size is nonzero and less than 4G.
mov edi, [r13+st_size_offset]
test edi, edi
jz short infileerr
cmp dword [r13+st_size_offset+4], 0
jnz short infileerr
; 4g. Allocate memory for the input file.
mov [insize], edi
call malloc
test rax, rax
jz nomem
mov [infile], rax
; 4g. Read the input file to the allocated memory.
mov rdi, rax
push 1
pop rsi
mov edx, [r13+st_size_offset]
mov rcx, r12
call fread
; 4h. Test result; must be equal to file size.
cmp eax, [r13+st_size_offset]
jnz infileerr
; 4i. Close the input file.
mov rdi, r12
call fclose
; 5. Calculate maximum size of the output.
mov edi, [insize]
shr edi, 3
add edi, [insize]
add edi, 400h ; should be enough for header
mov r12d, edi
; 6. Allocate memory for two copies of maximum output.
; 6a. Do system call.
call malloc
; 6b. Test return value. If ok, goto 6d.
test rax, rax
jnz short outmemok
; 6c. No memory; say error and exit.
nomem:
push nomem_len
pop rdx
mov rsi, offset nomem_str
jmp write_exit
; 6d. Remember allocated memory address.
outmemok:
mov [outfile], rax
; 8. Determine and set lzma_dict_size.
push 18h
pop rdi
call lzma_set_dict_size
; 9. Allocate lzma_workmem.
mov edi, (1 shl 18h) * 19 / 2 + 509000h
call malloc
test rax, rax
jz nomem
mov [workmem], rax
; 10. Say another 'hi'.
push compressing_len
pop rdx
mov rsi, offset compressing_str
call write_string
; 11. Do work.
; find jump to 32-bit code
mov rdi, [infile]
dec rdi
@@:
inc rdi
cmp dword [rdi], 0E88EE08Eh ; mov fs,ax/mov gs,ax
jnz @b
cmp dword [rdi+4], 00BCD08Eh ; mov ss,ax/mov esp,00xxxxxx
jnz @b
add rdi, 11
mov [inptr], rdi
sub rdi, [infile]
mov [indelta], edi
mov eax, [insize]
mov ebx, eax
add eax, 0x10000
mov [loader_base+..loader_patch3+2], eax
sub ebx, edi
mov [insize], ebx
call preprocess_calltrick2
mov al, [cti]
mov [loader_base+loader_patch5-1], al
mov eax, [ctn]
mov [loader_base+loader_patch4+1], eax
mov esi, [indelta]
add rsi, [outfile]
add rsi, loader_size - 5
mov rdi, [inptr]
mov edx, [insize]
mov rcx, [workmem]
call lzma_compress
mov edx, [indelta]
add eax, loader_size-5
mov [loader_base+loader_patch1+6], eax
add eax, edx
mov [outsize], eax
mov eax, edx
add rax, [outfile]
mov ecx, [rax + loader_size - 4]
bswap ecx
mov [loader_base+loader_patch2+4], ecx
add edx, 0x10000
mov [loader_base+loader_patch1+1], edx
mov rsi, [infile]
mov rdi, [outfile]
mov ecx, [indelta]
rep movsb
mov rsi, loader_base
mov ecx, loader_size
rep movsb
mov eax, [outsize]
cmp eax, [insize]
jb short packed_ok
push too_big_len
pop rdx
mov rsi, offset too_big_str
jmp write_exit
packed_ok:
; 12. Main work is done. Free lzma_workmem.
mov rdi, [workmem]
call free
; 13. Set header
mov eax, [outsize]
mov ecx, 100
mul ecx
div [insize]
mov cl, 10
div cl
add ax, '00'
mov [ratio], ax
push done_len
pop rdx
mov rsi, offset done_str
call write_string
; 14. Save the output file.
; 14a. Do system call for open.
mov rdi, [outfilename]
mov rsi, create_mode
call fopen
; 14b. Test for success; if yes, goto 14d.
test rax, rax
jnz short @f
; 14c. Say error and exit.
outerr:
push outfileerr_len
pop rdx
mov rsi, offset outfileerr_str
jmp write_exit
; 14d. Do system call for write.
@@:
mov r12, rax
mov rdi, [outfile]
mov esi, [outsize]
push 1
pop rdx
mov rcx, r12
call fwrite
test eax, eax
jz short outerr
; 14e. Close output file.
mov rdi, r12
call fclose
; 15. Exit.
xor edi, edi
call exit
 
; Scan command line, skipping possible options, and return first non-option
; ecx is number of arguments left, rdi points to first new argument (updated by func)
; After the call: ZF set if no arguments left, otherwise rax points to the arg.
get_file_name:
; 1. Test whether there are still arguments. If no, goto 5; note ZF is set.
dec ecx
jz @@end
; 2. Get the new arg, advance rdi (ecx was decreased in step 1).
mov rax, [rdi]
add rdi, 8
; 5. No arguments (ZF set) or normal argument (ZF cleared); return.
@@end:
ret
 
pack_calltrick_fail:
xor eax, eax
xor ebx, ebx
mov [ctn], eax
ret
 
preprocess_calltrick2:
; restore input
mov rsi, [infile]
; input preprocessing
push rax
mov edi, [insize]
add edi, edi
call malloc
pop rcx
test rax, rax
jz pack_calltrick_fail
mov rdi, offset ct1
xchg rax, rbx
xor eax, eax
push rdi
mov ecx, 256/4
rep stosd
pop rdi
mov ecx, [insize]
mov rsi, [inptr]
xchg eax, edx
push rbx
input_pre2:
lodsb
@@:
cmp al, 0Fh
jnz short ip1
dec ecx
jz short input_pre_done2
lodsb
cmp al, 80h
jb short @b
cmp al, 90h
jb short @f
ip1:
sub al, 0E8h
cmp al, 1
ja short input_pre_cont2
@@:
cmp ecx, 5
jb short input_pre_done2
lodsd
add eax, esi
sub eax, dword ptr [inptr]
cmp eax, [insize]
jae short xxx2
cmp eax, 1000000h
jae short xxx2
sub ecx, 4
bswap eax
mov [rsi-4], eax
inc edx
mov [rbx], rsi
add rbx, 8
jmp short input_pre_cont2
xxx2: sub rsi, 4
movzx eax, byte ptr [rsi]
mov byte ptr [rax+rdi], 1
input_pre_cont2:
loop input_pre2
input_pre_done2:
mov [ctn], edx
pop rdx
xor eax, eax
mov ecx, 256
repnz scasb
jnz pack_calltrick_fail
not cl
mov [cti], cl
@@:
cmp rbx, rdx
jz @f
sub rbx, 8
mov rax, [rbx]
mov [rax-4], cl
jmp @b
@@:
push rax
mov rdi, rbx
call free
pop rax
ret
 
extrn exit
extrn fopen
extrn fread
extrn fwrite
extrn fclose
extrn fseek
extrn ftell
extrn malloc
extrn free
extrn write
extrn utimes
extrn stat
 
open_mode db "rb",0
create_mode db "wb",0
 
.data
 
loader_base:
use32
org 0
include 'loader_lzma.asm'
/programs/other/kpack/kerpack_linux/kpack64.asm
0,0 → 1,657
; kpack = Kolibri Packer
; Written by diamond in 2006 specially for KolibriOS
 
; Uses LZMA compression library by Igor Pavlov
; (for more information on LZMA and 7-Zip visit http://www.7-zip.org)
; (plain-C packer and ASM unpacker are ported by diamond)
 
;freebsd = 1 ;uncomment for FreeBSD-specific changes
 
format ELF64
public _start
.data? fix section ".bss" writeable align 4
.data fix section ".data" writeable align 4
.const fix section ".const" align 4
.code fix section ".text" executable align 16
offset fix
ptr fix
struc label type {
label . type }
 
extrn lzma_compress
extrn lzma_set_dict_size
 
.data?
infilename dq ?
outfilename dq ?
infile dq ?
outfile1 dq ?
outfile2 dq ?
outfile dq ?
outfilebest dq ?
workmem dq ?
insize dd ?
outsize dd ?
lzma_dictsize dd ?
dd ?
strucstat rq 18
 
if defined freebsd
st_atime_offset = 24
st_mtime_offset = 40
st_birthtime_offset = 104
st_size_offset = 72
else
st_atime_offset = 72
st_mtime_offset = 88
;st_birthtime_offset not defined
st_size_offset = 48
end if
 
timeval rq 2*2
public environ
environ dq ?
public __progname
__progname dq ?
ct1 db 256 dup (?)
ctn dd ?
cti db ?
 
.const
info_str db 'KPack - Kolibri Packer, version 0.11',13,10
db 'Uses LZMA v4.32 compression library',13,10,13,10
info_len = $ - offset info_str
usage_str db 'Written by diamond in 2006, 2007 specially for KolibriOS',13,10
db 'LZMA compression library is copyright (c) 1999-2005 by Igor Pavlov',13,10
db 13,10
db 'Usage: kpack [--nologo] <infile> [<outfile>]',13,10
usage_len = $ - offset usage_str
errload_str db 'Cannot load input file',13,10
errload_len = $ - offset errload_str
outfileerr_str db 'Cannot save output file',13,10
outfileerr_len = $ - offset outfileerr_str
nomem_str db 'No memory',13,10
nomem_len = $ - offset nomem_str
too_big_str db 'failed, output is greater than input.',13,10
too_big_len = $ - too_big_str
compressing_str db 'Compressing ... '
compressing_len = $ - compressing_str
 
.data
bNoLogo db 0
done_str db 'OK! Compression ratio: '
ratio dw '00'
db '%',13,10,13,10
done_len = $ - done_str
 
use_lzma = 1
 
use_no_calltrick = 0
use_calltrick1 = 40h
use_calltrick2 = 80h
 
method db 1
 
.code
; Write string from [rsi] of rdx bytes.
write_string:
; 1. Align stack on 16 bytes.
push rdi
; 2. Set rdi to 1 = descriptor for stdout.
xor edi, edi
inc edi
; 3. Do system call.
call write
; 4. Restore stack and return.
pop rdi
ret
 
; Write string from [rsi] of rdx bytes and exit. Note that main code jumps (not calls) here,
; so we should not align the stack.
write_exit:
; 1. Call prev func.
call write_string
; 2. Do system call for exit.
; Note that this can be used as independent proc jumped (not called) to.
doexit:
xor edi, edi
call exit
 
; Main procedure.
_start:
; 1. Parse command line.
; Linux: [rsp] = argc, rsp+8 = argv
; FreeBSD: [rdi] = argc, rdi+8 = argv
; 1a. Load argc and argv to registers,
; skip first argument (which is always program name)
if defined freebsd
mov ecx, [rdi] ; ecx = argc
add rdi, 16 ; rdi = &argv[1]
else
mov ecx, [rsp] ; ecx = argc
lea rdi, [rsp+16] ; rdi = &argv[1]
end if
; 1b. Test for first filename parameter. If no, goto step 2.
call get_file_name
jz usage
; 1c. We got input file name, save it.
; Assume that output file name is the same; if no, we will rewrite it in step 1d.
mov [infilename], rax
mov [outfilename], rax
; 1d. Test for second filename parameter. If yes, rewrite assumption in step 1c and check that there are no 3rd parameter.
call get_file_name
jz @f
mov [outfilename], rax
call get_file_name
jnz usage
@@:
; 1e. Parsing is done, process to step 3.
jmp short cont
; 2. No arguments or too many arguments given; write message and exit.
usage:
cmp [bNoLogo], 0
jnz doexit
push info_len + usage_len
pop rdx
mov rsi, offset info_str;usage_str
jmp write_exit
; 3. Say hello unless disabled with --nologo.
cont:
cmp [bNoLogo], 0
jnz @f
push info_len
pop rdx
mov rsi, info_str
call write_string
@@:
; 4. Load the input file.
; 4a. Do system call for stat - get file times and file size.
mov rdi, [infilename]
mov rsi, offset strucstat
mov r13, rsi
call stat
; 4b. Test result; if not 0 (0 is OK), goto 4e.
test rax, rax
jnz short infileerr
; 4c. Do system call for open.
mov rdi, [infilename]
mov rsi, offset open_mode
call fopen
; 4d. Test result; if not NULL, goto 4f.
test rax, rax
jnz short inopened
infileerr:
; 4e. Say error and abort.
push errload_len
pop rdx
mov rsi, offset errload_str
jmp write_exit
inopened:
mov r12, rax
; 4f. Check that the size is nonzero and less than 4G.
mov edi, [r13+st_size_offset]
test edi, edi
jz short infileerr
cmp dword [r13+st_size_offset+4], 0
jnz short infileerr
; 4g. Allocate memory for the input file.
mov [insize], edi
call malloc
test rax, rax
jz nomem
mov [infile], rax
; 4g. Read the input file to the allocated memory.
mov rdi, rax
push 1
pop rsi
mov edx, [r13+st_size_offset]
mov rcx, r12
call fread
; 4h. Test result; must be equal to file size.
cmp eax, [r13+st_size_offset]
jnz infileerr
; 4i. Close the input file.
mov rdi, r12
call fclose
; 5. Calculate maximum size of the output.
mov edi, [insize]
shr edi, 3
add edi, [insize]
add edi, 400h ; should be enough for header
mov r12d, edi
; 6. Allocate memory for two copies of maximum output.
; 6a. Do system call.
add edi, edi
call malloc
; 6b. Test return value. If ok, goto 6d.
test rax, rax
jnz short outmemok
; 6c. No memory; say error and exit.
nomem:
push nomem_len
pop rdx
mov rsi, offset nomem_str
jmp write_exit
; 6d. Remember allocated memory address.
outmemok:
mov [outfile], rax
mov [outfile1], rax
mov [outfilebest], rax
add rax, r12
mov [outfile2], rax
sub rax, r12
; 7. Initialize KPCK header.
mov dword ptr [rax], 'KPCK'
mov ecx, [insize]
mov dword ptr [rax+4], ecx
; 8. Determine and set lzma_dict_size.
dec ecx
bsr eax, ecx
inc eax
cmp eax, 28
jb short @f
mov eax, 28
@@:
push rax
mov edi, eax
call lzma_set_dict_size
pop rcx
mov edi, 1
shl edi, cl
mov [lzma_dictsize], edi
; 9. Allocate lzma_workmem.
imul edi, 19
shr edi, 1
add edi, 509000h
call malloc
test rax, rax
jz nomem
mov [workmem], rax
; 10. Say another 'hi'.
push compressing_len
pop rdx
mov rsi, offset compressing_str
call write_string
; 11. Do work.
mov rax, [outfile2]
mov [outfile], rax
xchg rax, rdi
mov rsi, [outfile1]
movsd
movsd
call pack_lzma
mov [outsize], eax
mov rax, [outfile]
mov [outfilebest], rax
mov [method], use_lzma
call preprocess_calltrick
test eax, eax
jz short noct1
call set_outfile
call pack_lzma
add eax, 5
cmp eax, [outsize]
jae short @f
mov [outsize], eax
mov rax, [outfile]
mov [outfilebest], rax
mov [method], use_lzma or use_calltrick1
@@:
noct1:
call set_outfile
push qword ptr [ctn]
push qword ptr [cti]
call preprocess_calltrick2
test eax, eax
jz noct2
call set_outfile
call pack_lzma
add eax, 5
cmp eax, [outsize]
jae short @f
mov [outsize], eax
mov rax, [outfile]
mov [outfilebest], rax
mov [method], use_lzma or use_calltrick2
pop rcx
pop rcx
push qword ptr [ctn]
push qword ptr [cti]
@@:
noct2:
pop rax
mov [cti], al
pop rax
mov [ctn], eax
add [outsize], 12
mov eax, [outsize]
cmp eax, [insize]
jb short packed_ok
push too_big_len
pop rdx
mov rsi, offset too_big_str
jmp write_exit
packed_ok:
; 12. Main work is done. Free lzma_workmem.
mov rdi, [workmem]
call free
; 13. Set header
movzx eax, [method]
mov rdi, [outfilebest]
mov [rdi+8], eax
test al, use_calltrick1 or use_calltrick2
jz short @f
mov ecx, [outsize]
add rcx, rdi
mov eax, [ctn]
mov [rcx-5], eax
mov al, [cti]
mov [rcx-1], al
@@:
mov eax, [outsize]
mov ecx, 100
mul ecx
div [insize]
mov cl, 10
div cl
add ax, '00'
mov [ratio], ax
push done_len
pop rdx
cmp [bNoLogo], 0
jz @f
sub dl, 2
@@:
mov rsi, offset done_str
call write_string
; 14. Save the output file.
; 14a. Do system call for open.
mov rdi, [outfilename]
mov rsi, create_mode
call fopen
; 14b. Test for success; if yes, goto 14d.
test rax, rax
jnz short @f
; 14c. Say error and exit.
outerr:
push outfileerr_len
pop rdx
mov rsi, offset outfileerr_str
jmp write_exit
; 14d. Do system call for write.
@@:
mov r12, rax
mov rdi, [outfilebest]
mov esi, [outsize]
push 1
pop rdx
mov rcx, r12
call fwrite
test eax, eax
jz short outerr
; 14e. Close output file.
mov rdi, r12
call fclose
; 14f. Set output file time from the input file.
; Do two system calls, one for birth time, one for modification time.
mov rdi, [outfilename]
mov rsi, timeval
mov rax, [r13+st_atime_offset]
mov [rsi], rax
mov rax, [r13+st_atime_offset+8]
mov [rsi+8], rax
if defined st_birthtime_offset
mov rax, [r13+st_birthtime_offset]
mov [rsi+16], rax
mov rax, [r13+st_birthtime_offset+8]
mov [rsi+24], rax
call utimes
mov rdi, [outfilename]
mov rsi, timeval
end if
mov rax, [r13+st_mtime_offset]
mov [rsi+16], rax
mov rax, [r13+st_mtime_offset+8]
mov [rsi+24], rax
call utimes
; 15. Exit.
xor edi, edi
call exit
 
; Scan command line, skipping possible options, and return first non-option
; ecx is number of arguments left, rdi points to first new argument (updated by func)
; After the call: ZF set if no arguments left, otherwise rax points to the arg.
get_file_name:
; 1. Test whether there are still arguments. If no, goto 5; note ZF is set.
dec ecx
jz @@end
; 2. Get the new arg, advance rdi (ecx was decreased in step 1).
mov rax, [rdi]
add rdi, 8
; 3. Test for --nologo option. If no, goto 5; note ZF is cleared.
cmp dword [rax], '--no'
jnz @@end
cmp dword [rax+4], 'logo'
jnz @@end
; 4. Remember that --nologo was given and continue from the beginning.
mov [bNoLogo], 1
jmp get_file_name
; 5. No arguments (ZF set) or normal argument (ZF cleared); return.
@@end:
ret
 
set_outfile:
mov rax, [outfilebest]
xor rax, [outfile1]
xor rax, [outfile2]
mov [outfile], rax
ret
 
pack_calltrick_fail:
xor eax, eax
xor ebx, ebx
mov [ctn], eax
ret
preprocess_calltrick:
; input preprocessing
push rax
mov edi, [insize]
add edi, edi
call malloc
pop rcx
test rax, rax
jz pack_calltrick_fail
push rax
xor eax, eax
mov rdi, offset ct1
mov ecx, 256/4
push rdi
rep stosd
pop rdi
mov ecx, [insize]
mov rsi, [infile]
xchg eax, edx
pop rax
xchg rax, rbx
push rbx
input_pre:
lodsb
sub al, 0E8h
cmp al, 1
ja short input_pre_cont
cmp ecx, 5
jb short input_pre_done
lodsd
add eax, esi
sub eax, dword ptr [infile]
cmp eax, [insize]
jae short xxx
cmp eax, 1000000h
jae short xxx
sub ecx, 4
bswap eax
mov [rsi-4], eax
inc edx
mov [rbx], rsi
add rbx, 8
jmp short input_pre_cont
xxx: sub rsi, 4
movzx eax, byte ptr [rsi]
mov byte ptr [rax+rdi], 1
input_pre_cont:
loop input_pre
input_pre_done:
mov [ctn], edx
pop rdx
xor eax, eax
mov ecx, 256
repnz scasb
jnz pack_calltrick_fail
not cl
mov [cti], cl
@@:
cmp rbx, rdx
jz @f
sub rbx, 8
mov rax, [rbx]
mov [rax-4], cl
jmp @b
@@:
push rax
mov rdi, rbx
call free
pop rax
ret
 
pack_lzma:
push rcx
mov rdi, [infile]
mov rsi, [outfile]
add rsi, 11
mov edx, [insize]
mov rcx, [workmem]
call lzma_compress
pop rcx
mov rcx, [outfile]
mov edx, [rcx+12]
bswap edx
mov [rcx+12], edx
dec eax
ret
 
preprocess_calltrick2:
; restore input
mov rsi, [infile]
mov ecx, [ctn]
jecxz pc2l2
pc2l1:
lodsb
sub al, 0E8h
cmp al, 1
ja short pc2l1
mov al, [cti]
cmp [rsi], al
jnz short pc2l1
lodsd
mov al, 0
bswap eax
sub eax, esi
add eax, dword ptr [infile]
mov [rsi-4], eax
loop pc2l1
pc2l2:
; input preprocessing
push rax
mov edi, [insize]
add edi, edi
call malloc
pop rcx
test rax, rax
jz pack_calltrick_fail
mov rdi, offset ct1
xchg rax, rbx
xor eax, eax
push rdi
mov ecx, 256/4
rep stosd
pop rdi
mov ecx, [insize]
mov rsi, [infile]
xchg eax, edx
push rbx
input_pre2:
lodsb
@@:
cmp al, 0Fh
jnz short ip1
dec ecx
jz short input_pre_done2
lodsb
cmp al, 80h
jb short @b
cmp al, 90h
jb short @f
ip1:
sub al, 0E8h
cmp al, 1
ja short input_pre_cont2
@@:
cmp ecx, 5
jb short input_pre_done2
lodsd
add eax, esi
sub eax, dword ptr [infile]
cmp eax, [insize]
jae short xxx2
cmp eax, 1000000h
jae short xxx2
sub ecx, 4
bswap eax
mov [rsi-4], eax
inc edx
mov [rbx], rsi
add rbx, 8
jmp short input_pre_cont2
xxx2: sub rsi, 4
movzx eax, byte ptr [rsi]
mov byte ptr [rax+rdi], 1
input_pre_cont2:
loop input_pre2
input_pre_done2:
mov [ctn], edx
pop rdx
xor eax, eax
mov ecx, 256
repnz scasb
jnz pack_calltrick_fail
not cl
mov [cti], cl
@@:
cmp rbx, rdx
jz @f
sub rbx, 8
mov rax, [rbx]
mov [rax-4], cl
jmp @b
@@:
push rax
mov rdi, rbx
call free
pop rax
ret
 
extrn exit
extrn fopen
extrn fread
extrn fwrite
extrn fclose
extrn fseek
extrn ftell
extrn malloc
extrn free
extrn write
extrn utimes
extrn stat
 
open_mode db "rb",0
create_mode db "wb",0
/programs/other/kpack/kerpack_linux/loader_lzma.asm
0,0 → 1,404
loader_start:
; start address; this code will be injected after the init code
; (some commands below "B32" in the kernel)
mov edi, 0x280000
lea ebx, [edi+loader_size1+16]
lea edx, [ebx+4]
loader_patch1:
mov esi, 0 ; will be patched: start address to copy
mov ecx, 0 ; will be patched: size of data to copy
push esi
rep movsb
jmp edx
loader_size1 = $ - loader_start
 
loader_patch2:
dd 0x280000 + loader_size
dd 0 ; will be patched: start value for code
; (LZMA-specific)
dd -1
dd _RangeDecoderBitDecode_edx - loader_start + 0x280000
dd _RangeDecoderBitDecode - loader_start + 0x280000
RangeDecoderBitDecode equ dword [ebx]
RangeDecoderBitDecode_edx equ dword [ebx-4]
code_ equ ebx-12
range equ ebx-8
 
rep1 equ ebx-28
rep2 equ ebx-24
rep3 equ ebx-20
inptr_ldr equ ebx-16
 
pb equ 0 ; pos state bits
lp equ 0 ; literal pos state bits
lc equ 3 ; literal context bits
posStateMask equ ((1 shl pb)-1)
literalPosMask equ ((1 shl lp)-1)
 
kNumPosBitsMax = 4
kNumPosStatesMax = (1 shl kNumPosBitsMax)
 
kLenNumLowBits = 3
kLenNumLowSymbols = (1 shl kLenNumLowBits)
kLenNumMidBits = 3
kLenNumMidSymbols = (1 shl kLenNumMidBits)
kLenNumHighBits = 8
kLenNumHighSymbols = (1 shl kLenNumHighBits)
 
LenChoice = 0
LenChoice2 = 1
LenLow = 2
LenMid = (LenLow + (kNumPosStatesMax shl kLenNumLowBits))
LenHigh = (LenMid + (kNumPosStatesMax shl kLenNumMidBits))
kNumLenProbs = (LenHigh + kLenNumHighSymbols)
 
kNumStates = 12
kNumLitStates = 7
kStartPosModelIndex = 4
kEndPosModelIndex = 14
kNumFullDistances = (1 shl (kEndPosModelIndex/2))
kNumPosSlotBits = 6
kNumLenToPosStates = 4
kNumAlignBits = 4
kAlignTableSize = (1 shl kNumAlignBits)
kMatchMinLen = 2
 
IsMatch = 0
IsRep = 0xC0 ; (IsMatch + (kNumStates shl kNumPosBitsMax))
IsRepG0 = 0xCC ; (IsRep + kNumStates)
IsRepG1 = 0xD8 ; (IsRepG0 + kNumStates)
IsRepG2 = 0xE4 ; (IsRepG1 + kNumStates)
IsRep0Long = 0xF0 ; (IsRepG2 + kNumStates)
PosSlot = 0x1B0 ; (IsRep0Long + (kNumStates shl kNumPosBitsMax))
SpecPos = 0x2B0 ; (PosSlot + (kNumLenToPosStates shl kNumPosSlotBits))
Align_ = 0x322 ; (SpecPos + kNumFullDistances - kEndPosModelIndex)
Lencoder = 0x332 ; (Align_ + kAlignTableSize)
RepLencoder = 0x534 ; (Lencoder + kNumLenProbs)
Literal = 0x736 ; (RepLencoder + kNumLenProbs)
 
LZMA_BASE_SIZE = 1846 ; must be ==Literal
LZMA_LIT_SIZE = 768
 
kNumTopBits = 24
kTopValue = (1 shl kNumTopBits)
 
kNumBitModelTotalBits = 11
kBitModelTotal = (1 shl kNumBitModelTotalBits)
kNumMoveBits = 5
 
uninit_base = 2C0000h
 
p = uninit_base
 
unpacker:
xor ebp, ebp
xor eax, eax
dec eax
lea edi, [rep1]
stosd
stosd
stosd
xchg eax, esi
; mov ecx, Literal + (LZMA_LIT_SIZE shl (lc+lp))
mov ch, (Literal + (LZMA_LIT_SIZE shl (lc+lp)) + 0xFF) shr 8
mov eax, kBitModelTotal/2
mov edi, p
rep stosd
pop edi
push edi
.main_loop:
..loader_patch3:
cmp edi, dword 0 ; will be patched: end of data to unpack
jae .main_loop_done
if posStateMask
mov edx, edi
and edx, posStateMask
else
xor edx, edx
end if
push eax ; al = previous byte
lea eax, [ebp + ((p+IsMatch*4) shr (kNumPosBitsMax+2))]
shl eax, kNumPosBitsMax+2
if posStateMask
call RangeDecoderBitDecode_edx
else
call RangeDecoderBitDecode
end if
pop eax
jc .1
movzx eax, al
if literalPosMask
mov ah, dl
and ah, literalPosMask
end if
if ((LZMA_LIT_SIZE*4) and ((1 shl (8-lc)) - 1)) <> 0
shr eax, 8-lc
imul eax, LZMA_LIT_SIZE*4
else
and al, not ((1 shl (8-lc)) - 1)
imul eax, (LZMA_LIT_SIZE*4) shr (8-lc)
end if
add eax, p+Literal*4
mov dl, 1
cmp ebp, kNumLitStates
jb .literal
mov cl, [edi + esi]
.lx0:
add cl, cl
adc dh, 1
call RangeDecoderBitDecode_edx
adc dl, dl
jc .lx1
xor dh, dl
test dh, 1
mov dh, 0
jnz .lx0
.literal:
@@:
call RangeDecoderBitDecode_edx
adc dl, dl
jnc @b
.lx1:
mov eax, ebp
cmp al, 4
jb @f
cmp al, 10
mov al, 3
jb @f
mov al, 6
@@: sub ebp, eax
xchg eax, edx
.stosb_main_loop:
stosb
jmp .main_loop
.1:
lea eax, [p + IsRep*4 + ebp*4]
call RangeDecoderBitDecode
jnc .10
add eax, (IsRepG0 - IsRep)*4 ;lea eax, [p + IsRepG0*4 + ebp*4]
call RangeDecoderBitDecode
jc .111
mov eax, ebp
shl eax, kNumPosBitsMax+2
add eax, p + IsRep0Long*4
call RangeDecoderBitDecode_edx
jc .1101
cmp ebp, 7
sbb ebp, ebp
lea ebp, [ebp+ebp+11]
mov al, [edi + esi]
jmp .stosb_main_loop
.111:
add eax, (IsRepG1 - IsRepG0) * 4 ;lea eax, [p + IsRepG1*4 + ebp*4]
call RangeDecoderBitDecode
xchg esi, [rep1]
jnc @f
add eax, (IsRepG2 - IsRepG1) * 4 ;lea eax, [p + IsRepG2*4 + ebp*4]
call RangeDecoderBitDecode
xchg esi, [rep2]
jnc @f
xchg esi, [rep3]
@@:
.1101:
mov eax, p + RepLencoder*4
call LzmaLenDecode
push 8
jmp .rmu
.10:
xchg esi, [rep1]
xchg esi, [rep2]
mov [rep3], esi
mov eax, p + Lencoder*4
call LzmaLenDecode
push kNumLenToPosStates-1
pop edx
cmp edx, ecx
jb @f
mov edx, ecx
@@:
push ecx
push kNumPosSlotBits
pop ecx
mov eax, p+PosSlot*4
shl edx, cl
call RangeDecoderBitTreeDecode
mov esi, ecx
cmp ecx, kStartPosModelIndex
jb .l6
mov edx, ecx
xor eax, eax
shr ecx, 1
adc al, 2
dec ecx
shl eax, cl
mov esi, eax
sub eax, edx
lea eax, [p + (SpecPos - 1)*4 + eax*4]
cmp edx, kEndPosModelIndex
jb .l59
; call RangeDecoderDecodeDirectBits
;RangeDecoderDecodeDirectBits:
xor eax, eax
.l:
shr dword [range], 1
add eax, eax
mov edx, [code_]
sub edx, [range]
jb @f
mov [code_], edx
add al, 1 shl kNumAlignBits
@@:
call update_decoder
dec ecx
cmp ecx, kNumAlignBits
jnz .l
; ret
add esi, eax
mov eax, p+Align_*4
.l59:
; call RangeDecoderReverseBitTreeDecode_addesi
;_RangeDecoderReverseBitTreeDecode_addesi:
; in: eax->probs,ecx=numLevels
; out: esi+=length; destroys edx
push edi
xor edx, edx
inc edx
mov edi, edx
@@:
call RangeDecoderBitDecode_edx
jnc .591
add esi, edi
stc
.591:
adc edx, edx
add edi, edi
loop @b
pop edi
; ret
.l6:
pop ecx
not esi
push 7
.rmu:
cmp ebp, 7
pop ebp
jb @f
add ebp, 3
@@:
.repmovsb:
inc ecx
push esi
add esi, edi
rep movsb
lodsb
pop esi
jmp .stosb_main_loop
.main_loop_done:
include 'calltrick2.asm'
ret
 
_RangeDecoderBitDecode:
; in: eax->prob
; out: CF=bit
push edx
mov edx, [range]
shr edx, kNumBitModelTotalBits
imul edx, [eax]
cmp [code_], edx
jae .ae
mov [range], edx
mov edx, kBitModelTotal
sub edx, [eax]
shr edx, kNumMoveBits
add [eax], edx
.n:
pushfd
call update_decoder
popfd
pop edx
ret
.ae:
sub [range], edx
sub [code_], edx
mov edx, [eax]
shr edx, kNumMoveBits
sub [eax], edx
stc
jmp .n
 
update_decoder:
cmp byte [range+3], 0 ;cmp dword [range], kTopValue
jnz @f ;jae @f
shl dword [range], 8
shl dword [code_], 8
push eax
mov eax, [inptr_ldr]
mov al, [eax]
inc dword [inptr_ldr]
mov byte [code_], al
pop eax
@@: ret
 
_RangeDecoderBitDecode_edx:
push eax
lea eax, [eax+edx*4]
call RangeDecoderBitDecode
pop eax
ret
 
LzmaLenDecode:
; in: eax->prob, edx=posState
; out: ecx=len
 
; LenChoice==0
; add eax, LenChoice*4
if kLenNumMidBits <> kLenNumLowBits
error in optimization
end if
mov cl, kLenNumMidBits
call RangeDecoderBitDecode
jnc .0
add eax, (LenChoice2-LenChoice)*4
call RangeDecoderBitDecode
jc @f
if (kLenNumMidBits <> 3) | (LenMid-LenChoice2 > 0x7F + kLenNumMidBits)
shl edx, cl
add edx, LenMid-LenChoice2
else
lea edx, [ecx + edx*8 - kLenNumMidBits + LenMid-LenChoice2]
end if
push kLenNumLowSymbols
jmp RangeDecoderBitTreeDecode.1
@@:
mov edx, LenHigh-LenChoice2
mov cl, kLenNumHighBits
push kLenNumLowSymbols + kLenNumMidSymbols
jmp RangeDecoderBitTreeDecode.1
.0:
shl edx, cl
if LenLow = 2
inc edx
inc edx
else
add edx, LenLow
end if
RangeDecoderBitTreeDecode:
; in: eax+edx*4->probs,ecx=numLevels
; out: ecx=length; destroys edx
push 0
.1:
lea eax, [eax+edx*4]
xor edx, edx
inc edx
push ecx
@@:
call RangeDecoderBitDecode_edx
adc edx, edx
loop @b
pop ecx
btc edx, ecx
pop ecx
add ecx, edx
ret
 
loader_size = $ - loader_start
/programs/other/kpack/kerpack_linux/lzma_c/LZMAEncoder.c
0,0 → 1,1078
#include "LZMAEncoder.h"
#include "MatchFinder.h"
 
const byte kLiteralNextStates[kNumStates] = {0,0,0,0,1,2,3,4,5,6,4,5};
const byte kMatchNextStates[kNumStates] = {7,7,7,7,7,7,7,10,10,10,10,10};
const byte kRepNextStates[kNumStates] = {8,8,8,8,8,8,8,11,11,11,11,11};
const byte kShortRepNextStates[kNumStates] = {9,9,9,9,9,9,9,11,11,11,11,11};
 
static CState _state;
static byte _previousByte;
static unsigned _repDistances[kNumRepDistances];
 
static COptimal _optimum[kNumOpts];
static CMyBitEncoder _isMatch[kNumStates][kNumPosStatesEncodingMax];
static CMyBitEncoder _isRep[kNumStates];
static CMyBitEncoder _isRepG0[kNumStates];
static CMyBitEncoder _isRepG1[kNumStates];
static CMyBitEncoder _isRepG2[kNumStates];
static CMyBitEncoder _isRep0Long[kNumStates][kNumPosStatesEncodingMax];
static NRangeCoder_CBitTreeEncoder _posSlotEncoder[kNumLenToPosStates];
static CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
static NRangeCoder_CBitTreeEncoder _posAlignEncoder;
static NLength_CPriceTableEncoder _lenEncoder;
static NLength_CPriceTableEncoder _repMatchLenEncoder;
static CLiteralEncoder _literalEncoder;
static unsigned _matchDistances[kMatchMaxLen+1];
static unsigned _numFastBytes;
static unsigned _longestMatchLength;
static unsigned _additionalOffset;
static unsigned _optimumEndIndex;
static unsigned _optimumCurrentIndex;
static bool _longestMatchWasFound;
static unsigned _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
static unsigned _distancesPrices[kNumLenToPosStates][kNumFullDistances];
static unsigned _alignPrices[kAlignTableSize];
static unsigned _alignPriceCount;
static unsigned _distTableSize;
static unsigned _posStateBits;
static unsigned _posStateMask;
static unsigned _numLiteralPosStateBits;
static unsigned _numLiteralContextBits;
static unsigned _dictionarySize;
static uint64 lastPosSlotFillingPos;
static uint64 nowPos64;
static bool _finished;
static bool _writeEndMark;
 
static byte g_FastPos[1024];
 
// must be called before work
static void FastPosInit(void)
{
int c = 2;
int slotFast;
unsigned j,k;
g_FastPos[0] = 0;
g_FastPos[1] = 1;
for (slotFast = 2; slotFast < 20; slotFast++)
{
k = (1 << ((slotFast >> 1) - 1));
for (j=0;j<k;j++) g_FastPos[c++] = slotFast;
}
}
static unsigned GetPosSlot(unsigned pos)
{
if (pos < (1<<10))
return g_FastPos[pos];
if (pos < (1<<19))
return g_FastPos[pos>>9]+18;
return g_FastPos[pos>>18]+36;
}
static unsigned GetPosSlot2(unsigned pos)
{
if (pos < (1<<16))
return g_FastPos[pos>>6]+12;
if (pos < (1<<25))
return g_FastPos[pos>>15]+30;
return g_FastPos[pos>>24]+48;
}
 
unsigned pack_length;
unsigned pack_pos;
const byte* curin;
byte* curout;
 
static void NLength_CEncoder_Init(NLength_CEncoder*e, unsigned numPosStates)
{
unsigned posState;
CMyBitEncoder_Init(e->_choice);
CMyBitEncoder_Init(e->_choice2);
for (posState=0;posState<numPosStates;posState++)
{
CBitTreeEncoder_Init(&e->_lowCoder[posState],kNumLowBits);
CBitTreeEncoder_Init(&e->_midCoder[posState],kNumMidBits);
}
CBitTreeEncoder_Init(&e->_highCoder,kNumHighBits);
}
 
static void NLength_CEncoder_Encode(NLength_CEncoder*e, unsigned symbol, unsigned posState)
{
if (symbol < kNumLowSymbols)
{
CMyBitEncoder_Encode(&e->_choice,0);
CBitTreeEncoder_Encode(&e->_lowCoder[posState],symbol);
}
else
{
CMyBitEncoder_Encode(&e->_choice,1);
if (symbol < kNumLowSymbols + kNumMidSymbols)
{
CMyBitEncoder_Encode(&e->_choice2,0);
CBitTreeEncoder_Encode(&e->_midCoder[posState],symbol-kNumLowSymbols);
}
else
{
CMyBitEncoder_Encode(&e->_choice2,1);
CBitTreeEncoder_Encode(&e->_highCoder,symbol-kNumLowSymbols-kNumMidSymbols);
}
}
}
 
static unsigned NLength_CEncoder_GetPrice(NLength_CEncoder*e, unsigned symbol, unsigned posState)
{
unsigned price;
if (symbol < kNumLowSymbols)
return CMyBitEncoder_GetPrice0(&e->_choice) +
CBitTreeEncoder_GetPrice(&e->_lowCoder[posState],symbol);
price = CMyBitEncoder_GetPrice1(&e->_choice);
if (symbol < kNumLowSymbols + kNumMidSymbols)
{
price += CMyBitEncoder_GetPrice0(&e->_choice2);
price += CBitTreeEncoder_GetPrice(&e->_midCoder[posState],symbol-kNumLowSymbols);
}
else
{
price += CMyBitEncoder_GetPrice1(&e->_choice2);
price += CBitTreeEncoder_GetPrice(&e->_highCoder,symbol-kNumLowSymbols-kNumMidSymbols);
}
return price;
}
 
static void CPriceTableEncoder_SetTableSize(NLength_CPriceTableEncoder*pte,unsigned tableSize)
{pte->_tableSize = tableSize;}
static unsigned CPriceTableEncoder_GetPrice(NLength_CPriceTableEncoder*pte,unsigned symbol,unsigned posState)
{return pte->_prices[symbol][posState];}
static void CPriceTableEncoder_UpdateTable(NLength_CPriceTableEncoder*pte,unsigned posState)
{
unsigned len;
for (len=0;len<pte->_tableSize;len++)
pte->_prices[len][posState] = NLength_CEncoder_GetPrice(&pte->base,len,posState);
pte->_counters[posState] = pte->_tableSize;
}
static void CPriceTableEncoder_UpdateTables(NLength_CPriceTableEncoder*pte,unsigned numPosStates)
{
unsigned posState;
for (posState=0;posState<numPosStates;posState++)
CPriceTableEncoder_UpdateTable(pte,posState);
}
static void CPriceTableEncoder_Encode(NLength_CPriceTableEncoder*pte, unsigned symbol, unsigned posState)
{
NLength_CEncoder_Encode(&pte->base,symbol,posState);
if (--pte->_counters[posState] == 0)
CPriceTableEncoder_UpdateTable(pte,posState);
}
 
static void CBaseState_Init(void)
{
unsigned i;
CState_Init(_state);
_previousByte = 0;
for (i=0;i<kNumRepDistances;i++)
_repDistances[i] = 0;
}
 
static void CLiteralEncoder2_Init(CLiteralEncoder2 le)
{
int i;
for (i=0;i<0x300;i++)
CMyBitEncoder_Init(le[i]);
}
 
static void CLiteralEncoder2_Encode(CLiteralEncoder2 le, byte symbol)
{
unsigned context = 1;
int i;
unsigned bit;
for (i=8;i--;)
{
bit = (symbol >> i) & 1;
CMyBitEncoder_Encode(&le[context],bit);
context = (context << 1) | bit;
}
}
 
static void CLiteralEncoder2_EncodeMatched(CLiteralEncoder2 le, byte matchByte, byte symbol)
{
unsigned context = 1;
int i;
unsigned bit,matchBit;
for (i=8;i--;)
{
bit = (symbol >> i) & 1;
matchBit = (matchByte >> i) & 1;
CMyBitEncoder_Encode(&le[0x100 + (matchBit<<8) + context],bit);
context = (context << 1) | bit;
if (matchBit != bit)
{
while (i--)
{
bit = (symbol >> i) & 1;
CMyBitEncoder_Encode(&le[context],bit);
context = (context << 1) | bit;
}
break;
}
}
}
 
static unsigned CLiteralEncoder2_GetPrice(CLiteralEncoder2 le, bool matchMode, byte matchByte, byte symbol)
{
unsigned price = 0;
unsigned context = 1;
unsigned bit,matchBit;
int i = 8;
if (matchMode)
{
do
{
i--;
matchBit = (matchByte >> i) & 1;
bit = (symbol >> i) & 1;
price += CMyBitEncoder_GetPrice(&le[0x100 + (matchBit<<8) + context],bit);
context = (context << 1) | bit;
if (matchBit != bit)
break;
} while (i);
}
while (i--)
{
bit = (symbol >> i) & 1;
price += CMyBitEncoder_GetPrice(&le[context],bit);
context = (context << 1) | bit;
}
return price;
}
 
static void WriteEndMarker(unsigned posState)
{
unsigned posSlot;
if (!_writeEndMark)
return;
CMyBitEncoder_Encode(&_isMatch[_state][posState],1);
CMyBitEncoder_Encode(&_isRep[_state],0);
CState_UpdateMatch(_state);
CPriceTableEncoder_Encode(&_lenEncoder,0,posState);
posSlot = (1<<kNumPosSlotBits) - 1;
CBitTreeEncoder_Encode(&_posSlotEncoder[GetLenToPosState(kMatchMinLen)],posSlot);
RangeEncoder_EncodeDirectBits(((1<<30)-1)>>kNumAlignBits,30-kNumAlignBits);
CBitTreeEncoder_ReverseEncode(&_posAlignEncoder,((1<<30)-1) & kAlignMask);
}
 
static void CEncoder_Flush(void)
{
WriteEndMarker((unsigned)nowPos64 & _posStateMask);
RangeEncoder_FlushData();
}
 
static void CLiteralEncoder_Create(CLiteralEncoder*le, byte** memory, int numPosBits, int numPrevBits)
{
unsigned numStates;
le->_coders = (CLiteralEncoder2*)*memory;
numStates = 1 << (numPosBits+numPrevBits);
*memory = (byte*)(le->_coders + numStates);
le->_numPosBits = numPosBits;
le->_posMask = (1<<numPosBits) - 1;
le->_numPrevBits = numPrevBits;
}
 
static void CLiteralEncoder_Init(CLiteralEncoder*le)
{
unsigned numStates,i;
numStates = 1 << (le->_numPosBits + le->_numPrevBits);
for (i=0;i<numStates;i++)
CLiteralEncoder2_Init(le->_coders[i]);
}
 
static unsigned CLiteralEncoder_GetState(CLiteralEncoder*le,unsigned pos,byte prevByte)
{return ((pos&le->_posMask)<<le->_numPrevBits)+(prevByte>>(8-le->_numPrevBits));}
static CLiteralEncoder2* CLiteralEncoder_GetSubCoder(CLiteralEncoder*le,unsigned pos,byte prevByte)
{return &le->_coders[CLiteralEncoder_GetState(le,pos,prevByte)];}
 
static unsigned CLiteralEncoder_GetPrice(CLiteralEncoder*le,unsigned pos,byte prevByte,
bool matchMode, byte matchByte, byte symbol)
{
return CLiteralEncoder2_GetPrice(le->_coders[CLiteralEncoder_GetState(le,pos,prevByte)],
matchMode, matchByte, symbol);
}
 
static void CEncoder_Create(void*workmem)
{
byte* workpos = (byte*)workmem;
/* align on dword boundary */
unsigned a;
a = (unsigned)workpos & 3;
if (a) workpos += 4-a;
/* sizeof(CLiteralEncoder2) * (1<<(numPosBits+numPrevBits)) for literal encoders */
/* = 0xC00 * 8 = 0x6000 with current settings */
CLiteralEncoder_Create(&_literalEncoder,&workpos,_numLiteralPosStateBits,_numLiteralContextBits);
/* (dictsize+0x1223)*1.5+256 for LZ input window */
/* (0x140400 + (dictsize+1)*2) * 4 for match finder hash */
MatchFinder_Create(_dictionarySize,kNumOpts,_numFastBytes,
kMatchMaxLen*2+1-_numFastBytes,&workpos);
/* total 0x508C3C + dictsize*9.5 */
/* plus max 6 bytes for alignment */
}
 
static void CEncoder_Init(void)
{
int i;
unsigned j;
CBaseState_Init();
RangeEncoder_Init();
for (i=0;i<kNumStates;i++)
{
for (j=0;j<=_posStateMask;j++)
{
CMyBitEncoder_Init(_isMatch[i][j]);
CMyBitEncoder_Init(_isRep0Long[i][j]);
}
CMyBitEncoder_Init(_isRep[i]);
CMyBitEncoder_Init(_isRepG0[i]);
CMyBitEncoder_Init(_isRepG1[i]);
CMyBitEncoder_Init(_isRepG2[i]);
}
CLiteralEncoder_Init(&_literalEncoder);
for (i=0;i<kNumLenToPosStates;i++)
CBitTreeEncoder_Init(_posSlotEncoder+i,kNumPosSlotBits);
for (i=0;i<kNumFullDistances-kEndPosModelIndex;i++)
CMyBitEncoder_Init(_posEncoders[i]);
CPriceTableEncoder_Init(_lenEncoder, 1<<_posStateBits);
CPriceTableEncoder_Init(_repMatchLenEncoder,1<<_posStateBits);
CBitTreeEncoder_Init(&_posAlignEncoder,kNumAlignBits);
_longestMatchWasFound = false;
_optimumEndIndex = 0;
_optimumCurrentIndex = 0;
_additionalOffset = 0;
}
 
static void MovePos(unsigned num)
{
for (;num--;)
{
DummyLongestMatch();
MatchFinder_MovePos();
_additionalOffset++;
}
}
 
static unsigned Backward(unsigned* backRes, unsigned cur)
{
unsigned posMem,backMem;
unsigned posPrev,backCur;
_optimumEndIndex = cur;
posMem = _optimum[cur].PosPrev;
backMem = _optimum[cur].BackPrev;
do
{
if (_optimum[cur].Prev1IsChar)
{
COptimal_MakeAsChar(&_optimum[posMem]);
_optimum[posMem].PosPrev = posMem-1;
if (_optimum[cur].Prev2)
{
_optimum[posMem-1].Prev1IsChar = false;
_optimum[posMem-1].PosPrev = _optimum[cur].PosPrev2;
_optimum[posMem-1].BackPrev = _optimum[cur].BackPrev2;
}
}
posPrev = posMem;
backCur = backMem;
backMem = _optimum[posPrev].BackPrev;
posMem = _optimum[posPrev].PosPrev;
_optimum[posPrev].BackPrev = backCur;
_optimum[posPrev].PosPrev = cur;
cur = posPrev;
} while (cur);
*backRes = _optimum[0].BackPrev;
_optimumCurrentIndex = _optimum[0].PosPrev;
return _optimumCurrentIndex;
}
 
static unsigned ReadMatchDistances(void)
{
unsigned res;
res = GetLongestMatch(_matchDistances);
if (res == _numFastBytes)
res += GetMatchLen(res,_matchDistances[res],kMatchMaxLen-res);
_additionalOffset++;
MatchFinder_MovePos();
return res;
}
 
static void FillPosSlotPrices(void)
{
unsigned lenToPosState,posSlot;
for (lenToPosState=0;lenToPosState<kNumLenToPosStates;lenToPosState++)
{
for (posSlot=0;posSlot<kEndPosModelIndex && posSlot<_distTableSize;posSlot++)
_posSlotPrices[lenToPosState][posSlot] = CBitTreeEncoder_GetPrice(&_posSlotEncoder[lenToPosState],posSlot);
for (;posSlot<_distTableSize;posSlot++)
_posSlotPrices[lenToPosState][posSlot] = CBitTreeEncoder_GetPrice(&_posSlotEncoder[lenToPosState],posSlot) +
(((posSlot>>1)-1-kNumAlignBits)<<kNumBitPriceShiftBits);
}
}
 
static void FillDistancesPrices(void)
{
unsigned lenToPosState,i;
unsigned posSlot,footerBits,base;
for (lenToPosState=0;lenToPosState<kNumLenToPosStates;lenToPosState++)
{
for (i=0;i<kStartPosModelIndex;i++)
_distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][i];
for (;i<kNumFullDistances;i++)
{
posSlot = GetPosSlot(i);
footerBits = ((posSlot>>1)-1);
base = (2|(posSlot&1))<<footerBits;
_distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][posSlot] +
ReverseBitTreeGetPrice(_posEncoders+base-posSlot-1,footerBits,i-base);
}
}
}
 
static void FillAlignPrices(void)
{
unsigned i;
for (i=0;i<kAlignTableSize;i++)
_alignPrices[i] = CBitTreeEncoder_ReverseGetPrice(&_posAlignEncoder,i);
_alignPriceCount = kAlignTableSize;
}
 
static unsigned GetRepLen1Price(CState state, unsigned posState)
{
return CMyBitEncoder_GetPrice0(&_isRepG0[state]) +
CMyBitEncoder_GetPrice0(&_isRep0Long[state][posState]);
}
static unsigned GetRepPrice(unsigned repIndex, unsigned len, CState state, unsigned posState)
{
unsigned price;
price = CPriceTableEncoder_GetPrice(&_repMatchLenEncoder,len-kMatchMinLen,posState);
if (!repIndex)
{
price += CMyBitEncoder_GetPrice0(&_isRepG0[state]);
price += CMyBitEncoder_GetPrice1(&_isRep0Long[state][posState]);
}
else
{
price += CMyBitEncoder_GetPrice1(&_isRepG0[state]);
if (repIndex == 1)
price += CMyBitEncoder_GetPrice0(&_isRepG1[state]);
else
{
price += CMyBitEncoder_GetPrice1(&_isRepG1[state]);
price += CMyBitEncoder_GetPrice(&_isRepG2[state],repIndex-2);
}
}
return price;
}
static unsigned GetPosLenPrice(unsigned pos, unsigned len, unsigned posState)
{
unsigned price,lenToPosState;
if (len==2 && pos>=0x80)
return kIfinityPrice;
lenToPosState = GetLenToPosState(len);
if (pos < kNumFullDistances)
price = _distancesPrices[lenToPosState][pos];
else
price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
_alignPrices[pos & kAlignMask];
return price + CPriceTableEncoder_GetPrice(&_lenEncoder,len-kMatchMinLen,posState);
}
 
static void GetOptimum(unsigned position,unsigned*backRes,unsigned*lenRes)
{
int lenMain,lenEnd;
COptimal* opt,*prevOpt;
int reps[kNumRepDistances];
int repLens[kNumRepDistances];
int repIndex,repMaxIndex;
int i,len,repLen,lenTest,newLen,lenTestTemp,lenTest2;
int posState,posStateNext;
byte currentByte,matchByte;
unsigned matchPrice,repMatchPrice,shortRepPrice,normalMatchPrice,curAndLenPrice,curPrice,curAnd1Price,curAndLenCharPrice;
unsigned nextMatchPrice,nextRepMatchPrice;
int cur,posPrev,pos;
CState state,state2;
const byte* data;
bool nextIsChar;
int numAvailableBytesFull,numAvailableBytes;
int backOffset,offset;
int limit;
if (_optimumEndIndex != _optimumCurrentIndex)
{
opt = &_optimum[_optimumCurrentIndex];
*lenRes = opt->PosPrev - _optimumCurrentIndex;
*backRes = opt->BackPrev;
_optimumCurrentIndex = opt->PosPrev;
return;
}
_optimumCurrentIndex = _optimumEndIndex = 0;
if (!_longestMatchWasFound)
lenMain = ReadMatchDistances();
else
{
lenMain = _longestMatchLength;
_longestMatchWasFound = false;
}
for (i=0;i<kNumRepDistances;i++)
{
reps[i] = _repDistances[i];
repLens[i] = GetMatchLen(0-1,reps[i],kMatchMaxLen);
if (i==0 || repLens[i] > repLens[repMaxIndex])
repMaxIndex = i;
}
if (repLens[repMaxIndex] >= _numFastBytes)
{
*backRes = repMaxIndex;
*lenRes = repLens[repMaxIndex];
MovePos(*lenRes-1);
return;
}
if (lenMain >= _numFastBytes)
{
*backRes = _matchDistances[_numFastBytes]+kNumRepDistances;
*lenRes = lenMain;
MovePos(lenMain-1);
return;
}
currentByte = GetIndexByte(0-1);
_optimum[0].State = _state;
matchByte = GetIndexByte(0-_repDistances[0]-2);
posState = position & _posStateMask;
_optimum[1].Price = CMyBitEncoder_GetPrice0(&_isMatch[_state][posState]) +
CLiteralEncoder_GetPrice(&_literalEncoder,position,_previousByte,
(bool)!CState_IsCharState(_state),matchByte,currentByte);
COptimal_MakeAsChar(&_optimum[1]);
_optimum[1].PosPrev = 0;
for (i=0;i<kNumRepDistances;i++)
_optimum[0].Backs[i] = reps[i];
matchPrice = CMyBitEncoder_GetPrice1(&_isMatch[_state][posState]);
repMatchPrice = matchPrice + CMyBitEncoder_GetPrice1(&_isRep[_state]);
if (matchByte == currentByte)
{
shortRepPrice = repMatchPrice + GetRepLen1Price(_state,posState);
if (shortRepPrice < _optimum[1].Price)
{
_optimum[1].Price = shortRepPrice;
COptimal_MakeAsShortRep(&_optimum[1]);
}
}
if (lenMain < 2)
{
*backRes = _optimum[1].BackPrev;
*lenRes = 1;
return;
}
normalMatchPrice = matchPrice + CMyBitEncoder_GetPrice0(&_isRep[_state]);
if (lenMain <= repLens[repMaxIndex])
lenMain = 0;
for (len=2;len<=lenMain;len++)
{
_optimum[len].PosPrev = 0;
_optimum[len].BackPrev = _matchDistances[len] + kNumRepDistances;
_optimum[len].Price = normalMatchPrice + GetPosLenPrice(_matchDistances[len],len,posState);
_optimum[len].Prev1IsChar = false;
}
if (lenMain < repLens[repMaxIndex])
lenMain = repLens[repMaxIndex];
for (;len<=lenMain;len++)
_optimum[len].Price = kIfinityPrice;
for (i=0;i<kNumRepDistances;i++)
{
repLen = repLens[i];
for (lenTest=2;lenTest<=repLen;lenTest++)
{
curAndLenPrice = repMatchPrice + GetRepPrice(i,lenTest,_state,posState);
opt = &_optimum[lenTest];
if (curAndLenPrice < opt->Price)
{
opt->Price = curAndLenPrice;
opt->PosPrev = 0;
opt->BackPrev = i;
opt->Prev1IsChar = false;
}
}
}
cur=0;
lenEnd = lenMain;
while (1)
{
cur++;
if (cur==lenEnd)
{
*lenRes = Backward(backRes,cur);
return;
}
position++;
opt = &_optimum[cur];
posPrev = opt->PosPrev;
if (opt->Prev1IsChar)
{
posPrev--;
if (opt->Prev2)
{
state = _optimum[opt->PosPrev2].State;
if (opt->BackPrev2 < kNumRepDistances)
CState_UpdateRep(state);
else
CState_UpdateMatch(state);
}
else
state = _optimum[posPrev].State;
CState_UpdateChar(state);
}
else
state = _optimum[posPrev].State;
if (posPrev == cur-1)
{
if (COptimal_IsShortRep(opt))
CState_UpdateShortRep(state);
else
CState_UpdateChar(state);
}
else
{
if (opt->Prev1IsChar && opt->Prev2)
{
posPrev = opt->PosPrev2;
pos = opt->BackPrev2;
CState_UpdateRep(state);
}
else
{
pos = opt->BackPrev;
if (pos < kNumRepDistances)
CState_UpdateRep(state);
else
CState_UpdateMatch(state);
}
prevOpt = &_optimum[posPrev];
if (pos < kNumRepDistances)
{
reps[0] = prevOpt->Backs[pos];
for (i=1;i<=pos;i++)
reps[i] = prevOpt->Backs[i-1];
for (;i<kNumRepDistances;i++)
reps[i] = prevOpt->Backs[i];
}
else
{
reps[0] = pos-kNumRepDistances;
for (i=1;i<kNumRepDistances;i++)
reps[i] = prevOpt->Backs[i-1];
}
}
opt->State = state;
for (i=0;i<kNumRepDistances;i++)
opt->Backs[i] = reps[i];
newLen = ReadMatchDistances();
if (newLen >= _numFastBytes)
{
_longestMatchLength = newLen;
_longestMatchWasFound = true;
*lenRes = Backward(backRes,cur);
return;
}
curPrice = opt->Price;
data = GetPointerToCurrentPos()-1;
currentByte = *data;
matchByte = data[-1-reps[0]];
posState = position & _posStateMask;
curAnd1Price = curPrice + CMyBitEncoder_GetPrice0(&_isMatch[state][posState]) +
CLiteralEncoder_GetPrice(&_literalEncoder,position,data[-1],(bool)!CState_IsCharState(state),matchByte,currentByte);
opt = &_optimum[cur+1];
nextIsChar = false;
if (curAnd1Price < opt->Price)
{
opt->Price = curAnd1Price;
opt->PosPrev = cur;
COptimal_MakeAsChar(opt);
nextIsChar = true;
}
matchPrice = curPrice + CMyBitEncoder_GetPrice1(&_isMatch[state][posState]);
repMatchPrice = matchPrice + CMyBitEncoder_GetPrice1(&_isRep[state]);
if (matchByte == currentByte && !(opt->PosPrev<cur && !opt->BackPrev))
{
shortRepPrice = repMatchPrice + GetRepLen1Price(state,posState);
if (shortRepPrice <= opt->Price)
{
opt->Price = shortRepPrice;
opt->PosPrev = cur;
COptimal_MakeAsShortRep(opt);
}
}
numAvailableBytesFull = GetNumAvailableBytes()+1;
if (numAvailableBytesFull > kNumOpts-1-cur)
numAvailableBytesFull = kNumOpts-1-cur;
numAvailableBytes = numAvailableBytesFull;
if (numAvailableBytes < 2)
continue;
if (numAvailableBytes > _numFastBytes)
numAvailableBytes = _numFastBytes;
if (numAvailableBytes >= 3 && !nextIsChar)
{
// try Literal + rep0
int temp;
backOffset = reps[0]+1;
for (temp=1;temp<numAvailableBytes;temp++)
if (data[temp]!=data[temp-backOffset])
break;
lenTest = temp-1;
if (lenTest>=2)
{
int posStateNext;
unsigned nextRepMatchPrice;
state2 = state;
CState_UpdateChar(state2);
posStateNext = (position+1) & _posStateMask;
nextRepMatchPrice = curAnd1Price +
CMyBitEncoder_GetPrice1(&_isMatch[state2][posStateNext]) +
CMyBitEncoder_GetPrice1(&_isRep[state2]);
while (lenEnd < cur+1+lenTest)
_optimum[++lenEnd].Price = kIfinityPrice;
curAndLenPrice = nextRepMatchPrice + GetRepPrice(0,lenTest,state2,posStateNext);
opt = &_optimum[cur+1+lenTest];
if (curAndLenPrice < opt->Price)
{
opt->Price = curAndLenPrice;
opt->PosPrev = cur+1;
opt->BackPrev = 0;
opt->Prev1IsChar = true;
opt->Prev2 = false;
}
}
}
for (repIndex=0;repIndex<kNumRepDistances;repIndex++)
{
backOffset = reps[repIndex]+1;
if (data[0] != data[0-backOffset] ||
data[1] != data[1-backOffset])
continue;
for (lenTest=2;lenTest<numAvailableBytes;lenTest++)
if (data[lenTest]!=data[lenTest-backOffset])
break;
lenTestTemp = lenTest;
do
{
while (lenEnd < cur+lenTest)
_optimum[++lenEnd].Price = kIfinityPrice;
curAndLenPrice = repMatchPrice + GetRepPrice(repIndex,lenTest,state,posState);
opt = &_optimum[cur+lenTest];
if (curAndLenPrice < opt->Price)
{
opt->Price = curAndLenPrice;
opt->PosPrev = cur;
opt->BackPrev = repIndex;
opt->Prev1IsChar = false;
}
} while (--lenTest>=2);
lenTest = lenTestTemp;
lenTest2 = lenTest+1;
limit = lenTest2 + _numFastBytes;
if (limit > numAvailableBytesFull)
limit = numAvailableBytesFull;
for (;lenTest2<limit;lenTest2++)
if (data[lenTest2] != data[lenTest2-backOffset])
break;
lenTest2 -= lenTest+1;
if (lenTest2 >= 2)
{
unsigned nextMatchPrice,nextRepMatchPrice;
int offset;
state2 = state;
CState_UpdateRep(state2);
posStateNext = (position+lenTest)&_posStateMask;
curAndLenCharPrice = repMatchPrice + GetRepPrice(repIndex,lenTest,state,posState) +
CMyBitEncoder_GetPrice0(&_isMatch[state2][posStateNext]) +
CLiteralEncoder_GetPrice(&_literalEncoder,position+lenTest,data[lenTest-1],true,data[lenTest-backOffset],data[lenTest]);
CState_UpdateChar(state2);
posStateNext = (position+lenTest+1)&_posStateMask;
nextMatchPrice = curAndLenCharPrice + CMyBitEncoder_GetPrice1(&_isMatch[state2][posStateNext]);
nextRepMatchPrice = nextMatchPrice + CMyBitEncoder_GetPrice1(&_isRep[state2]);
offset = lenTest+1+lenTest2;
while (lenEnd<cur+offset)
_optimum[++lenEnd].Price = kIfinityPrice;
curAndLenPrice = nextRepMatchPrice + GetRepPrice(0,lenTest2,state2,posStateNext);
opt = &_optimum[cur+offset];
if (curAndLenPrice < opt->Price)
{
opt->Price = curAndLenPrice;
opt->PosPrev = cur+lenTest+1;
opt->BackPrev = 0;
opt->Prev1IsChar = true;
opt->Prev2 = true;
opt->PosPrev2 = cur;
opt->BackPrev2 = repIndex;
}
}
}
if (newLen > numAvailableBytes)
newLen = numAvailableBytes;
if (newLen >= 2)
{
if (newLen==2 && _matchDistances[2] >= 0x80)
continue;
normalMatchPrice = matchPrice + CMyBitEncoder_GetPrice0(&_isRep[state]);
while (lenEnd < cur+newLen)
_optimum[++lenEnd].Price = kIfinityPrice;
for (lenTest=newLen;lenTest>=2;lenTest--)
{
backOffset = _matchDistances[lenTest];
curAndLenPrice = normalMatchPrice + GetPosLenPrice(backOffset,lenTest,posState);
opt = &_optimum[cur+lenTest];
if (curAndLenPrice < opt->Price)
{
opt->Price = curAndLenPrice;
opt->PosPrev = cur;
opt->BackPrev = backOffset+kNumRepDistances;
opt->Prev1IsChar = false;
}
if (lenTest==newLen || backOffset!=_matchDistances[lenTest+1])
{
// Try Match + Literal + Rep0
backOffset++;
lenTest2 = lenTest+1;
limit = lenTest2+_numFastBytes;
if (limit > numAvailableBytesFull)
limit = numAvailableBytesFull;
for (;lenTest2<limit;lenTest2++)
if (data[lenTest2]!=data[lenTest2-backOffset])
break;
lenTest2 -= lenTest+1;
if (lenTest2 >= 2)
{
state2 = state;
CState_UpdateMatch(state2);
posStateNext = (position+lenTest)&_posStateMask;
curAndLenCharPrice = curAndLenPrice + CMyBitEncoder_GetPrice0(&_isMatch[state2][posStateNext]) +
CLiteralEncoder_GetPrice(&_literalEncoder,position+lenTest,data[lenTest-1],true,data[lenTest-backOffset],data[lenTest]);
CState_UpdateChar(state2);
posStateNext = (position+lenTest+1)&_posStateMask;
nextMatchPrice = curAndLenCharPrice + CMyBitEncoder_GetPrice1(&_isMatch[state2][posStateNext]);
nextRepMatchPrice = nextMatchPrice + CMyBitEncoder_GetPrice1(&_isRep[state2]);
offset = lenTest+1+lenTest2;
while (lenEnd<cur+offset)
_optimum[++lenEnd].Price = kIfinityPrice;
curAndLenPrice = nextRepMatchPrice + GetRepPrice(0,lenTest2,state2,posStateNext);
opt = &_optimum[cur+offset];
if (curAndLenPrice < opt->Price)
{
opt->Price = curAndLenPrice;
opt->PosPrev = cur+lenTest+1;
opt->BackPrev = 0;
opt->Prev1IsChar = true;
opt->Prev2 = true;
opt->PosPrev2 = cur;
opt->BackPrev2 = backOffset - 1 + kNumRepDistances;
}
}
}
}
}
}
}
 
static bool CodeOneBlock(void)
{
unsigned posState;
byte curByte,matchByte;
unsigned pos,len,distance,i;
unsigned posSlot,lenToPosState;
CLiteralEncoder2* subCoder;
uint64 progressPosValuePrev;
 
if (_finished)
return false;
_finished = true;
progressPosValuePrev = nowPos64;
if (nowPos64 == 0)
{
if (GetNumAvailableBytes() == 0)
{
CEncoder_Flush();
return false;
}
ReadMatchDistances();
posState = (unsigned)nowPos64 & _posStateMask;
CMyBitEncoder_Encode(&_isMatch[_state][posState],0);
CState_UpdateChar(_state);
curByte = GetIndexByte(0 - _additionalOffset);
CLiteralEncoder2_Encode(
*CLiteralEncoder_GetSubCoder(&_literalEncoder,(unsigned)nowPos64,_previousByte),
curByte);
_previousByte = curByte;
_additionalOffset--;
nowPos64++;
}
if (GetNumAvailableBytes() == 0)
{
CEncoder_Flush();
return false;
}
for (;;)
{
posState = (unsigned)nowPos64 & _posStateMask;
GetOptimum((unsigned)nowPos64,&pos,&len);
if (len==1 && pos==0xFFFFFFFF)
{
CMyBitEncoder_Encode(&_isMatch[_state][posState],0);
curByte = GetIndexByte(0-_additionalOffset);
subCoder = CLiteralEncoder_GetSubCoder(&_literalEncoder,(unsigned)nowPos64,
_previousByte);
if (!CState_IsCharState(_state))
{
matchByte = GetIndexByte(0-_repDistances[0]-1-_additionalOffset);
CLiteralEncoder2_EncodeMatched(*subCoder,matchByte,curByte);
}
else
CLiteralEncoder2_Encode(*subCoder,curByte);
CState_UpdateChar(_state);
_previousByte = curByte;
}
else
{
CMyBitEncoder_Encode(&_isMatch[_state][posState],1);
if (pos < kNumRepDistances)
{
CMyBitEncoder_Encode(&_isRep[_state],1);
if (pos==0)
{
CMyBitEncoder_Encode(&_isRepG0[_state],0);
CMyBitEncoder_Encode(&_isRep0Long[_state][posState],
(len==1) ? 0 : 1);
}
else
{
CMyBitEncoder_Encode(&_isRepG0[_state],1);
if (pos==1)
CMyBitEncoder_Encode(&_isRepG1[_state],0);
else
{
CMyBitEncoder_Encode(&_isRepG1[_state],1);
CMyBitEncoder_Encode(&_isRepG2[_state],pos-2);
}
}
if (len==1)
CState_UpdateShortRep(_state);
else
{
CPriceTableEncoder_Encode(&_repMatchLenEncoder,len-kMatchMinLen,posState);
CState_UpdateRep(_state);
}
distance = _repDistances[pos];
if (pos)
{
for (i=pos;i;i--)
_repDistances[i] = _repDistances[i-1];
_repDistances[0] = distance;
}
}
else
{
CMyBitEncoder_Encode(&_isRep[_state],0);
CState_UpdateMatch(_state);
CPriceTableEncoder_Encode(&_lenEncoder,len-kMatchMinLen,posState);
pos -= kNumRepDistances;
posSlot = GetPosSlot(pos);
lenToPosState = GetLenToPosState(len);
CBitTreeEncoder_Encode(&_posSlotEncoder[lenToPosState],posSlot);
if (posSlot >= kStartPosModelIndex)
{
unsigned footerBits;
unsigned base,posReduced;
footerBits = (posSlot>>1)-1;
base = (2 | (posSlot&1)) << footerBits;
posReduced = pos-base;
if (posSlot < kEndPosModelIndex)
ReverseBitTreeEncode(_posEncoders+base-posSlot-1,
footerBits,posReduced);
else
{
RangeEncoder_EncodeDirectBits(posReduced>>kNumAlignBits,footerBits-kNumAlignBits);
CBitTreeEncoder_ReverseEncode(&_posAlignEncoder,posReduced&kAlignMask);
if (--_alignPriceCount == 0)
FillAlignPrices();
}
}
distance = pos;
for (i=kNumRepDistances-1;i;i--)
_repDistances[i] = _repDistances[i-1];
_repDistances[0] = distance;
}
_previousByte = GetIndexByte(len-1-_additionalOffset);
}
_additionalOffset -= len;
nowPos64 += len;
if (nowPos64 - lastPosSlotFillingPos >= (1<<9))
{
FillPosSlotPrices();
FillDistancesPrices();
lastPosSlotFillingPos = nowPos64;
}
if (!_additionalOffset)
{
if (GetNumAvailableBytes() == 0)
{
CEncoder_Flush();
return false;
}
if (nowPos64 - progressPosValuePrev >= (1<<12))
{
_finished = false;
return true;
}
}
}
}
 
extern void __stdcall lzma_set_dict_size(
unsigned logdictsize)
{
_dictionarySize = 1 << logdictsize;
_distTableSize = logdictsize*2;
}
 
extern unsigned __stdcall lzma_compress(
const void* source,
void* destination,
unsigned length,
void* workmem)
{
FastPosInit();
//memset(&encoder,0,sizeof(encoder));
//memset(&rangeEncoder,0,sizeof(rangeEncoder));
// CEncoder::CEncoder, CEncoder::SetCoderProperties
_numFastBytes = 128;
#ifdef FOR_KERPACK
_posStateBits = 0;
_posStateMask = 0;
#else
_posStateBits = 2;
_posStateMask = 3;
#endif
_numLiteralContextBits = 3;
_numLiteralPosStateBits = 0;
_writeEndMark = false;
// CEncoder::Code - ïîåõàëè!
_finished = false;
CEncoder_Create(workmem);
CEncoder_Init();
FillPosSlotPrices();
FillDistancesPrices();
FillAlignPrices();
CPriceTableEncoder_SetTableSize(&_lenEncoder,_numFastBytes+1-kMatchMinLen);
CPriceTableEncoder_UpdateTables(&_lenEncoder,1<<_posStateBits);
CPriceTableEncoder_SetTableSize(&_repMatchLenEncoder,_numFastBytes+1-kMatchMinLen);
CPriceTableEncoder_UpdateTables(&_repMatchLenEncoder,1<<_posStateBits);
lastPosSlotFillingPos = 0;
nowPos64 = 0;
pack_length = length;
pack_pos = 0;
curin = (const byte*)source;
curout = (byte*)destination;
MatchFinder_Init();
while (CodeOneBlock()) ;
return curout - (byte*)destination;
}
/programs/other/kpack/kerpack_linux/lzma_c/LZMAEncoder.h
0,0 → 1,53
#ifndef _LZMA_ENCODER_H
#define _LZMA_ENCODER_H
 
#include "lzma.h"
#include "RangeCoderBitTree.h"
 
typedef struct
{
CState State;
bool Prev1IsChar;
bool Prev2;
unsigned PosPrev2;
unsigned BackPrev2;
unsigned Price;
unsigned PosPrev;
unsigned BackPrev;
unsigned Backs[kNumRepDistances];
} COptimal;
#define COptimal_MakeAsChar(a) (a)->BackPrev=(unsigned)-1,(a)->Prev1IsChar=false
#define COptimal_MakeAsShortRep(a) (a)->BackPrev=0,(a)->Prev1IsChar=false
#define COptimal_IsShortRep(a) ((a)->BackPrev==0)
 
#define kIfinityPrice 0xFFFFFFF
#define kNumOpts (1<<12)
 
typedef CMyBitEncoder CLiteralEncoder2[0x300];
typedef struct
{
CLiteralEncoder2* _coders;
int _numPrevBits;
int _numPosBits;
unsigned _posMask;
} CLiteralEncoder;
 
typedef struct
{
CMyBitEncoder _choice;
CMyBitEncoder _choice2;
NRangeCoder_CBitTreeEncoder _lowCoder[kNumPosStatesEncodingMax];
NRangeCoder_CBitTreeEncoder _midCoder[kNumPosStatesEncodingMax];
NRangeCoder_CBitTreeEncoder _highCoder;
} NLength_CEncoder;
 
typedef struct
{
NLength_CEncoder base;
unsigned _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
unsigned _tableSize;
unsigned _counters[kNumPosStatesEncodingMax];
} NLength_CPriceTableEncoder;
#define CPriceTableEncoder_Init(a,b) NLength_CEncoder_Init(&a.base,b)
 
#endif
/programs/other/kpack/kerpack_linux/lzma_c/MatchFinder.c
0,0 → 1,422
#include "MatchFinder.h"
/* memcpy must be inlined - we do not want to use RTL */
#include <memory.h>
/*#pragma function(memcpy)
void* __cdecl memcpy(void* _Dst, const void* _Src, size_t _Size)
{
unsigned long i;
for (i = 0; i < _Size; i++)
((char*)_Dst)[i] = ((char*)_Src)[i];
return _Dst;
}*/
//#pragma intrinsic(memcpy)
 
#define kMaxValForNormalize (((unsigned)1<<31)-1)
 
/* settings for bt4:
defined HASH_ARRAY_2
defined HASH_ARRAY_3
*/
 
//#define kHash2Size 0x400
#define kNumHashDirectBytes 0
#define kNumHashBytes 3
//#define kHash3Size 0x40000
#define kHash2Size 0x10000
#define kHashSize 0x100000
 
#define kHashSizeSum (kHashSize+kHash2Size)
#define kHash2Offset kHashSize
 
static unsigned _cyclicBufferPos;
static unsigned _cyclicBufferSize;
static unsigned _matchMaxLen;
static unsigned* _hash;
static unsigned _cutValue;
 
#ifdef GENERIC_INPUT
static byte* _bufferBase;
static unsigned _posLimit;
static bool _streamEndWasReached;
static byte* _pointerToLastSafePosition;
static byte* _buffer;
static unsigned _blockSize;
static unsigned _pos;
static unsigned _keepSizeBefore;
static unsigned _keepSizeAfter;
static unsigned _keepSizeReserv;
static unsigned _streamPos;
#else
#define _buffer curin
#define _pos pack_pos
#define _streamPos pack_length
#endif
 
#ifdef GENERIC_INPUT
/* LZ Window */
 
static void LZInWindow_Create(unsigned keepSizeBefore,unsigned keepSizeAfter,unsigned keepSizeReserv,byte**mem)
{
_keepSizeBefore = keepSizeBefore;
_keepSizeAfter = keepSizeAfter;
_keepSizeReserv = keepSizeReserv;
_blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
_bufferBase = *mem;
_blockSize = (_blockSize + 3) & ~3;
*mem += _blockSize;
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
}
 
static void ReadBlock(void)
{
if (_streamEndWasReached)
return;
for (;;)
{
unsigned size;
size = (unsigned)(_bufferBase-_buffer) + _blockSize - _streamPos;
if (!size) return;
if (size > pack_length - pack_pos)
size = pack_length - pack_pos;
memcpy(_buffer+_streamPos,curin,size);
curin += size;
pack_pos += size;
if (size == 0)
{
byte* pointerToPosition;
_posLimit = _streamPos;
pointerToPosition = _buffer + _posLimit;
if (pointerToPosition > _pointerToLastSafePosition)
_posLimit = _pointerToLastSafePosition - _buffer;
_streamEndWasReached = true;
return;
}
_streamPos += size;
if (_streamPos >= _pos + _keepSizeAfter)
{
_posLimit = _streamPos - _keepSizeAfter;
return;
}
}
}
 
static void LZInWindow_Init(void)
{
_buffer = _bufferBase;
_pos = 0;
_streamPos = 0;
_streamEndWasReached = false;
ReadBlock();
}
#else
#define LZInWindow_Create(a,b,c,d) /* nothing */
#define LZInWindow_Init() _buffer--, _pos++, _streamPos++
#endif
 
const byte* GetPointerToCurrentPos(void) {return _buffer+_pos;}
 
#ifdef GENERIC_INPUT
static void MoveBlock(void)
{
unsigned offset,numBytes;
offset = _buffer-_bufferBase+_pos-_keepSizeBefore;
numBytes = _buffer-_bufferBase+_streamPos-offset;
// copying backwards: safe to use memcpy instead of memmove
memcpy(_bufferBase,_bufferBase+offset,numBytes);
_buffer -= offset;
}
 
static void LZInWindow_MovePos(void)
{
_pos++;
if (_pos > _posLimit)
{
const byte* pointerToPosition = _buffer+_pos;
if (pointerToPosition > _pointerToLastSafePosition)
MoveBlock();
ReadBlock();
}
}
#else
#define LZInWindow_MovePos() _pos++
#endif
 
byte GetIndexByte(int index) {return _buffer[_pos+index];}
 
unsigned GetMatchLen(int index,unsigned distance,unsigned limit)
{
const byte* pby;
unsigned i;
#ifdef GENERIC_INPUT
if (_streamEndWasReached)
if ((_pos+index)+limit > _streamPos)
limit = _streamPos - (_pos+index);
#else
unsigned limit2 = pack_length - (pack_pos + index);
if (limit > limit2)
limit = limit2;
#endif
distance++;
pby = _buffer + _pos + index;
for (i=0;i<limit && pby[i]==pby[(int)(i-distance)];i++) ;
return i;
}
 
unsigned GetNumAvailableBytes(void) {return _streamPos-_pos;}
 
#ifdef GENERIC_INPUT
void ReduceOffsets(int subValue)
{
_buffer += subValue;
_posLimit -= subValue;
_pos -= subValue;
_streamPos -= subValue;
}
#else
#define ReduceOffsets(a) /* nothing */
#endif
 
/* Binary tree Match Finder */
 
static unsigned crc_table[256];
 
void MatchFinder_Create(unsigned historySize,unsigned keepAddBufferBefore,unsigned matchMaxLen,unsigned keepAddBufferAfter,byte**mem)
{
unsigned sizeReserv;
sizeReserv = (historySize + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter)/2+256;
LZInWindow_Create(historySize+keepAddBufferBefore,matchMaxLen+keepAddBufferAfter,sizeReserv,mem);
_matchMaxLen = matchMaxLen;
_cyclicBufferSize = historySize+1;
_hash = (unsigned*)*mem;
*mem += (kHashSizeSum + _cyclicBufferSize*2) * sizeof(unsigned);
_cutValue = 0xFF;
}
 
void MatchFinder_Init(void)
{
unsigned i,j,r;
LZInWindow_Init();
for (i=0;i<kHashSizeSum;i++)
_hash[i] = 0;
_cyclicBufferPos = 0;
ReduceOffsets(-1);
for (i=0;i<256;i++)
{
r = i;
for (j=0;j<8;j++)
{
if (r & 1)
r = (r>>1) ^ 0xEDB88320;
else
r >>= 1;
}
crc_table[i] = r;
}
}
 
static unsigned Hash(const byte* ptr, unsigned* hash2Value)
{
unsigned temp;
temp = crc_table[ptr[0]] ^ ptr[1];
*hash2Value = *(word*)ptr; //ptr[0] + ((unsigned)ptr[1] << 8);
return (temp ^ ((unsigned)ptr[2]<<8)) & (kHashSize - 1);
}
 
unsigned GetLongestMatch(unsigned* distances)
{
unsigned lenLimit,maxLen=0;
unsigned matchMinPos;
const byte* cur;
unsigned hash2Value,hashValue;
unsigned curMatch,curMatch2;
unsigned *son,*ptr0,*ptr1;
unsigned len0,len1,count;
if (_pos + _matchMaxLen <= _streamPos)
lenLimit = _matchMaxLen;
else
{
lenLimit = _streamPos - _pos;
if (lenLimit < kNumHashBytes)
return 0;
}
matchMinPos = (_pos>_cyclicBufferSize) ? (_pos-_cyclicBufferSize) : 0;
cur = _buffer+_pos;
hashValue = Hash(cur,&hash2Value);
curMatch = _hash[hashValue];
curMatch2 = _hash[kHash2Offset + hash2Value];
_hash[kHash2Offset + hash2Value] = _pos;
distances[2] = 0xFFFFFFFF;
if (curMatch2 > matchMinPos)
//if (_buffer[curMatch2] == cur[0])
{
distances[2] = _pos - curMatch2 - 1;
maxLen = 2;
}
_hash[hashValue] = _pos;
son = _hash + kHashSizeSum;
ptr0 = son + (_cyclicBufferPos << 1) + 1;
ptr1 = son + (_cyclicBufferPos << 1);
distances[kNumHashBytes] = 0xFFFFFFFF;
len0 = len1 = kNumHashDirectBytes;
count = _cutValue;
for (;;)
{
const byte* pb;
unsigned len,delta;
unsigned cyclicPos;
unsigned* pair;
if (curMatch <= matchMinPos || count--==0)
{
*ptr0 = *ptr1 = 0;
break;
}
pb = _buffer+curMatch;
len = (len0<len1) ? len0 : len1;
do
if (pb[len] != cur[len]) break;
while (++len != lenLimit);
delta = _pos - curMatch;
while (maxLen < len)
distances[++maxLen] = delta-1;
cyclicPos = (delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta) :
(_cyclicBufferPos - delta + _cyclicBufferSize);
pair = son + (cyclicPos<<1);
if (len != lenLimit)
{
if (pb[len] < cur[len])
{
*ptr1 = curMatch;
ptr1 = pair+1;
curMatch = *ptr1;
len1 = len;
}
else
{
*ptr0 = curMatch;
ptr0 = pair;
curMatch = *ptr0;
len0 = len;
}
}
else
{
*ptr1 = pair[0];
*ptr0 = pair[1];
break;
}
}
/*if (distances[4] < distances[3])
distances[3] = distances[4];
if (distances[3] < distances[2])
distances[2] = distances[3];*/
return maxLen;
}
 
void DummyLongestMatch(void)
{
unsigned lenLimit;
unsigned matchMinPos;
const byte* cur;
unsigned hash2Value,hashValue;
unsigned curMatch;
unsigned* son,*ptr0,*ptr1;
unsigned len0,len1,count;
if (_pos + _matchMaxLen <= _streamPos)
lenLimit = _matchMaxLen;
else
{
lenLimit = _streamPos - _pos;
if (lenLimit < kNumHashBytes)
return;
}
matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
cur = _buffer+_pos;
hashValue = Hash(cur,&hash2Value);
_hash[kHash2Offset + hash2Value] = _pos;
curMatch = _hash[hashValue];
_hash[hashValue] = _pos;
son = _hash+kHashSizeSum;
ptr0 = son + (_cyclicBufferPos << 1) + 1;
ptr1 = son + (_cyclicBufferPos << 1);
len0 = len1 = kNumHashDirectBytes;
count = _cutValue;
for (;;)
{
const byte* pb;
unsigned len;
unsigned delta,cyclicPos;
unsigned* pair;
if (curMatch <= matchMinPos || count--==0)
break;
pb = _buffer+curMatch;
len = (len0<len1) ? len0 : len1;
do
if (pb[len] != cur[len]) break;
while (++len != lenLimit);
delta = _pos - curMatch;
cyclicPos = (delta <= _cyclicBufferPos) ?
(_cyclicBufferPos - delta) :
(_cyclicBufferPos - delta + _cyclicBufferSize);
pair = son + (cyclicPos << 1);
if (len != lenLimit)
{
if (pb[len] < cur[len])
{
*ptr1 = curMatch;
ptr1 = pair+1;
curMatch = *ptr1;
len1 = len;
}
else
{
*ptr0 = curMatch;
ptr0 = pair;
curMatch = *ptr0;
len0 = len;
}
}
else
{
*ptr1 = pair[0];
*ptr0 = pair[1];
return;
}
}
*ptr0 = *ptr1 = 0;
}
 
#ifdef GENERIC_INPUT
// for memory input size is always less than kMaxValForNormalize
static void Normalize(void)
{
unsigned subValue;
unsigned* items;
unsigned i,numItems;
subValue = _pos - _cyclicBufferSize;
items = _hash;
numItems = (kHashSizeSum + _cyclicBufferSize*2);
for (i=0;i<numItems;i++)
{
unsigned value;
value = items[i];
if (value <= subValue)
value = 0;
else
value -= subValue;
items[i] = value;
}
ReduceOffsets(subValue);
}
#endif
 
void MatchFinder_MovePos(void)
{
if (++_cyclicBufferPos == _cyclicBufferSize)
_cyclicBufferPos = 0;
LZInWindow_MovePos();
#ifdef GENERIC_INPUT
if (_pos == kMaxValForNormalize)
Normalize();
#endif
}
/programs/other/kpack/kerpack_linux/lzma_c/MatchFinder.h
0,0 → 1,13
#include "common.h"
 
extern const byte* GetPointerToCurrentPos(void);
extern byte GetIndexByte(int index);
extern unsigned GetMatchLen(int index,unsigned distance,unsigned limit);
extern unsigned GetNumAvailableBytes(void);
extern void ReduceOffsets(int subValue);
 
extern void MatchFinder_Init(void);
extern void MatchFinder_Create(unsigned historySize,unsigned keepAddBufferBefore,unsigned matchMaxLen,unsigned keepAddBufferAfter,byte**mem);
extern unsigned GetLongestMatch(unsigned*distances);
extern void DummyLongestMatch(void);
extern void MatchFinder_MovePos(void);
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoder.c
0,0 → 1,191
#include "RangeCoderBitTree.h"
#include "lzma.h"
 
static unsigned _cacheSize;
static byte _cache;
static uint64 low;
static unsigned range;
 
static unsigned PriceTable[kBitModelTotal >> kNumMoveReducingBits];
 
void RangeEncoder_Init(void)
{
int i;
unsigned start,end,j;
low = 0;
range = 0xFFFFFFFF;
_cacheSize = 1;
_cache = 0;
/* init price table */
#define kNumBits (kNumBitModelTotalBits - kNumMoveReducingBits)
for (i=kNumBits;i--;)
{
start = 1 << (kNumBits - i - 1);
end = 1 << (kNumBits - i);
for (j=start;j<end;j++)
PriceTable[j] = (i<<kNumBitPriceShiftBits) +
(((end-j)<<kNumBitPriceShiftBits) >> (kNumBits - i - 1));
}
#undef kNumBits
}
 
void RangeEncoder_ShiftLow(void)
{
if ((unsigned)low < 0xFF000000U || (int)(low>>32))
{
byte temp = _cache;
do
{
*curout++ = (byte)(temp + (byte)(low>>32));
temp = 0xFF;
} while (--_cacheSize);
_cache = (byte)((unsigned)low>>24);
}
_cacheSize++;
low = (unsigned)low << 8;
}
 
void RangeEncoder_FlushData(void)
{
int i;
for (i=0;i<5;i++)
RangeEncoder_ShiftLow();
}
 
void RangeEncoder_EncodeDirectBits(unsigned value,int numTotalBits)
{
int i;
for (i=numTotalBits;i--;)
{
range >>= 1;
if (((value >> i) & 1) == 1)
low += range;
if (range < kTopValue)
{
range <<= 8;
RangeEncoder_ShiftLow();
}
}
}
 
void CMyBitEncoder_Encode(CMyBitEncoder* e,unsigned symbol)
{
unsigned newBound;
newBound = (range >> kNumBitModelTotalBits) * *e;
if (symbol == 0)
{
range = newBound;
*e += (kBitModelTotal - *e) >> kNumMoveBits;
}
else
{
low += newBound;
range -= newBound;
*e -= *e >> kNumMoveBits;
}
if (range < kTopValue)
{
range <<= 8;
RangeEncoder_ShiftLow();
}
}
 
unsigned CMyBitEncoder_GetPrice(CMyBitEncoder* e, unsigned symbol)
{
return PriceTable[(((*e-symbol)^((-(int)symbol))) & (kBitModelTotal-1)) >> kNumMoveReducingBits];
}
unsigned CMyBitEncoder_GetPrice0(CMyBitEncoder* e)
{
return PriceTable[*e >> kNumMoveReducingBits];
}
unsigned CMyBitEncoder_GetPrice1(CMyBitEncoder* e)
{
return PriceTable[(kBitModelTotal - *e) >> kNumMoveReducingBits];
}
 
void CBitTreeEncoder_Init(NRangeCoder_CBitTreeEncoder*e,int numBitLevels)
{
unsigned i;
e->numBitLevels = numBitLevels;
for (i=1;i<((unsigned)1<<numBitLevels);i++)
CMyBitEncoder_Init(e->Models[i]);
}
void CBitTreeEncoder_Encode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
{
unsigned modelIndex = 1;
int bitIndex;
unsigned bit;
for (bitIndex = e->numBitLevels; bitIndex--;)
{
bit = (symbol >> bitIndex) & 1;
CMyBitEncoder_Encode(&e->Models[modelIndex],bit);
modelIndex = (modelIndex << 1) | bit;
}
}
void CBitTreeEncoder_ReverseEncode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
{
unsigned modelIndex = 1;
int i;
unsigned bit;
for (i=0;i<e->numBitLevels;i++)
{
bit = symbol & 1;
CMyBitEncoder_Encode(&e->Models[modelIndex],bit);
modelIndex = (modelIndex << 1) | bit;
symbol >>= 1;
}
}
unsigned CBitTreeEncoder_GetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
{
unsigned price = 0;
symbol |= (1 << e->numBitLevels);
while (symbol != 1)
{
price += CMyBitEncoder_GetPrice(&e->Models[symbol>>1],symbol&1);
symbol >>= 1;
}
return price;
}
unsigned CBitTreeEncoder_ReverseGetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
{
unsigned price=0;
unsigned modelIndex=1;
int i;
unsigned bit;
for (i=e->numBitLevels;i;i--)
{
bit = symbol&1;
symbol >>= 1;
price += CMyBitEncoder_GetPrice(&e->Models[modelIndex],bit);
modelIndex = (modelIndex<<1)|bit;
}
return price;
}
unsigned ReverseBitTreeGetPrice(CMyBitEncoder*Models,unsigned NumBitLevels,unsigned symbol)
{
unsigned price=0;
unsigned modelIndex=1;
unsigned bit;
int i;
for (i=NumBitLevels;i;i--)
{
bit = symbol & 1;
symbol >>= 1;
price += CMyBitEncoder_GetPrice(Models+modelIndex,bit);
modelIndex = (modelIndex<<1)|bit;
}
return price;
}
void ReverseBitTreeEncode(CMyBitEncoder*Models,int NumBitLevels,unsigned symbol)
{
unsigned modelIndex = 1;
int i;
unsigned bit;
for (i=0;i<NumBitLevels;i++)
{
bit = symbol & 1;
CMyBitEncoder_Encode(Models+modelIndex,bit);
modelIndex = (modelIndex<<1)|bit;
symbol >>= 1;
}
}
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoder.h
0,0 → 1,7
#include "common.h"
#define kNumTopBits 24
#define kTopValue (1<<kNumTopBits)
extern void RangeEncoder_Init(void);
extern void RangeEncoder_FlushData(void);
extern void RangeEncoder_ShiftLow(void);
extern void RangeEncoder_EncodeDirectBits(unsigned value,int numTotalBits);
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoderBit.h
0,0 → 1,18
#include "RangeCoder.h"
 
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1<<kNumBitModelTotalBits)
 
#define kNumMoveReducingBits 2
 
#define kNumBitPriceShiftBits 6
#define kBitPrice (1<<kNumBitPriceShiftBits)
 
typedef unsigned NRangeCoder_CBitModel;
typedef NRangeCoder_CBitModel CMyBitEncoder;
 
extern void CMyBitEncoder_Encode(CMyBitEncoder* e,unsigned symbol);
extern unsigned CMyBitEncoder_GetPrice(CMyBitEncoder* e, unsigned symbol);
extern unsigned CMyBitEncoder_GetPrice0(CMyBitEncoder* e);
extern unsigned CMyBitEncoder_GetPrice1(CMyBitEncoder* e);
#define CMyBitEncoder_Init(a) a=kBitModelTotal/2
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoderBitTree.h
0,0 → 1,15
#include "RangeCoderBit.h"
 
typedef struct
{
CMyBitEncoder Models[1<<8];
int numBitLevels;
} NRangeCoder_CBitTreeEncoder;
 
extern void CBitTreeEncoder_Init(NRangeCoder_CBitTreeEncoder*e,int numBitLevels);
extern void CBitTreeEncoder_Encode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol);
extern void CBitTreeEncoder_ReverseEncode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol);
extern unsigned CBitTreeEncoder_GetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol);
extern unsigned CBitTreeEncoder_ReverseGetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol);
extern unsigned ReverseBitTreeGetPrice(CMyBitEncoder*Models,unsigned NumBitLevels,unsigned symbol);
extern void ReverseBitTreeEncode(CMyBitEncoder*Models,int NumBitLevels,unsigned symbol);
/programs/other/kpack/kerpack_linux/lzma_c/common.h
0,0 → 1,22
#ifndef _COMMON_H
#define _COMMON_H
 
typedef unsigned char byte;
typedef unsigned short word;
// conditional compiling, mike.dld
#ifdef WIN32
typedef unsigned __int64 uint64;
#else
typedef unsigned long long uint64;
#define __stdcall __attribute__((stdcall))
#endif
typedef byte bool;
#define true 1
#define false 0
 
extern unsigned pack_length;
extern unsigned pack_pos;
extern const byte* curin;
extern byte* curout;
 
#endif
/programs/other/kpack/kerpack_linux/lzma_c/lzma.h
0,0 → 1,52
#include "common.h"
#define kNumRepDistances 4
#define kNumStates 12
extern const byte kLiteralNextStates[kNumStates];
extern const byte kMatchNextStates[kNumStates];
extern const byte kRepNextStates[kNumStates];
extern const byte kShortRepNextStates[kNumStates];
 
typedef byte CState;
#define CState_Init(a) a=0
#define CState_UpdateChar(a) a=kLiteralNextStates[a]
#define CState_UpdateMatch(a) a=kMatchNextStates[a]
#define CState_UpdateRep(a) a=kRepNextStates[a]
#define CState_UpdateShortRep(a) a=kShortRepNextStates[a]
#define CState_IsCharState(a) (a<7)
 
#define kNumPosSlotBits 6
#define kDicLogSizeMin 0
#define kDicLogSizeMax 32
#define kDistTableSizeMax (kDicLogSizeMax*2)
#define kNumLenToPosStates 4
 
#define GetLenToPosState(len) ((len<kNumLenToPosStates+2)?len-2:kNumLenToPosStates-1)
 
#define kNumPosStatesBitsMax 4
#define kNumPosStatesMax (1<<kNumPosStatesBitsMax)
 
#define kNumPosStatesBitsEncodingMax 4
#define kNumPosStatesEncodingMax (1 << kNumPosStatesBitsEncodingMax)
 
#define kNumLowBits 3
#define kNumMidBits 3
#define kNumHighBits 8
#define kNumLowSymbols (1<<kNumLowBits)
#define kNumMidSymbols (1<<kNumMidBits)
#define kNumSymbolsTotal (kNumLowSymbols + kNumMidSymbols + (1<<kNumHighBits))
 
#define kMatchMinLen 2
#define kMatchMaxLen (kMatchMinLen + kNumSymbolsTotal - 1)
 
#define kNumAlignBits 4
#define kAlignTableSize (1<<kNumAlignBits)
#define kAlignMask (kAlignTableSize-1)
 
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumPosModels (kEndPosModelIndex-kStartPosModelIndex)
 
#define kNumFullDistances (1<<(kEndPosModelIndex/2))
#define kNumLitPosStatesBitsEncodingMax 4
#define kNumLitContextBitsMax 8
#define kNumMoveBits 5
/programs/other/kpack/kerpack_linux/lzma_c/lzmapack.dsp
0,0 → 1,132
# Microsoft Developer Studio Project File - Name="lzmapack" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
 
# TARGTYPE "Win32 (x86) Static Library" 0x0104
 
CFG=lzmapack - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "lzmapack.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "lzmapack.mak" CFG="lzmapack - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "lzmapack - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "lzmapack - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
 
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
 
!IF "$(CFG)" == "lzmapack - Win32 Release"
 
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ""
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O1 /Ob1 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /Zl /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
 
!ELSEIF "$(CFG)" == "lzmapack - Win32 Debug"
 
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ""
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
 
!ENDIF
 
# Begin Target
 
# Name "lzmapack - Win32 Release"
# Name "lzmapack - Win32 Debug"
# Begin Group "Source Files"
 
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
 
SOURCE=.\LZMAEncoder.c
# End Source File
# Begin Source File
 
SOURCE=.\MatchFinder.c
# End Source File
# Begin Source File
 
SOURCE=.\RangeCoder.c
# End Source File
# End Group
# Begin Group "Header Files"
 
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
 
SOURCE=.\common.h
# End Source File
# Begin Source File
 
SOURCE=.\lzma.h
# End Source File
# Begin Source File
 
SOURCE=.\LZMAEncoder.h
# End Source File
# Begin Source File
 
SOURCE=.\MatchFinder.h
# End Source File
# Begin Source File
 
SOURCE=.\RangeCoder.h
# End Source File
# Begin Source File
 
SOURCE=.\RangeCoderBit.h
# End Source File
# Begin Source File
 
SOURCE=.\RangeCoderBitTree.h
# End Source File
# End Group
# End Target
# End Project
/programs/other/kpack/kerpack_linux/lzma_c/lzmapack.dsw
0,0 → 1,44
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
 
###############################################################################
 
Project: "lzmapack"=.\lzmapack.dsp - Package Owner=<4>
 
Package=<5>
{{{
}}}
 
Package=<4>
{{{
}}}
 
###############################################################################
 
Project: "lzmatest"=.\lzmatest\lzmatest.dsp - Package Owner=<4>
 
Package=<5>
{{{
}}}
 
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name lzmapack
End Project Dependency
}}}
 
###############################################################################
 
Global:
 
Package=<5>
{{{
}}}
 
Package=<3>
{{{
}}}
 
###############################################################################
 
/programs/other/kpack/kerpack_linux/lzma_c/lzmatest/lzmatest.dsp
0,0 → 1,102
# Microsoft Developer Studio Project File - Name="lzmatest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
 
# TARGTYPE "Win32 (x86) Console Application" 0x0103
 
CFG=lzmatest - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "lzmatest.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "lzmatest.mak" CFG="lzmatest - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "lzmatest - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "lzmatest - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
 
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
 
!IF "$(CFG)" == "lzmatest - Win32 Release"
 
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib ..\lzmapack.lib /nologo /subsystem:console /machine:I386
 
!ELSEIF "$(CFG)" == "lzmatest - Win32 Debug"
 
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib ..\lzmapack.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
 
!ENDIF
 
# Begin Target
 
# Name "lzmatest - Win32 Release"
# Name "lzmatest - Win32 Debug"
# Begin Group "Source Files"
 
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
 
SOURCE=.\main.cpp
# End Source File
# End Group
# Begin Group "Header Files"
 
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
 
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
/programs/other/kpack/kerpack_linux/lzma_c/lzmatest/main.cpp
0,0 → 1,31
#include <stdio.h>
#include <windows.h>
extern "C" __stdcall lzma_set_dict_size(unsigned logdictsize);
extern "C" __stdcall lzma_compress(
const void* source,
void* destination,
unsigned length,
void* workmem);
 
int main()
{
FILE* f;
f = fopen("test.in","rb");
fseek(f,0,SEEK_END);
unsigned inlen = ftell(f);
fseek(f,0,SEEK_SET);
void* in = VirtualAlloc(NULL,inlen,MEM_COMMIT,PAGE_READWRITE);
void* out = VirtualAlloc(NULL,inlen,MEM_COMMIT,PAGE_READWRITE);
fread(in,1,inlen,f);
fclose(f);
unsigned logdictsize,dictsize;
for (logdictsize=0,dictsize=1;dictsize<inlen && logdictsize<=28;logdictsize++,dictsize<<=1) ;
lzma_set_dict_size(logdictsize);
void* work = VirtualAlloc(NULL,dictsize*19/2+0x509000,MEM_COMMIT,PAGE_READWRITE);
unsigned outlen = lzma_compress(in,out,inlen,work);
printf("%d -> %d\n",inlen,outlen);
f = fopen("test.out","wb");
fwrite(out,1,outlen,f);
fclose(f);
return 0;
}
/programs/other/kpack/kerpack_linux/lzma_c/readme.txt
0,0 → 1,44
 ýòîì êàòàëîãå íàõîäèòñÿ óïðîùåííàÿ ïåðåïèñàííàÿ íà C ìíîþ, diamond'îì, âåðñèÿ
LZMA-óïàêîâùèêà. Îðèãèíàëüíûé LZMA SDK 4.32 ÿâëÿåòñÿ copyright (c) 1999-2005
Igor Pavlov, ìîæåò áûòü ïîëó÷åí íà ñòðàíèöå http://www.7-zip.org/sdk.html,
ñîäåðæèò, â ÷àñòíîñòè, âåðñèè èñõîäíîãî êîäà íà C++,C# è Java äëÿ óïàêîâêè è
ðàñïàêîâêè, êîä LZMA-ðàñïàêîâêè íà ANSI-C, îïèñàíèå ôîðìàòà 7z.
 
Ýòà âåðñèÿ íå ÿâëÿåòñÿ áåçîïàñíîé â ìíîãîïîòî÷íîé ñðåäå, ïîääåðæèâàåò òîëüêî
bt4 match-finder, íåêîòîðûå ïàðàìåòðû óïàêîâêè çàôèêñèðîâàíû (âïðî÷åì, ýòî ïðè
íåîáõîäèìîñòè ëåãêî ìîäèôèöèðîâàòü), ïîääåðæèâàåòñÿ òîëüêî ñæàòèå äàííûõ â
îïåðàòèâíîé ïàìÿòè. (Ýòèõ îãðàíè÷åíèé íåò â îðèãèíàëüíîì LZMA
SDK.) Ýòà âåðñèÿ íå îáÿçàíà êîìïèëèðîâàòüñÿ ëþáûì êîìïèëÿòîðîì, èáî ÿ èñïîëüçóþ
òîëüêî VC++, õîòÿ åäèíñòâåííîå èçâåñòíîå ìíå îòêëîíåíèå îò ANSI C ñîñòîèò â
èñïîëüçîâàíèè VC-ñïåöèôè÷íîé äèðåêòèâû #pragma intrinsic(memcpy), íåîáõîäèìîé,
÷òîáû memcpy áûëà âñòðîåíà ïðÿìî â êîä - â ðåçóëüòàòå áèáëèîòåêà íå ññûëàåòñÿ
íè íà îäíó èç ôóíêöèé C run-time library. (Ìíå ýòî íåîáõîäèìî, ïîñêîëüêó
áèáëèîòåêà èñïîëüçóåòñÿ â àññåìáëåðíîé ïðîãðàììå MtApPack, íå èñïîëüçóþùåé
RTL è ê òîìó æå ñóùåñòâóþùåé è äëÿ Windows, è äëÿ Kolibri.)
 
Ýòà áèáëèîòåêà, êàê è îðèãèíàëüíûé LZMA SDK, ìîæåò áûòü èñïîëüçîâàíà â äðóãèõ
ïðîãðàììàõ â ñîîòâåòñòâèè ñ îäíîé èç ëèöåíçèé (íà âàø âûáîð) GNU LGPL èëè
GNU CPL. (Îðèãèíàëüíûé SDK òàêæå äîïóñêàåò èñïîëüçîâàíèå îðèãèíàëüíîé
áèáëèîòåêè áåç îãðàíè÷åíèé ïðè óñëîâèè èñïîëüçîâàíèÿ îáúåêòíûõ ôàéëîâ áåç
ìîäèôèêàöèè êîäà, íà äàííóþ âåðñèþ ýòî íå ðàñïðîñòðàíÿåòñÿ.)
 
Ýêñïîðòèðóþòñÿ äâå ôóíêöèè: â C++-ñòèëå îáúÿâëåíèå âûãëÿäèò òàê:
extern "C" __stdcall void lzma_set_dict_size(unsigned logdictsize);
extern "C" __stdcall unsigned lzma_compress(
const void* source,
void* destination,
unsigned length,
void* workmem);
 
Ïåðåä óïàêîâêîé òðåáóåòñÿ óñòàíîâèòü ðàçìåð ñëîâàðÿ ïåðâîé èç ýòèõ ôóíêöèé,
ïðèíèìàþùåé ëîãàðèôì ïî îñíîâàíèþ 2 ýòîãî çíà÷åíèÿ
(ò.å. dictsize == (1<<logdictsize)). Ìàêñèìàëüíûé ðàçìåð áóôåðà ðàâåí 256Mb,
òàê ÷òî ïàðàìåòð logdictsize íå äîëæåí ïðåâîñõîäèòü 28. Åñëè ðàçìåð áóôåðà
áîëüøå ðàçìåðà âõîäíûõ äàííûõ, òî ðåçóëüòàò íå çàâèñèò îò ðàçìåðà áóôåðà,
ò.å. äëÿ äàííûõ ðàçìåðîì 12345 áàéò ðåçóëüòàòû ñæàòèÿ ñ áóôåðîì íà 16384 áàéò è
íà 1 ìåãàáàéò îäèíàêîâû.
Óïàêîâêà ïðîèçâîäèòñÿ âûçîâîì âòîðîé èç ýòèõ ôóíêöèé. source - óêàçàòåëü íà
âõîäíûå äàííûå, destination - óêàçàòåëü íà áóôåð äëÿ óïàêîâàííûõ äàííûõ,
length - äëèíà âõîäíûõ äàííûõ, workmem - óêàçàòåëü íà âðåìåííóþ ïàìÿòü,
èñïîëüçóåìóþ óïàêîâùèêîì; äîëæíî áûòü âûäåëåíî íå ìåíåå 0x509000+dictsize*19/2
áàéò. Äëÿ óïàêîâàííûõ äàííûõ â õóäøåì ñëó÷àå äîñòàòî÷íî 0x10 + length*9/8 áàéò.