Normalize all the line endings

This commit is contained in:
Tino Reichardt
2020-05-31 13:08:03 +02:00
parent d8345ee3b3
commit 9c3c277ad7
1156 changed files with 292304 additions and 292304 deletions

View File

@@ -1,100 +1,100 @@
CODE32 CODE32
EXPORT |CrcUpdateT4@16| EXPORT |CrcUpdateT4@16|
AREA |.text|, CODE, ARM AREA |.text|, CODE, ARM
MACRO MACRO
CRC32_STEP_1 CRC32_STEP_1
ldrb r4, [r1], #1 ldrb r4, [r1], #1
subs r2, r2, #1 subs r2, r2, #1
eor r4, r4, r0 eor r4, r4, r0
and r4, r4, #0xFF and r4, r4, #0xFF
ldr r4, [r3, +r4, lsl #2] ldr r4, [r3, +r4, lsl #2]
eor r0, r4, r0, lsr #8 eor r0, r4, r0, lsr #8
MEND MEND
MACRO MACRO
CRC32_STEP_4 $STREAM_WORD CRC32_STEP_4 $STREAM_WORD
eor r7, r7, r8 eor r7, r7, r8
eor r7, r7, r9 eor r7, r7, r9
eor r0, r0, r7 eor r0, r0, r7
eor r0, r0, $STREAM_WORD eor r0, r0, $STREAM_WORD
ldr $STREAM_WORD, [r1], #4 ldr $STREAM_WORD, [r1], #4
and r7, r0, #0xFF and r7, r0, #0xFF
and r8, r0, #0xFF00 and r8, r0, #0xFF00
and r9, r0, #0xFF0000 and r9, r0, #0xFF0000
and r0, r0, #0xFF000000 and r0, r0, #0xFF000000
ldr r7, [r6, +r7, lsl #2] ldr r7, [r6, +r7, lsl #2]
ldr r8, [r5, +r8, lsr #6] ldr r8, [r5, +r8, lsr #6]
ldr r9, [r4, +r9, lsr #14] ldr r9, [r4, +r9, lsr #14]
ldr r0, [r3, +r0, lsr #22] ldr r0, [r3, +r0, lsr #22]
MEND MEND
|CrcUpdateT4@16| PROC |CrcUpdateT4@16| PROC
stmdb sp!, {r4-r11, lr} stmdb sp!, {r4-r11, lr}
cmp r2, #0 cmp r2, #0
beq |$fin| beq |$fin|
|$v1| |$v1|
tst r1, #7 tst r1, #7
beq |$v2| beq |$v2|
CRC32_STEP_1 CRC32_STEP_1
bne |$v1| bne |$v1|
|$v2| |$v2|
cmp r2, #16 cmp r2, #16
blo |$v3| blo |$v3|
ldr r10, [r1], #4 ldr r10, [r1], #4
ldr r11, [r1], #4 ldr r11, [r1], #4
add r4, r3, #0x400 add r4, r3, #0x400
add r5, r3, #0x800 add r5, r3, #0x800
add r6, r3, #0xC00 add r6, r3, #0xC00
mov r7, #0 mov r7, #0
mov r8, #0 mov r8, #0
mov r9, #0 mov r9, #0
sub r2, r2, #16 sub r2, r2, #16
|$loop| |$loop|
; pld [r1, #0x40] ; pld [r1, #0x40]
CRC32_STEP_4 r10 CRC32_STEP_4 r10
CRC32_STEP_4 r11 CRC32_STEP_4 r11
subs r2, r2, #8 subs r2, r2, #8
bhs |$loop| bhs |$loop|
sub r1, r1, #8 sub r1, r1, #8
add r2, r2, #16 add r2, r2, #16
eor r7, r7, r8 eor r7, r7, r8
eor r7, r7, r9 eor r7, r7, r9
eor r0, r0, r7 eor r0, r0, r7
|$v3| |$v3|
cmp r2, #0 cmp r2, #0
beq |$fin| beq |$fin|
|$v4| |$v4|
CRC32_STEP_1 CRC32_STEP_1
bne |$v4| bne |$v4|
|$fin| |$fin|
ldmia sp!, {r4-r11, pc} ldmia sp!, {r4-r11, pc}
|CrcUpdateT4@16| ENDP |CrcUpdateT4@16| ENDP
END END

View File

@@ -1,147 +1,147 @@
; 7zAsm.asm -- ASM macros ; 7zAsm.asm -- ASM macros
; 2018-02-03 : Igor Pavlov : Public domain ; 2018-02-03 : Igor Pavlov : Public domain
MY_ASM_START macro MY_ASM_START macro
ifdef x64 ifdef x64
.code .code
else else
.386 .386
.model flat .model flat
_TEXT$00 SEGMENT PARA PUBLIC 'CODE' _TEXT$00 SEGMENT PARA PUBLIC 'CODE'
endif endif
endm endm
MY_PROC macro name:req, numParams:req MY_PROC macro name:req, numParams:req
align 16 align 16
proc_numParams = numParams proc_numParams = numParams
ifdef x64 ifdef x64
proc_name equ name proc_name equ name
else else
proc_name equ @CatStr(@,name,@, %numParams * 4) proc_name equ @CatStr(@,name,@, %numParams * 4)
endif endif
proc_name PROC proc_name PROC
endm endm
MY_ENDP macro MY_ENDP macro
ifdef x64 ifdef x64
ret ret
else else
if proc_numParams LT 3 if proc_numParams LT 3
ret ret
else else
ret (proc_numParams - 2) * 4 ret (proc_numParams - 2) * 4
endif endif
endif endif
proc_name ENDP proc_name ENDP
endm endm
ifdef x64 ifdef x64
REG_SIZE equ 8 REG_SIZE equ 8
REG_LOGAR_SIZE equ 3 REG_LOGAR_SIZE equ 3
else else
REG_SIZE equ 4 REG_SIZE equ 4
REG_LOGAR_SIZE equ 2 REG_LOGAR_SIZE equ 2
endif endif
x0 equ EAX x0 equ EAX
x1 equ ECX x1 equ ECX
x2 equ EDX x2 equ EDX
x3 equ EBX x3 equ EBX
x4 equ ESP x4 equ ESP
x5 equ EBP x5 equ EBP
x6 equ ESI x6 equ ESI
x7 equ EDI x7 equ EDI
x0_W equ AX x0_W equ AX
x1_W equ CX x1_W equ CX
x2_W equ DX x2_W equ DX
x3_W equ BX x3_W equ BX
x5_W equ BP x5_W equ BP
x6_W equ SI x6_W equ SI
x7_W equ DI x7_W equ DI
x0_L equ AL x0_L equ AL
x1_L equ CL x1_L equ CL
x2_L equ DL x2_L equ DL
x3_L equ BL x3_L equ BL
x0_H equ AH x0_H equ AH
x1_H equ CH x1_H equ CH
x2_H equ DH x2_H equ DH
x3_H equ BH x3_H equ BH
ifdef x64 ifdef x64
x5_L equ BPL x5_L equ BPL
x6_L equ SIL x6_L equ SIL
x7_L equ DIL x7_L equ DIL
r0 equ RAX r0 equ RAX
r1 equ RCX r1 equ RCX
r2 equ RDX r2 equ RDX
r3 equ RBX r3 equ RBX
r4 equ RSP r4 equ RSP
r5 equ RBP r5 equ RBP
r6 equ RSI r6 equ RSI
r7 equ RDI r7 equ RDI
x8 equ r8d x8 equ r8d
x9 equ r9d x9 equ r9d
x10 equ r10d x10 equ r10d
x11 equ r11d x11 equ r11d
x12 equ r12d x12 equ r12d
x13 equ r13d x13 equ r13d
x14 equ r14d x14 equ r14d
x15 equ r15d x15 equ r15d
else else
r0 equ x0 r0 equ x0
r1 equ x1 r1 equ x1
r2 equ x2 r2 equ x2
r3 equ x3 r3 equ x3
r4 equ x4 r4 equ x4
r5 equ x5 r5 equ x5
r6 equ x6 r6 equ x6
r7 equ x7 r7 equ x7
endif endif
MY_PUSH_4_REGS macro MY_PUSH_4_REGS macro
push r3 push r3
push r5 push r5
push r6 push r6
push r7 push r7
endm endm
MY_POP_4_REGS macro MY_POP_4_REGS macro
pop r7 pop r7
pop r6 pop r6
pop r5 pop r5
pop r3 pop r3
endm endm
ifdef x64 ifdef x64
; for WIN64-x64 ABI: ; for WIN64-x64 ABI:
REG_PARAM_0 equ r1 REG_PARAM_0 equ r1
REG_PARAM_1 equ r2 REG_PARAM_1 equ r2
REG_PARAM_2 equ r8 REG_PARAM_2 equ r8
REG_PARAM_3 equ r9 REG_PARAM_3 equ r9
MY_PUSH_PRESERVED_REGS macro MY_PUSH_PRESERVED_REGS macro
MY_PUSH_4_REGS MY_PUSH_4_REGS
push r12 push r12
push r13 push r13
push r14 push r14
push r15 push r15
endm endm
MY_POP_PRESERVED_REGS macro MY_POP_PRESERVED_REGS macro
pop r15 pop r15
pop r14 pop r14
pop r13 pop r13
pop r12 pop r12
MY_POP_4_REGS MY_POP_4_REGS
endm endm
endif endif

View File

@@ -1,147 +1,147 @@
; 7zCrcOpt.asm -- CRC32 calculation : optimized version ; 7zCrcOpt.asm -- CRC32 calculation : optimized version
; 2009-12-12 : Igor Pavlov : Public domain ; 2009-12-12 : Igor Pavlov : Public domain
include 7zAsm.asm include 7zAsm.asm
MY_ASM_START MY_ASM_START
rD equ r2 rD equ r2
rN equ r7 rN equ r7
ifdef x64 ifdef x64
num_VAR equ r8 num_VAR equ r8
table_VAR equ r9 table_VAR equ r9
else else
data_size equ (REG_SIZE * 5) data_size equ (REG_SIZE * 5)
crc_table equ (REG_SIZE + data_size) crc_table equ (REG_SIZE + data_size)
num_VAR equ [r4 + data_size] num_VAR equ [r4 + data_size]
table_VAR equ [r4 + crc_table] table_VAR equ [r4 + crc_table]
endif endif
SRCDAT equ rN + rD + 4 * SRCDAT equ rN + rD + 4 *
CRC macro op:req, dest:req, src:req, t:req CRC macro op:req, dest:req, src:req, t:req
op dest, DWORD PTR [r5 + src * 4 + 0400h * t] op dest, DWORD PTR [r5 + src * 4 + 0400h * t]
endm endm
CRC_XOR macro dest:req, src:req, t:req CRC_XOR macro dest:req, src:req, t:req
CRC xor, dest, src, t CRC xor, dest, src, t
endm endm
CRC_MOV macro dest:req, src:req, t:req CRC_MOV macro dest:req, src:req, t:req
CRC mov, dest, src, t CRC mov, dest, src, t
endm endm
CRC1b macro CRC1b macro
movzx x6, BYTE PTR [rD] movzx x6, BYTE PTR [rD]
inc rD inc rD
movzx x3, x0_L movzx x3, x0_L
xor x6, x3 xor x6, x3
shr x0, 8 shr x0, 8
CRC xor, x0, r6, 0 CRC xor, x0, r6, 0
dec rN dec rN
endm endm
MY_PROLOG macro crc_end:req MY_PROLOG macro crc_end:req
MY_PUSH_4_REGS MY_PUSH_4_REGS
mov x0, x1 mov x0, x1
mov rN, num_VAR mov rN, num_VAR
mov r5, table_VAR mov r5, table_VAR
test rN, rN test rN, rN
jz crc_end jz crc_end
@@: @@:
test rD, 7 test rD, 7
jz @F jz @F
CRC1b CRC1b
jnz @B jnz @B
@@: @@:
cmp rN, 16 cmp rN, 16
jb crc_end jb crc_end
add rN, rD add rN, rD
mov num_VAR, rN mov num_VAR, rN
sub rN, 8 sub rN, 8
and rN, NOT 7 and rN, NOT 7
sub rD, rN sub rD, rN
xor x0, [SRCDAT 0] xor x0, [SRCDAT 0]
endm endm
MY_EPILOG macro crc_end:req MY_EPILOG macro crc_end:req
xor x0, [SRCDAT 0] xor x0, [SRCDAT 0]
mov rD, rN mov rD, rN
mov rN, num_VAR mov rN, num_VAR
sub rN, rD sub rN, rD
crc_end: crc_end:
test rN, rN test rN, rN
jz @F jz @F
CRC1b CRC1b
jmp crc_end jmp crc_end
@@: @@:
MY_POP_4_REGS MY_POP_4_REGS
endm endm
MY_PROC CrcUpdateT8, 4 MY_PROC CrcUpdateT8, 4
MY_PROLOG crc_end_8 MY_PROLOG crc_end_8
mov x1, [SRCDAT 1] mov x1, [SRCDAT 1]
align 16 align 16
main_loop_8: main_loop_8:
mov x6, [SRCDAT 2] mov x6, [SRCDAT 2]
movzx x3, x1_L movzx x3, x1_L
CRC_XOR x6, r3, 3 CRC_XOR x6, r3, 3
movzx x3, x1_H movzx x3, x1_H
CRC_XOR x6, r3, 2 CRC_XOR x6, r3, 2
shr x1, 16 shr x1, 16
movzx x3, x1_L movzx x3, x1_L
movzx x1, x1_H movzx x1, x1_H
CRC_XOR x6, r3, 1 CRC_XOR x6, r3, 1
movzx x3, x0_L movzx x3, x0_L
CRC_XOR x6, r1, 0 CRC_XOR x6, r1, 0
mov x1, [SRCDAT 3] mov x1, [SRCDAT 3]
CRC_XOR x6, r3, 7 CRC_XOR x6, r3, 7
movzx x3, x0_H movzx x3, x0_H
shr x0, 16 shr x0, 16
CRC_XOR x6, r3, 6 CRC_XOR x6, r3, 6
movzx x3, x0_L movzx x3, x0_L
CRC_XOR x6, r3, 5 CRC_XOR x6, r3, 5
movzx x3, x0_H movzx x3, x0_H
CRC_MOV x0, r3, 4 CRC_MOV x0, r3, 4
xor x0, x6 xor x0, x6
add rD, 8 add rD, 8
jnz main_loop_8 jnz main_loop_8
MY_EPILOG crc_end_8 MY_EPILOG crc_end_8
MY_ENDP MY_ENDP
MY_PROC CrcUpdateT4, 4 MY_PROC CrcUpdateT4, 4
MY_PROLOG crc_end_4 MY_PROLOG crc_end_4
align 16 align 16
main_loop_4: main_loop_4:
movzx x1, x0_L movzx x1, x0_L
movzx x3, x0_H movzx x3, x0_H
shr x0, 16 shr x0, 16
movzx x6, x0_H movzx x6, x0_H
and x0, 0FFh and x0, 0FFh
CRC_MOV x1, r1, 3 CRC_MOV x1, r1, 3
xor x1, [SRCDAT 1] xor x1, [SRCDAT 1]
CRC_XOR x1, r3, 2 CRC_XOR x1, r3, 2
CRC_XOR x1, r6, 0 CRC_XOR x1, r6, 0
CRC_XOR x1, r0, 1 CRC_XOR x1, r0, 1
movzx x0, x1_L movzx x0, x1_L
movzx x3, x1_H movzx x3, x1_H
shr x1, 16 shr x1, 16
movzx x6, x1_H movzx x6, x1_H
and x1, 0FFh and x1, 0FFh
CRC_MOV x0, r0, 3 CRC_MOV x0, r0, 3
xor x0, [SRCDAT 2] xor x0, [SRCDAT 2]
CRC_XOR x0, r3, 2 CRC_XOR x0, r3, 2
CRC_XOR x0, r6, 0 CRC_XOR x0, r6, 0
CRC_XOR x0, r1, 1 CRC_XOR x0, r1, 1
add rD, 8 add rD, 8
jnz main_loop_4 jnz main_loop_4
MY_EPILOG crc_end_4 MY_EPILOG crc_end_4
MY_ENDP MY_ENDP
end end

View File

@@ -1,237 +1,237 @@
; AesOpt.asm -- Intel's AES. ; AesOpt.asm -- Intel's AES.
; 2009-12-12 : Igor Pavlov : Public domain ; 2009-12-12 : Igor Pavlov : Public domain
include 7zAsm.asm include 7zAsm.asm
MY_ASM_START MY_ASM_START
ifndef x64 ifndef x64
.xmm .xmm
endif endif
ifdef x64 ifdef x64
num equ r8 num equ r8
else else
num equ [r4 + REG_SIZE * 4] num equ [r4 + REG_SIZE * 4]
endif endif
rD equ r2 rD equ r2
rN equ r0 rN equ r0
MY_PROLOG macro reg:req MY_PROLOG macro reg:req
ifdef x64 ifdef x64
movdqa [r4 + 8], xmm6 movdqa [r4 + 8], xmm6
movdqa [r4 + 8 + 16], xmm7 movdqa [r4 + 8 + 16], xmm7
endif endif
push r3 push r3
push r5 push r5
push r6 push r6
mov rN, num mov rN, num
mov x6, [r1 + 16] mov x6, [r1 + 16]
shl x6, 5 shl x6, 5
movdqa reg, [r1] movdqa reg, [r1]
add r1, 32 add r1, 32
endm endm
MY_EPILOG macro MY_EPILOG macro
pop r6 pop r6
pop r5 pop r5
pop r3 pop r3
ifdef x64 ifdef x64
movdqa xmm6, [r4 + 8] movdqa xmm6, [r4 + 8]
movdqa xmm7, [r4 + 8 + 16] movdqa xmm7, [r4 + 8 + 16]
endif endif
MY_ENDP MY_ENDP
endm endm
ways equ 4 ways equ 4
ways16 equ (ways * 16) ways16 equ (ways * 16)
OP_W macro op, op2 OP_W macro op, op2
i = 0 i = 0
rept ways rept ways
op @CatStr(xmm,%i), op2 op @CatStr(xmm,%i), op2
i = i + 1 i = i + 1
endm endm
endm endm
LOAD_OP macro op:req, offs:req LOAD_OP macro op:req, offs:req
op xmm0, [r1 + r3 offs] op xmm0, [r1 + r3 offs]
endm endm
LOAD_OP_W macro op:req, offs:req LOAD_OP_W macro op:req, offs:req
movdqa xmm7, [r1 + r3 offs] movdqa xmm7, [r1 + r3 offs]
OP_W op, xmm7 OP_W op, xmm7
endm endm
; ---------- AES-CBC Decode ---------- ; ---------- AES-CBC Decode ----------
CBC_DEC_UPDATE macro reg, offs CBC_DEC_UPDATE macro reg, offs
pxor reg, xmm6 pxor reg, xmm6
movdqa xmm6, [rD + offs] movdqa xmm6, [rD + offs]
movdqa [rD + offs], reg movdqa [rD + offs], reg
endm endm
DECODE macro op:req DECODE macro op:req
op aesdec, +16 op aesdec, +16
@@: @@:
op aesdec, +0 op aesdec, +0
op aesdec, -16 op aesdec, -16
sub x3, 32 sub x3, 32
jnz @B jnz @B
op aesdeclast, +0 op aesdeclast, +0
endm endm
MY_PROC AesCbc_Decode_Intel, 3 MY_PROC AesCbc_Decode_Intel, 3
MY_PROLOG xmm6 MY_PROLOG xmm6
sub x6, 32 sub x6, 32
jmp check2 jmp check2
align 16 align 16
nextBlocks2: nextBlocks2:
mov x3, x6 mov x3, x6
OP_W movdqa, [rD + i * 16] OP_W movdqa, [rD + i * 16]
LOAD_OP_W pxor, +32 LOAD_OP_W pxor, +32
DECODE LOAD_OP_W DECODE LOAD_OP_W
OP_W CBC_DEC_UPDATE, i * 16 OP_W CBC_DEC_UPDATE, i * 16
add rD, ways16 add rD, ways16
check2: check2:
sub rN, ways sub rN, ways
jnc nextBlocks2 jnc nextBlocks2
add rN, ways add rN, ways
jmp check jmp check
nextBlock: nextBlock:
mov x3, x6 mov x3, x6
movdqa xmm1, [rD] movdqa xmm1, [rD]
LOAD_OP movdqa, +32 LOAD_OP movdqa, +32
pxor xmm0, xmm1 pxor xmm0, xmm1
DECODE LOAD_OP DECODE LOAD_OP
pxor xmm0, xmm6 pxor xmm0, xmm6
movdqa [rD], xmm0 movdqa [rD], xmm0
movdqa xmm6, xmm1 movdqa xmm6, xmm1
add rD, 16 add rD, 16
check: check:
sub rN, 1 sub rN, 1
jnc nextBlock jnc nextBlock
movdqa [r1 - 32], xmm6 movdqa [r1 - 32], xmm6
MY_EPILOG MY_EPILOG
; ---------- AES-CBC Encode ---------- ; ---------- AES-CBC Encode ----------
ENCODE macro op:req ENCODE macro op:req
op aesenc, -16 op aesenc, -16
@@: @@:
op aesenc, +0 op aesenc, +0
op aesenc, +16 op aesenc, +16
add r3, 32 add r3, 32
jnz @B jnz @B
op aesenclast, +0 op aesenclast, +0
endm endm
MY_PROC AesCbc_Encode_Intel, 3 MY_PROC AesCbc_Encode_Intel, 3
MY_PROLOG xmm0 MY_PROLOG xmm0
add r1, r6 add r1, r6
neg r6 neg r6
add r6, 32 add r6, 32
jmp check_e jmp check_e
align 16 align 16
nextBlock_e: nextBlock_e:
mov r3, r6 mov r3, r6
pxor xmm0, [rD] pxor xmm0, [rD]
pxor xmm0, [r1 + r3 - 32] pxor xmm0, [r1 + r3 - 32]
ENCODE LOAD_OP ENCODE LOAD_OP
movdqa [rD], xmm0 movdqa [rD], xmm0
add rD, 16 add rD, 16
check_e: check_e:
sub rN, 1 sub rN, 1
jnc nextBlock_e jnc nextBlock_e
movdqa [r1 + r6 - 64], xmm0 movdqa [r1 + r6 - 64], xmm0
MY_EPILOG MY_EPILOG
; ---------- AES-CTR ---------- ; ---------- AES-CTR ----------
XOR_UPD_1 macro reg, offs XOR_UPD_1 macro reg, offs
pxor reg, [rD + offs] pxor reg, [rD + offs]
endm endm
XOR_UPD_2 macro reg, offs XOR_UPD_2 macro reg, offs
movdqa [rD + offs], reg movdqa [rD + offs], reg
endm endm
MY_PROC AesCtr_Code_Intel, 3 MY_PROC AesCtr_Code_Intel, 3
MY_PROLOG xmm6 MY_PROLOG xmm6
mov r5, r4 mov r5, r4
shr r5, 4 shr r5, 4
dec r5 dec r5
shl r5, 4 shl r5, 4
mov DWORD PTR [r5], 1 mov DWORD PTR [r5], 1
mov DWORD PTR [r5 + 4], 0 mov DWORD PTR [r5 + 4], 0
mov DWORD PTR [r5 + 8], 0 mov DWORD PTR [r5 + 8], 0
mov DWORD PTR [r5 + 12], 0 mov DWORD PTR [r5 + 12], 0
add r1, r6 add r1, r6
neg r6 neg r6
add r6, 32 add r6, 32
jmp check2_c jmp check2_c
align 16 align 16
nextBlocks2_c: nextBlocks2_c:
movdqa xmm7, [r5] movdqa xmm7, [r5]
i = 0 i = 0
rept ways rept ways
paddq xmm6, xmm7 paddq xmm6, xmm7
movdqa @CatStr(xmm,%i), xmm6 movdqa @CatStr(xmm,%i), xmm6
i = i + 1 i = i + 1
endm endm
mov r3, r6 mov r3, r6
LOAD_OP_W pxor, -32 LOAD_OP_W pxor, -32
ENCODE LOAD_OP_W ENCODE LOAD_OP_W
OP_W XOR_UPD_1, i * 16 OP_W XOR_UPD_1, i * 16
OP_W XOR_UPD_2, i * 16 OP_W XOR_UPD_2, i * 16
add rD, ways16 add rD, ways16
check2_c: check2_c:
sub rN, ways sub rN, ways
jnc nextBlocks2_c jnc nextBlocks2_c
add rN, ways add rN, ways
jmp check_c jmp check_c
nextBlock_c: nextBlock_c:
paddq xmm6, [r5] paddq xmm6, [r5]
mov r3, r6 mov r3, r6
movdqa xmm0, [r1 + r3 - 32] movdqa xmm0, [r1 + r3 - 32]
pxor xmm0, xmm6 pxor xmm0, xmm6
ENCODE LOAD_OP ENCODE LOAD_OP
XOR_UPD_1 xmm0, 0 XOR_UPD_1 xmm0, 0
XOR_UPD_2 xmm0, 0 XOR_UPD_2 xmm0, 0
add rD, 16 add rD, 16
check_c: check_c:
sub rN, 1 sub rN, 1
jnc nextBlock_c jnc nextBlock_c
movdqa [r1 + r6 - 64], xmm6 movdqa [r1 + r6 - 64], xmm6
MY_EPILOG MY_EPILOG
end end

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,205 +1,205 @@
; XzCrc64Opt.asm -- CRC64 calculation : optimized version ; XzCrc64Opt.asm -- CRC64 calculation : optimized version
; 2011-06-28 : Igor Pavlov : Public domain ; 2011-06-28 : Igor Pavlov : Public domain
include 7zAsm.asm include 7zAsm.asm
MY_ASM_START MY_ASM_START
ifdef x64 ifdef x64
rD equ r9 rD equ r9
rN equ r10 rN equ r10
num_VAR equ r8 num_VAR equ r8
table_VAR equ r9 table_VAR equ r9
SRCDAT equ rN + rD SRCDAT equ rN + rD
CRC_XOR macro dest:req, src:req, t:req CRC_XOR macro dest:req, src:req, t:req
xor dest, QWORD PTR [r5 + src * 8 + 0800h * t] xor dest, QWORD PTR [r5 + src * 8 + 0800h * t]
endm endm
CRC1b macro CRC1b macro
movzx x6, BYTE PTR [rD] movzx x6, BYTE PTR [rD]
inc rD inc rD
movzx x3, x0_L movzx x3, x0_L
xor x6, x3 xor x6, x3
shr r0, 8 shr r0, 8
CRC_XOR r0, r6, 0 CRC_XOR r0, r6, 0
dec rN dec rN
endm endm
MY_PROLOG macro crc_end:req MY_PROLOG macro crc_end:req
MY_PUSH_4_REGS MY_PUSH_4_REGS
mov r0, r1 mov r0, r1
mov rN, num_VAR mov rN, num_VAR
mov r5, table_VAR mov r5, table_VAR
mov rD, r2 mov rD, r2
test rN, rN test rN, rN
jz crc_end jz crc_end
@@: @@:
test rD, 3 test rD, 3
jz @F jz @F
CRC1b CRC1b
jnz @B jnz @B
@@: @@:
cmp rN, 8 cmp rN, 8
jb crc_end jb crc_end
add rN, rD add rN, rD
mov num_VAR, rN mov num_VAR, rN
sub rN, 4 sub rN, 4
and rN, NOT 3 and rN, NOT 3
sub rD, rN sub rD, rN
mov x1, [SRCDAT] mov x1, [SRCDAT]
xor r0, r1 xor r0, r1
add rN, 4 add rN, 4
endm endm
MY_EPILOG macro crc_end:req MY_EPILOG macro crc_end:req
sub rN, 4 sub rN, 4
mov x1, [SRCDAT] mov x1, [SRCDAT]
xor r0, r1 xor r0, r1
mov rD, rN mov rD, rN
mov rN, num_VAR mov rN, num_VAR
sub rN, rD sub rN, rD
crc_end: crc_end:
test rN, rN test rN, rN
jz @F jz @F
CRC1b CRC1b
jmp crc_end jmp crc_end
@@: @@:
MY_POP_4_REGS MY_POP_4_REGS
endm endm
MY_PROC XzCrc64UpdateT4, 4 MY_PROC XzCrc64UpdateT4, 4
MY_PROLOG crc_end_4 MY_PROLOG crc_end_4
align 16 align 16
main_loop_4: main_loop_4:
mov x1, [SRCDAT] mov x1, [SRCDAT]
movzx x2, x0_L movzx x2, x0_L
movzx x3, x0_H movzx x3, x0_H
shr r0, 16 shr r0, 16
movzx x6, x0_L movzx x6, x0_L
movzx x7, x0_H movzx x7, x0_H
shr r0, 16 shr r0, 16
CRC_XOR r1, r2, 3 CRC_XOR r1, r2, 3
CRC_XOR r0, r3, 2 CRC_XOR r0, r3, 2
CRC_XOR r1, r6, 1 CRC_XOR r1, r6, 1
CRC_XOR r0, r7, 0 CRC_XOR r0, r7, 0
xor r0, r1 xor r0, r1
add rD, 4 add rD, 4
jnz main_loop_4 jnz main_loop_4
MY_EPILOG crc_end_4 MY_EPILOG crc_end_4
MY_ENDP MY_ENDP
else else
rD equ r1 rD equ r1
rN equ r7 rN equ r7
crc_val equ (REG_SIZE * 5) crc_val equ (REG_SIZE * 5)
crc_table equ (8 + crc_val) crc_table equ (8 + crc_val)
table_VAR equ [r4 + crc_table] table_VAR equ [r4 + crc_table]
num_VAR equ table_VAR num_VAR equ table_VAR
SRCDAT equ rN + rD SRCDAT equ rN + rD
CRC macro op0:req, op1:req, dest0:req, dest1:req, src:req, t:req CRC macro op0:req, op1:req, dest0:req, dest1:req, src:req, t:req
op0 dest0, DWORD PTR [r5 + src * 8 + 0800h * t] op0 dest0, DWORD PTR [r5 + src * 8 + 0800h * t]
op1 dest1, DWORD PTR [r5 + src * 8 + 0800h * t + 4] op1 dest1, DWORD PTR [r5 + src * 8 + 0800h * t + 4]
endm endm
CRC_XOR macro dest0:req, dest1:req, src:req, t:req CRC_XOR macro dest0:req, dest1:req, src:req, t:req
CRC xor, xor, dest0, dest1, src, t CRC xor, xor, dest0, dest1, src, t
endm endm
CRC1b macro CRC1b macro
movzx x6, BYTE PTR [rD] movzx x6, BYTE PTR [rD]
inc rD inc rD
movzx x3, x0_L movzx x3, x0_L
xor x6, x3 xor x6, x3
shrd r0, r2, 8 shrd r0, r2, 8
shr r2, 8 shr r2, 8
CRC_XOR r0, r2, r6, 0 CRC_XOR r0, r2, r6, 0
dec rN dec rN
endm endm
MY_PROLOG macro crc_end:req MY_PROLOG macro crc_end:req
MY_PUSH_4_REGS MY_PUSH_4_REGS
mov rN, r2 mov rN, r2
mov x0, [r4 + crc_val] mov x0, [r4 + crc_val]
mov x2, [r4 + crc_val + 4] mov x2, [r4 + crc_val + 4]
mov r5, table_VAR mov r5, table_VAR
test rN, rN test rN, rN
jz crc_end jz crc_end
@@: @@:
test rD, 3 test rD, 3
jz @F jz @F
CRC1b CRC1b
jnz @B jnz @B
@@: @@:
cmp rN, 8 cmp rN, 8
jb crc_end jb crc_end
add rN, rD add rN, rD
mov num_VAR, rN mov num_VAR, rN
sub rN, 4 sub rN, 4
and rN, NOT 3 and rN, NOT 3
sub rD, rN sub rD, rN
xor r0, [SRCDAT] xor r0, [SRCDAT]
add rN, 4 add rN, 4
endm endm
MY_EPILOG macro crc_end:req MY_EPILOG macro crc_end:req
sub rN, 4 sub rN, 4
xor r0, [SRCDAT] xor r0, [SRCDAT]
mov rD, rN mov rD, rN
mov rN, num_VAR mov rN, num_VAR
sub rN, rD sub rN, rD
crc_end: crc_end:
test rN, rN test rN, rN
jz @F jz @F
CRC1b CRC1b
jmp crc_end jmp crc_end
@@: @@:
MY_POP_4_REGS MY_POP_4_REGS
endm endm
MY_PROC XzCrc64UpdateT4, 5 MY_PROC XzCrc64UpdateT4, 5
MY_PROLOG crc_end_4 MY_PROLOG crc_end_4
movzx x6, x0_L movzx x6, x0_L
align 16 align 16
main_loop_4: main_loop_4:
mov r3, [SRCDAT] mov r3, [SRCDAT]
xor r3, r2 xor r3, r2
CRC xor, mov, r3, r2, r6, 3 CRC xor, mov, r3, r2, r6, 3
movzx x6, x0_H movzx x6, x0_H
shr r0, 16 shr r0, 16
CRC_XOR r3, r2, r6, 2 CRC_XOR r3, r2, r6, 2
movzx x6, x0_L movzx x6, x0_L
movzx x0, x0_H movzx x0, x0_H
CRC_XOR r3, r2, r6, 1 CRC_XOR r3, r2, r6, 1
CRC_XOR r3, r2, r0, 0 CRC_XOR r3, r2, r0, 0
movzx x6, x3_L movzx x6, x3_L
mov r0, r3 mov r0, r3
add rD, 4 add rD, 4
jnz main_loop_4 jnz main_loop_4
MY_EPILOG crc_end_4 MY_EPILOG crc_end_4
MY_ENDP MY_ENDP
endif endif
end end

404
C/7z.h
View File

@@ -1,202 +1,202 @@
/* 7z.h -- 7z interface /* 7z.h -- 7z interface
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_H #ifndef __7Z_H
#define __7Z_H #define __7Z_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20 #define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6 #define k7zSignatureSize 6
extern const Byte k7zSignature[k7zSignatureSize]; extern const Byte k7zSignature[k7zSignatureSize];
typedef struct typedef struct
{ {
const Byte *Data; const Byte *Data;
size_t Size; size_t Size;
} CSzData; } CSzData;
/* CSzCoderInfo & CSzFolder support only default methods */ /* CSzCoderInfo & CSzFolder support only default methods */
typedef struct typedef struct
{ {
size_t PropsOffset; size_t PropsOffset;
UInt32 MethodID; UInt32 MethodID;
Byte NumStreams; Byte NumStreams;
Byte PropsSize; Byte PropsSize;
} CSzCoderInfo; } CSzCoderInfo;
typedef struct typedef struct
{ {
UInt32 InIndex; UInt32 InIndex;
UInt32 OutIndex; UInt32 OutIndex;
} CSzBond; } CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4 #define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3 #define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4 #define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
typedef struct typedef struct
{ {
UInt32 NumCoders; UInt32 NumCoders;
UInt32 NumBonds; UInt32 NumBonds;
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 UnpackStream; UInt32 UnpackStream;
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX]; CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder; } CSzFolder;
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd); SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct typedef struct
{ {
UInt32 Low; UInt32 Low;
UInt32 High; UInt32 High;
} CNtfsFileTime; } CNtfsFileTime;
typedef struct typedef struct
{ {
Byte *Defs; /* MSB 0 bit numbering */ Byte *Defs; /* MSB 0 bit numbering */
UInt32 *Vals; UInt32 *Vals;
} CSzBitUi32s; } CSzBitUi32s;
typedef struct typedef struct
{ {
Byte *Defs; /* MSB 0 bit numbering */ Byte *Defs; /* MSB 0 bit numbering */
// UInt64 *Vals; // UInt64 *Vals;
CNtfsFileTime *Vals; CNtfsFileTime *Vals;
} CSzBitUi64s; } CSzBitUi64s;
#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) #define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0) #define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
typedef struct typedef struct
{ {
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 NumFolders; UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1 UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs; // NumFolders CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets; // NumFolders + 1 size_t *FoCodersOffsets; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; // NumFolders + 1 UInt32 *FoStartPackStreamIndex; // NumFolders + 1
UInt32 *FoToCoderUnpackSizes; // NumFolders + 1 UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
Byte *FoToMainUnpackSizeIndex; // NumFolders Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders UInt64 *CoderUnpackSizes; // for all coders in all folders
Byte *CodersData; Byte *CodersData;
} CSzAr; } CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex); UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos, ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAllocPtr allocMain); ISzAllocPtr allocMain);
typedef struct typedef struct
{ {
CSzAr db; CSzAr db;
UInt64 startPosAfterHeader; UInt64 startPosAfterHeader;
UInt64 dataPos; UInt64 dataPos;
UInt32 NumFiles; UInt32 NumFiles;
UInt64 *UnpackPositions; // NumFiles + 1 UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles; // Byte *IsEmptyFiles;
Byte *IsDirs; Byte *IsDirs;
CSzBitUi32s CRCs; CSzBitUi32s CRCs;
CSzBitUi32s Attribs; CSzBitUi32s Attribs;
// CSzBitUi32s Parents; // CSzBitUi32s Parents;
CSzBitUi64s MTime; CSzBitUi64s MTime;
CSzBitUi64s CTime; CSzBitUi64s CTime;
UInt32 *FolderToFile; // NumFolders + 1 UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FileToFolder; // NumFiles UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */ size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */ Byte *FileNames; /* UTF-16-LE */
} CSzArEx; } CSzArEx;
#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i)) #define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i]) #define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p); void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc); void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/* /*
if dest == NULL, the return value specifies the required size of the buffer, if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character. in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */ are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/* /*
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex); size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest); UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/ */
/* /*
SzArEx_Extract extracts file from archive SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive. *outBuffer must be 0 before first call for each new archive.
Extracting cache: Extracting cache:
If you need to decompress more than one file, you can send If you need to decompress more than one file, you can send
these values from previous call: these values from previous call:
*blockIndex, *blockIndex,
*outBuffer, *outBuffer,
*outBufferSize *outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid, You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed. it will increase decompression speed.
If you use external function, you can declare these 3 cache variables If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function. (blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache. Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/ */
SRes SzArEx_Extract( SRes SzArEx_Extract(
const CSzArEx *db, const CSzArEx *db,
ILookInStream *inStream, ILookInStream *inStream,
UInt32 fileIndex, /* index of file */ UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */ UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */ size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */ size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */ size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAllocPtr allocMain, ISzAllocPtr allocMain,
ISzAllocPtr allocTemp); ISzAllocPtr allocTemp);
/* /*
SzArEx_Open Errors: SzArEx_Open Errors:
SZ_ERROR_NO_ARCHIVE SZ_ERROR_NO_ARCHIVE
SZ_ERROR_ARCHIVE SZ_ERROR_ARCHIVE
SZ_ERROR_UNSUPPORTED SZ_ERROR_UNSUPPORTED
SZ_ERROR_MEM SZ_ERROR_MEM
SZ_ERROR_CRC SZ_ERROR_CRC
SZ_ERROR_INPUT_EOF SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL SZ_ERROR_FAIL
*/ */
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAllocPtr allocMain, ISzAllocPtr allocTemp); ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,80 +1,80 @@
/* 7zAlloc.c -- Allocation functions /* 7zAlloc.c -- Allocation functions
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdlib.h> #include <stdlib.h>
#include "7zAlloc.h" #include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */ /* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
int g_allocCount = 0; int g_allocCount = 0;
int g_allocCountTemp = 0; int g_allocCountTemp = 0;
#endif #endif
void *SzAlloc(ISzAllocPtr p, size_t size) void *SzAlloc(ISzAllocPtr p, size_t size)
{ {
UNUSED_VAR(p); UNUSED_VAR(p);
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount); fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount);
g_allocCount++; g_allocCount++;
#endif #endif
return malloc(size); return malloc(size);
} }
void SzFree(ISzAllocPtr p, void *address) void SzFree(ISzAllocPtr p, void *address)
{ {
UNUSED_VAR(p); UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) if (address != 0)
{ {
g_allocCount--; g_allocCount--;
fprintf(stderr, "\nFree; count = %10d", g_allocCount); fprintf(stderr, "\nFree; count = %10d", g_allocCount);
} }
#endif #endif
free(address); free(address);
} }
void *SzAllocTemp(ISzAllocPtr p, size_t size) void *SzAllocTemp(ISzAllocPtr p, size_t size)
{ {
UNUSED_VAR(p); UNUSED_VAR(p);
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp); fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp);
g_allocCountTemp++; g_allocCountTemp++;
#ifdef _WIN32 #ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size); return HeapAlloc(GetProcessHeap(), 0, size);
#endif #endif
#endif #endif
return malloc(size); return malloc(size);
} }
void SzFreeTemp(ISzAllocPtr p, void *address) void SzFreeTemp(ISzAllocPtr p, void *address)
{ {
UNUSED_VAR(p); UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) if (address != 0)
{ {
g_allocCountTemp--; g_allocCountTemp--;
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
} }
#ifdef _WIN32 #ifdef _WIN32
HeapFree(GetProcessHeap(), 0, address); HeapFree(GetProcessHeap(), 0, address);
return; return;
#endif #endif
#endif #endif
free(address); free(address);
} }

View File

@@ -1,19 +1,19 @@
/* 7zAlloc.h -- Allocation functions /* 7zAlloc.h -- Allocation functions
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H #ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H #define __7Z_ALLOC_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
void *SzAlloc(ISzAllocPtr p, size_t size); void *SzAlloc(ISzAllocPtr p, size_t size);
void SzFree(ISzAllocPtr p, void *address); void SzFree(ISzAllocPtr p, void *address);
void *SzAllocTemp(ISzAllocPtr p, size_t size); void *SzAllocTemp(ISzAllocPtr p, size_t size);
void SzFreeTemp(ISzAllocPtr p, void *address); void SzFreeTemp(ISzAllocPtr p, void *address);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +1,36 @@
/* 7zBuf.c -- Byte Buffer /* 7zBuf.c -- Byte Buffer
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "7zBuf.h" #include "7zBuf.h"
void Buf_Init(CBuf *p) void Buf_Init(CBuf *p)
{ {
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
} }
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc) int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
{ {
p->size = 0; p->size = 0;
if (size == 0) if (size == 0)
{ {
p->data = 0; p->data = 0;
return 1; return 1;
} }
p->data = (Byte *)ISzAlloc_Alloc(alloc, size); p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
if (p->data) if (p->data)
{ {
p->size = size; p->size = size;
return 1; return 1;
} }
return 0; return 0;
} }
void Buf_Free(CBuf *p, ISzAllocPtr alloc) void Buf_Free(CBuf *p, ISzAllocPtr alloc)
{ {
ISzAlloc_Free(alloc, p->data); ISzAlloc_Free(alloc, p->data);
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
} }

View File

@@ -1,35 +1,35 @@
/* 7zBuf.h -- Byte Buffer /* 7zBuf.h -- Byte Buffer
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H #ifndef __7Z_BUF_H
#define __7Z_BUF_H #define __7Z_BUF_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
typedef struct typedef struct
{ {
Byte *data; Byte *data;
size_t size; size_t size;
} CBuf; } CBuf;
void Buf_Init(CBuf *p); void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc); int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
void Buf_Free(CBuf *p, ISzAllocPtr alloc); void Buf_Free(CBuf *p, ISzAllocPtr alloc);
typedef struct typedef struct
{ {
Byte *data; Byte *data;
size_t size; size_t size;
size_t pos; size_t pos;
} CDynBuf; } CDynBuf;
void DynBuf_Construct(CDynBuf *p); void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p); void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc); int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc); void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,52 +1,52 @@
/* 7zBuf2.c -- Byte Buffer /* 7zBuf2.c -- Byte Buffer
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <string.h> #include <string.h>
#include "7zBuf.h" #include "7zBuf.h"
void DynBuf_Construct(CDynBuf *p) void DynBuf_Construct(CDynBuf *p)
{ {
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
p->pos = 0; p->pos = 0;
} }
void DynBuf_SeekToBeg(CDynBuf *p) void DynBuf_SeekToBeg(CDynBuf *p)
{ {
p->pos = 0; p->pos = 0;
} }
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc) int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
{ {
if (size > p->size - p->pos) if (size > p->size - p->pos)
{ {
size_t newSize = p->pos + size; size_t newSize = p->pos + size;
Byte *data; Byte *data;
newSize += newSize / 4; newSize += newSize / 4;
data = (Byte *)ISzAlloc_Alloc(alloc, newSize); data = (Byte *)ISzAlloc_Alloc(alloc, newSize);
if (!data) if (!data)
return 0; return 0;
p->size = newSize; p->size = newSize;
if (p->pos != 0) if (p->pos != 0)
memcpy(data, p->data, p->pos); memcpy(data, p->data, p->pos);
ISzAlloc_Free(alloc, p->data); ISzAlloc_Free(alloc, p->data);
p->data = data; p->data = data;
} }
if (size != 0) if (size != 0)
{ {
memcpy(p->data + p->pos, buf, size); memcpy(p->data + p->pos, buf, size);
p->pos += size; p->pos += size;
} }
return 1; return 1;
} }
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc) void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc)
{ {
ISzAlloc_Free(alloc, p->data); ISzAlloc_Free(alloc, p->data);
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
p->pos = 0; p->pos = 0;
} }

256
C/7zCrc.c
View File

@@ -1,128 +1,128 @@
/* 7zCrc.c -- CRC32 init /* 7zCrc.c -- CRC32 init
2017-06-06 : Igor Pavlov : Public domain */ 2017-06-06 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "7zCrc.h" #include "7zCrc.h"
#include "CpuArch.h" #include "CpuArch.h"
#define kCrcPoly 0xEDB88320 #define kCrcPoly 0xEDB88320
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8 #define CRC_NUM_TABLES 8
#else #else
#define CRC_NUM_TABLES 9 #define CRC_NUM_TABLES 9
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif #endif
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif #endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
CRC_FUNC g_CrcUpdateT4; CRC_FUNC g_CrcUpdateT4;
CRC_FUNC g_CrcUpdateT8; CRC_FUNC g_CrcUpdateT8;
CRC_FUNC g_CrcUpdate; CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{ {
return g_CrcUpdate(v, data, size, g_CrcTable); return g_CrcUpdate(v, data, size, g_CrcTable);
} }
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
{ {
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
} }
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
const Byte *p = (const Byte *)data; const Byte *p = (const Byte *)data;
const Byte *pEnd = p + size; const Byte *pEnd = p + size;
for (; p != pEnd; p++) for (; p != pEnd; p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
return v; return v;
} }
void MY_FAST_CALL CrcGenerateTable() void MY_FAST_CALL CrcGenerateTable()
{ {
UInt32 i; UInt32 i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
UInt32 r = i; UInt32 r = i;
unsigned j; unsigned j;
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1))); r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
g_CrcTable[i] = r; g_CrcTable[i] = r;
} }
for (i = 256; i < 256 * CRC_NUM_TABLES; i++) for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
{ {
UInt32 r = g_CrcTable[(size_t)i - 256]; UInt32 r = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
} }
#if CRC_NUM_TABLES < 4 #if CRC_NUM_TABLES < 4
g_CrcUpdate = CrcUpdateT1; g_CrcUpdate = CrcUpdateT1;
#else #else
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
g_CrcUpdateT4 = CrcUpdateT4; g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4; g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8 #if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8; g_CrcUpdateT8 = CrcUpdateT8;
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder()) if (!CPU_Is_InOrder())
#endif #endif
g_CrcUpdate = CrcUpdateT8; g_CrcUpdate = CrcUpdateT8;
#endif #endif
#else #else
{ {
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
UInt32 k = 0x01020304; UInt32 k = 0x01020304;
const Byte *p = (const Byte *)&k; const Byte *p = (const Byte *)&k;
if (p[0] == 4 && p[1] == 3) if (p[0] == 4 && p[1] == 3)
{ {
g_CrcUpdateT4 = CrcUpdateT4; g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4; g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8 #if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8; g_CrcUpdateT8 = CrcUpdateT8;
g_CrcUpdate = CrcUpdateT8; g_CrcUpdate = CrcUpdateT8;
#endif #endif
} }
else if (p[0] != 1 || p[1] != 2) else if (p[0] != 1 || p[1] != 2)
g_CrcUpdate = CrcUpdateT1; g_CrcUpdate = CrcUpdateT1;
else else
#endif #endif
{ {
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{ {
UInt32 x = g_CrcTable[(size_t)i - 256]; UInt32 x = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x); g_CrcTable[i] = CRC_UINT32_SWAP(x);
} }
g_CrcUpdateT4 = CrcUpdateT1_BeT4; g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4; g_CrcUpdate = CrcUpdateT1_BeT4;
#if CRC_NUM_TABLES >= 8 #if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT1_BeT8; g_CrcUpdateT8 = CrcUpdateT1_BeT8;
g_CrcUpdate = CrcUpdateT1_BeT8; g_CrcUpdate = CrcUpdateT1_BeT8;
#endif #endif
} }
} }
#endif #endif
#endif #endif
} }

View File

@@ -1,25 +1,25 @@
/* 7zCrc.h -- CRC32 calculation /* 7zCrc.h -- CRC32 calculation
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H #ifndef __7Z_CRC_H
#define __7Z_CRC_H #define __7Z_CRC_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
extern UInt32 g_CrcTable[]; extern UInt32 g_CrcTable[];
/* Call CrcGenerateTable one time before other CRC functions */ /* Call CrcGenerateTable one time before other CRC functions */
void MY_FAST_CALL CrcGenerateTable(void); void MY_FAST_CALL CrcGenerateTable(void);
#define CRC_INIT_VAL 0xFFFFFFFF #define CRC_INIT_VAL 0xFFFFFFFF
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) #define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,115 +1,115 @@
/* 7zCrcOpt.c -- CRC32 calculation /* 7zCrcOpt.c -- CRC32 calculation
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
const Byte *p = (const Byte *)data; const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 4; size -= 4, p += 4) for (; size >= 4; size -= 4, p += 4)
{ {
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
(table + 0x300)[((v ) & 0xFF)] (table + 0x300)[((v ) & 0xFF)]
^ (table + 0x200)[((v >> 8) & 0xFF)] ^ (table + 0x200)[((v >> 8) & 0xFF)]
^ (table + 0x100)[((v >> 16) & 0xFF)] ^ (table + 0x100)[((v >> 16) & 0xFF)]
^ (table + 0x000)[((v >> 24))]; ^ (table + 0x000)[((v >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
return v; return v;
} }
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
const Byte *p = (const Byte *)data; const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 8; size -= 8, p += 8) for (; size >= 8; size -= 8, p += 8)
{ {
UInt32 d; UInt32 d;
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
(table + 0x700)[((v ) & 0xFF)] (table + 0x700)[((v ) & 0xFF)]
^ (table + 0x600)[((v >> 8) & 0xFF)] ^ (table + 0x600)[((v >> 8) & 0xFF)]
^ (table + 0x500)[((v >> 16) & 0xFF)] ^ (table + 0x500)[((v >> 16) & 0xFF)]
^ (table + 0x400)[((v >> 24))]; ^ (table + 0x400)[((v >> 24))];
d = *((const UInt32 *)p + 1); d = *((const UInt32 *)p + 1);
v ^= v ^=
(table + 0x300)[((d ) & 0xFF)] (table + 0x300)[((d ) & 0xFF)]
^ (table + 0x200)[((d >> 8) & 0xFF)] ^ (table + 0x200)[((d >> 8) & 0xFF)]
^ (table + 0x100)[((d >> 16) & 0xFF)] ^ (table + 0x100)[((d >> 16) & 0xFF)]
^ (table + 0x000)[((d >> 24))]; ^ (table + 0x000)[((d >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
return v; return v;
} }
#endif #endif
#ifndef MY_CPU_LE #ifndef MY_CPU_LE
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8)) #define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
const Byte *p = (const Byte *)data; const Byte *p = (const Byte *)data;
table += 0x100; table += 0x100;
v = CRC_UINT32_SWAP(v); v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p); v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 4; size -= 4, p += 4) for (; size >= 4; size -= 4, p += 4)
{ {
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
(table + 0x000)[((v ) & 0xFF)] (table + 0x000)[((v ) & 0xFF)]
^ (table + 0x100)[((v >> 8) & 0xFF)] ^ (table + 0x100)[((v >> 8) & 0xFF)]
^ (table + 0x200)[((v >> 16) & 0xFF)] ^ (table + 0x200)[((v >> 16) & 0xFF)]
^ (table + 0x300)[((v >> 24))]; ^ (table + 0x300)[((v >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p); v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v); return CRC_UINT32_SWAP(v);
} }
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
const Byte *p = (const Byte *)data; const Byte *p = (const Byte *)data;
table += 0x100; table += 0x100;
v = CRC_UINT32_SWAP(v); v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p); v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 8; size -= 8, p += 8) for (; size >= 8; size -= 8, p += 8)
{ {
UInt32 d; UInt32 d;
v ^= *(const UInt32 *)p; v ^= *(const UInt32 *)p;
v = v =
(table + 0x400)[((v ) & 0xFF)] (table + 0x400)[((v ) & 0xFF)]
^ (table + 0x500)[((v >> 8) & 0xFF)] ^ (table + 0x500)[((v >> 8) & 0xFF)]
^ (table + 0x600)[((v >> 16) & 0xFF)] ^ (table + 0x600)[((v >> 16) & 0xFF)]
^ (table + 0x700)[((v >> 24))]; ^ (table + 0x700)[((v >> 24))];
d = *((const UInt32 *)p + 1); d = *((const UInt32 *)p + 1);
v ^= v ^=
(table + 0x000)[((d ) & 0xFF)] (table + 0x000)[((d ) & 0xFF)]
^ (table + 0x100)[((d >> 8) & 0xFF)] ^ (table + 0x100)[((d >> 8) & 0xFF)]
^ (table + 0x200)[((d >> 16) & 0xFF)] ^ (table + 0x200)[((d >> 16) & 0xFF)]
^ (table + 0x300)[((d >> 24))]; ^ (table + 0x300)[((d >> 24))];
} }
for (; size > 0; size--, p++) for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p); v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v); return CRC_UINT32_SWAP(v);
} }
#endif #endif

1182
C/7zDec.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,286 +1,286 @@
/* 7zFile.c -- File IO /* 7zFile.c -- File IO
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "7zFile.h" #include "7zFile.h"
#ifndef USE_WINDOWS_FILE #ifndef USE_WINDOWS_FILE
#ifndef UNDER_CE #ifndef UNDER_CE
#include <errno.h> #include <errno.h>
#endif #endif
#else #else
/* /*
ReadFile and WriteFile functions in Windows have BUG: ReadFile and WriteFile functions in Windows have BUG:
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
(Insufficient system resources exist to complete the requested service). (Insufficient system resources exist to complete the requested service).
Probably in some version of Windows there are problems with other sizes: Probably in some version of Windows there are problems with other sizes:
for 32 MB (maybe also for 16 MB). for 32 MB (maybe also for 16 MB).
And message can be "Network connection was lost" And message can be "Network connection was lost"
*/ */
#define kChunkSizeMax (1 << 22) #define kChunkSizeMax (1 << 22)
#endif #endif
void File_Construct(CSzFile *p) void File_Construct(CSzFile *p)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
p->handle = INVALID_HANDLE_VALUE; p->handle = INVALID_HANDLE_VALUE;
#else #else
p->file = NULL; p->file = NULL;
#endif #endif
} }
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
static WRes File_Open(CSzFile *p, const char *name, int writeMode) static WRes File_Open(CSzFile *p, const char *name, int writeMode)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
p->handle = CreateFileA(name, p->handle = CreateFileA(name,
writeMode ? GENERIC_WRITE : GENERIC_READ, writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL, FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING, writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL); FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
#else #else
p->file = fopen(name, writeMode ? "wb+" : "rb"); p->file = fopen(name, writeMode ? "wb+" : "rb");
return (p->file != 0) ? 0 : return (p->file != 0) ? 0 :
#ifdef UNDER_CE #ifdef UNDER_CE
2; /* ENOENT */ 2; /* ENOENT */
#else #else
errno; errno;
#endif #endif
#endif #endif
} }
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
#endif #endif
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
{ {
p->handle = CreateFileW(name, p->handle = CreateFileW(name,
writeMode ? GENERIC_WRITE : GENERIC_READ, writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL, FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING, writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL); FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
} }
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
#endif #endif
WRes File_Close(CSzFile *p) WRes File_Close(CSzFile *p)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
if (p->handle != INVALID_HANDLE_VALUE) if (p->handle != INVALID_HANDLE_VALUE)
{ {
if (!CloseHandle(p->handle)) if (!CloseHandle(p->handle))
return GetLastError(); return GetLastError();
p->handle = INVALID_HANDLE_VALUE; p->handle = INVALID_HANDLE_VALUE;
} }
#else #else
if (p->file != NULL) if (p->file != NULL)
{ {
int res = fclose(p->file); int res = fclose(p->file);
if (res != 0) if (res != 0)
return res; return res;
p->file = NULL; p->file = NULL;
} }
#endif #endif
return 0; return 0;
} }
WRes File_Read(CSzFile *p, void *data, size_t *size) WRes File_Read(CSzFile *p, void *data, size_t *size)
{ {
size_t originalSize = *size; size_t originalSize = *size;
if (originalSize == 0) if (originalSize == 0)
return 0; return 0;
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
*size = 0; *size = 0;
do do
{ {
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0; DWORD processed = 0;
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed); data = (void *)((Byte *)data + processed);
originalSize -= processed; originalSize -= processed;
*size += processed; *size += processed;
if (!res) if (!res)
return GetLastError(); return GetLastError();
if (processed == 0) if (processed == 0)
break; break;
} }
while (originalSize > 0); while (originalSize > 0);
return 0; return 0;
#else #else
*size = fread(data, 1, originalSize, p->file); *size = fread(data, 1, originalSize, p->file);
if (*size == originalSize) if (*size == originalSize)
return 0; return 0;
return ferror(p->file); return ferror(p->file);
#endif #endif
} }
WRes File_Write(CSzFile *p, const void *data, size_t *size) WRes File_Write(CSzFile *p, const void *data, size_t *size)
{ {
size_t originalSize = *size; size_t originalSize = *size;
if (originalSize == 0) if (originalSize == 0)
return 0; return 0;
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
*size = 0; *size = 0;
do do
{ {
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0; DWORD processed = 0;
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed); data = (void *)((Byte *)data + processed);
originalSize -= processed; originalSize -= processed;
*size += processed; *size += processed;
if (!res) if (!res)
return GetLastError(); return GetLastError();
if (processed == 0) if (processed == 0)
break; break;
} }
while (originalSize > 0); while (originalSize > 0);
return 0; return 0;
#else #else
*size = fwrite(data, 1, originalSize, p->file); *size = fwrite(data, 1, originalSize, p->file);
if (*size == originalSize) if (*size == originalSize)
return 0; return 0;
return ferror(p->file); return ferror(p->file);
#endif #endif
} }
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
LARGE_INTEGER value; LARGE_INTEGER value;
DWORD moveMethod; DWORD moveMethod;
value.LowPart = (DWORD)*pos; value.LowPart = (DWORD)*pos;
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
switch (origin) switch (origin)
{ {
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
case SZ_SEEK_END: moveMethod = FILE_END; break; case SZ_SEEK_END: moveMethod = FILE_END; break;
default: return ERROR_INVALID_PARAMETER; default: return ERROR_INVALID_PARAMETER;
} }
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
if (value.LowPart == 0xFFFFFFFF) if (value.LowPart == 0xFFFFFFFF)
{ {
WRes res = GetLastError(); WRes res = GetLastError();
if (res != NO_ERROR) if (res != NO_ERROR)
return res; return res;
} }
*pos = ((Int64)value.HighPart << 32) | value.LowPart; *pos = ((Int64)value.HighPart << 32) | value.LowPart;
return 0; return 0;
#else #else
int moveMethod; int moveMethod;
int res; int res;
switch (origin) switch (origin)
{ {
case SZ_SEEK_SET: moveMethod = SEEK_SET; break; case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
case SZ_SEEK_END: moveMethod = SEEK_END; break; case SZ_SEEK_END: moveMethod = SEEK_END; break;
default: return 1; default: return 1;
} }
res = fseek(p->file, (long)*pos, moveMethod); res = fseek(p->file, (long)*pos, moveMethod);
*pos = ftell(p->file); *pos = ftell(p->file);
return res; return res;
#endif #endif
} }
WRes File_GetLength(CSzFile *p, UInt64 *length) WRes File_GetLength(CSzFile *p, UInt64 *length)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
DWORD sizeHigh; DWORD sizeHigh;
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
if (sizeLow == 0xFFFFFFFF) if (sizeLow == 0xFFFFFFFF)
{ {
DWORD res = GetLastError(); DWORD res = GetLastError();
if (res != NO_ERROR) if (res != NO_ERROR)
return res; return res;
} }
*length = (((UInt64)sizeHigh) << 32) + sizeLow; *length = (((UInt64)sizeHigh) << 32) + sizeLow;
return 0; return 0;
#else #else
long pos = ftell(p->file); long pos = ftell(p->file);
int res = fseek(p->file, 0, SEEK_END); int res = fseek(p->file, 0, SEEK_END);
*length = ftell(p->file); *length = ftell(p->file);
fseek(p->file, pos, SEEK_SET); fseek(p->file, pos, SEEK_SET);
return res; return res;
#endif #endif
} }
/* ---------- FileSeqInStream ---------- */ /* ---------- FileSeqInStream ---------- */
static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size) static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt); CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
} }
void FileSeqInStream_CreateVTable(CFileSeqInStream *p) void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
{ {
p->vt.Read = FileSeqInStream_Read; p->vt.Read = FileSeqInStream_Read;
} }
/* ---------- FileInStream ---------- */ /* ---------- FileInStream ---------- */
static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size) static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
{ {
CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt); CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
} }
static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin) static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
{ {
CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt); CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return File_Seek(&p->file, pos, origin); return File_Seek(&p->file, pos, origin);
} }
void FileInStream_CreateVTable(CFileInStream *p) void FileInStream_CreateVTable(CFileInStream *p)
{ {
p->vt.Read = FileInStream_Read; p->vt.Read = FileInStream_Read;
p->vt.Seek = FileInStream_Seek; p->vt.Seek = FileInStream_Seek;
} }
/* ---------- FileOutStream ---------- */ /* ---------- FileOutStream ---------- */
static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size) static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
{ {
CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt); CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
File_Write(&p->file, data, &size); File_Write(&p->file, data, &size);
return size; return size;
} }
void FileOutStream_CreateVTable(CFileOutStream *p) void FileOutStream_CreateVTable(CFileOutStream *p)
{ {
p->vt.Write = FileOutStream_Write; p->vt.Write = FileOutStream_Write;
} }

View File

@@ -1,83 +1,83 @@
/* 7zFile.h -- File IO /* 7zFile.h -- File IO
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H #ifndef __7Z_FILE_H
#define __7Z_FILE_H #define __7Z_FILE_H
#ifdef _WIN32 #ifdef _WIN32
#define USE_WINDOWS_FILE #define USE_WINDOWS_FILE
#endif #endif
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
#include <windows.h> #include <windows.h>
#else #else
#include <stdio.h> #include <stdio.h>
#endif #endif
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* ---------- File ---------- */ /* ---------- File ---------- */
typedef struct typedef struct
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
HANDLE handle; HANDLE handle;
#else #else
FILE *file; FILE *file;
#endif #endif
} CSzFile; } CSzFile;
void File_Construct(CSzFile *p); void File_Construct(CSzFile *p);
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
WRes InFile_Open(CSzFile *p, const char *name); WRes InFile_Open(CSzFile *p, const char *name);
WRes OutFile_Open(CSzFile *p, const char *name); WRes OutFile_Open(CSzFile *p, const char *name);
#endif #endif
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
WRes InFile_OpenW(CSzFile *p, const WCHAR *name); WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
#endif #endif
WRes File_Close(CSzFile *p); WRes File_Close(CSzFile *p);
/* reads max(*size, remain file's size) bytes */ /* reads max(*size, remain file's size) bytes */
WRes File_Read(CSzFile *p, void *data, size_t *size); WRes File_Read(CSzFile *p, void *data, size_t *size);
/* writes *size bytes */ /* writes *size bytes */
WRes File_Write(CSzFile *p, const void *data, size_t *size); WRes File_Write(CSzFile *p, const void *data, size_t *size);
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
WRes File_GetLength(CSzFile *p, UInt64 *length); WRes File_GetLength(CSzFile *p, UInt64 *length);
/* ---------- FileInStream ---------- */ /* ---------- FileInStream ---------- */
typedef struct typedef struct
{ {
ISeqInStream vt; ISeqInStream vt;
CSzFile file; CSzFile file;
} CFileSeqInStream; } CFileSeqInStream;
void FileSeqInStream_CreateVTable(CFileSeqInStream *p); void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct typedef struct
{ {
ISeekInStream vt; ISeekInStream vt;
CSzFile file; CSzFile file;
} CFileInStream; } CFileInStream;
void FileInStream_CreateVTable(CFileInStream *p); void FileInStream_CreateVTable(CFileInStream *p);
typedef struct typedef struct
{ {
ISeqOutStream vt; ISeqOutStream vt;
CSzFile file; CSzFile file;
} CFileOutStream; } CFileOutStream;
void FileOutStream_CreateVTable(CFileOutStream *p); void FileOutStream_CreateVTable(CFileOutStream *p);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,176 +1,176 @@
/* 7zStream.c -- 7z Stream functions /* 7zStream.c -- 7z Stream functions
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <string.h> #include <string.h>
#include "7zTypes.h" #include "7zTypes.h"
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(ISeqInStream_Read(stream, buf, &processed)); RINOK(ISeqInStream_Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((Byte *)buf + processed); buf = (void *)((Byte *)buf + processed);
size -= processed; size -= processed;
} }
return SZ_OK; return SZ_OK;
} }
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size) SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
{ {
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf) SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
{ {
size_t processed = 1; size_t processed = 1;
RINOK(ISeqInStream_Read(stream, buf, &processed)); RINOK(ISeqInStream_Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
} }
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset) SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
{ {
Int64 t = offset; Int64 t = offset;
return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
} }
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size) SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
{ {
const void *lookBuf; const void *lookBuf;
if (*size == 0) if (*size == 0)
return SZ_OK; return SZ_OK;
RINOK(ILookInStream_Look(stream, &lookBuf, size)); RINOK(ILookInStream_Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size); memcpy(buf, lookBuf, *size);
return ILookInStream_Skip(stream, *size); return ILookInStream_Skip(stream, *size);
} }
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(ILookInStream_Read(stream, buf, &processed)); RINOK(ILookInStream_Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((Byte *)buf + processed); buf = (void *)((Byte *)buf + processed);
size -= processed; size -= processed;
} }
return SZ_OK; return SZ_OK;
} }
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size) SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
{ {
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt); #define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size) static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
GET_LookToRead2 GET_LookToRead2
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size != 0) if (size2 == 0 && *size != 0)
{ {
p->pos = 0; p->pos = 0;
p->size = 0; p->size = 0;
size2 = p->bufSize; size2 = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, &size2); res = ISeekInStream_Read(p->realStream, p->buf, &size2);
p->size = size2; p->size = size2;
} }
if (*size > size2) if (*size > size2)
*size = size2; *size = size2;
*buf = p->buf + p->pos; *buf = p->buf + p->pos;
return res; return res;
} }
static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size) static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
GET_LookToRead2 GET_LookToRead2
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size != 0) if (size2 == 0 && *size != 0)
{ {
p->pos = 0; p->pos = 0;
p->size = 0; p->size = 0;
if (*size > p->bufSize) if (*size > p->bufSize)
*size = p->bufSize; *size = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, size); res = ISeekInStream_Read(p->realStream, p->buf, size);
size2 = p->size = *size; size2 = p->size = *size;
} }
if (*size > size2) if (*size > size2)
*size = size2; *size = size2;
*buf = p->buf + p->pos; *buf = p->buf + p->pos;
return res; return res;
} }
static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset) static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
{ {
GET_LookToRead2 GET_LookToRead2
p->pos += offset; p->pos += offset;
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
{ {
GET_LookToRead2 GET_LookToRead2
size_t rem = p->size - p->pos; size_t rem = p->size - p->pos;
if (rem == 0) if (rem == 0)
return ISeekInStream_Read(p->realStream, buf, size); return ISeekInStream_Read(p->realStream, buf, size);
if (rem > *size) if (rem > *size)
rem = *size; rem = *size;
memcpy(buf, p->buf + p->pos, rem); memcpy(buf, p->buf + p->pos, rem);
p->pos += rem; p->pos += rem;
*size = rem; *size = rem;
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin) static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
{ {
GET_LookToRead2 GET_LookToRead2
p->pos = p->size = 0; p->pos = p->size = 0;
return ISeekInStream_Seek(p->realStream, pos, origin); return ISeekInStream_Seek(p->realStream, pos, origin);
} }
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead) void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
{ {
p->vt.Look = lookahead ? p->vt.Look = lookahead ?
LookToRead2_Look_Lookahead : LookToRead2_Look_Lookahead :
LookToRead2_Look_Exact; LookToRead2_Look_Exact;
p->vt.Skip = LookToRead2_Skip; p->vt.Skip = LookToRead2_Skip;
p->vt.Read = LookToRead2_Read; p->vt.Read = LookToRead2_Read;
p->vt.Seek = LookToRead2_Seek; p->vt.Seek = LookToRead2_Seek;
} }
static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size) static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt); CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
return LookInStream_LookRead(p->realStream, buf, size); return LookInStream_LookRead(p->realStream, buf, size);
} }
void SecToLook_CreateVTable(CSecToLook *p) void SecToLook_CreateVTable(CSecToLook *p)
{ {
p->vt.Read = SecToLook_Read; p->vt.Read = SecToLook_Read;
} }
static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size) static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt); CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
return ILookInStream_Read(p->realStream, buf, size); return ILookInStream_Read(p->realStream, buf, size);
} }
void SecToRead_CreateVTable(CSecToRead *p) void SecToRead_CreateVTable(CSecToRead *p)
{ {
p->vt.Read = SecToRead_Read; p->vt.Read = SecToRead_Read;
} }

View File

@@ -1,375 +1,375 @@
/* 7zTypes.h -- Basic types /* 7zTypes.h -- Basic types
2018-08-04 : Igor Pavlov : Public domain */ 2018-08-04 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
#ifdef _WIN32 #ifdef _WIN32
/* #include <windows.h> */ /* #include <windows.h> */
#endif #endif
#include <stddef.h> #include <stddef.h>
#ifndef EXTERN_C_BEGIN #ifndef EXTERN_C_BEGIN
#ifdef __cplusplus #ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" { #define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END } #define EXTERN_C_END }
#else #else
#define EXTERN_C_BEGIN #define EXTERN_C_BEGIN
#define EXTERN_C_END #define EXTERN_C_END
#endif #endif
#endif #endif
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define SZ_OK 0 #define SZ_OK 0
#define SZ_ERROR_DATA 1 #define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2 #define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3 #define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4 #define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5 #define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6 #define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7 #define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8 #define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9 #define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10 #define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11 #define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12 #define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16 #define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17 #define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes; typedef int SRes;
#ifdef _WIN32 #ifdef _WIN32
/* typedef DWORD WRes; */ /* typedef DWORD WRes; */
typedef unsigned WRes; typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) #define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else #else
typedef int WRes; typedef int WRes;
#define MY__FACILITY_WIN32 7 #define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32 #define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000))) #define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif #endif
typedef unsigned char Byte; typedef unsigned char Byte;
typedef short Int16; typedef short Int16;
typedef unsigned short UInt16; typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG #ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32; typedef long Int32;
typedef unsigned long UInt32; typedef unsigned long UInt32;
#else #else
typedef int Int32; typedef int Int32;
typedef unsigned int UInt32; typedef unsigned int UInt32;
#endif #endif
#ifdef _SZ_NO_INT_64 #ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. /* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */ NOTES: Some code will work incorrectly in that case! */
typedef long Int64; typedef long Int64;
typedef unsigned long UInt64; typedef unsigned long UInt64;
#else #else
#if defined(_MSC_VER) || defined(__BORLANDC__) #if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64; typedef __int64 Int64;
typedef unsigned __int64 UInt64; typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n #define UINT64_CONST(n) n
#else #else
typedef long long int Int64; typedef long long int Int64;
typedef unsigned long long int UInt64; typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL #define UINT64_CONST(n) n ## ULL
#endif #endif
#endif #endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T #ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT; typedef UInt32 SizeT;
#else #else
typedef size_t SizeT; typedef size_t SizeT;
#endif #endif
typedef int BoolInt; typedef int BoolInt;
/* typedef BoolInt Bool; */ /* typedef BoolInt Bool; */
#define True 1 #define True 1
#define False 0 #define False 0
#ifdef _WIN32 #ifdef _WIN32
#define MY_STD_CALL __stdcall #define MY_STD_CALL __stdcall
#else #else
#define MY_STD_CALL #define MY_STD_CALL
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER >= 1300 #if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline) #define MY_NO_INLINE __declspec(noinline)
#else #else
#define MY_NO_INLINE #define MY_NO_INLINE
#endif #endif
#define MY_FORCE_INLINE __forceinline #define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl #define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall #define MY_FAST_CALL __fastcall
#else #else
#define MY_NO_INLINE #define MY_NO_INLINE
#define MY_FORCE_INLINE #define MY_FORCE_INLINE
#define MY_CDECL #define MY_CDECL
#define MY_FAST_CALL #define MY_FAST_CALL
/* inline keyword : for C++ / C99 */ /* inline keyword : for C++ / C99 */
/* GCC, clang: */ /* GCC, clang: */
/* /*
#if defined (__GNUC__) && (__GNUC__ >= 4) #if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline)) #define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline)) #define MY_NO_INLINE __attribute__((noinline))
#endif #endif
*/ */
#endif #endif
/* The following interfaces use first parameter as pointer to structure */ /* The following interfaces use first parameter as pointer to structure */
typedef struct IByteIn IByteIn; typedef struct IByteIn IByteIn;
struct IByteIn struct IByteIn
{ {
Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */ Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
}; };
#define IByteIn_Read(p) (p)->Read(p) #define IByteIn_Read(p) (p)->Read(p)
typedef struct IByteOut IByteOut; typedef struct IByteOut IByteOut;
struct IByteOut struct IByteOut
{ {
void (*Write)(const IByteOut *p, Byte b); void (*Write)(const IByteOut *p, Byte b);
}; };
#define IByteOut_Write(p, b) (p)->Write(p, b) #define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct ISeqInStream ISeqInStream; typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream struct ISeqInStream
{ {
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size); SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
}; };
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) #define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */ /* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size); SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType); SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf); SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct ISeqOutStream ISeqOutStream; typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream struct ISeqOutStream
{ {
size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size); size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes. /* Returns: result - the number of actually written bytes.
(result < size) means error */ (result < size) means error */
}; };
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size) #define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum typedef enum
{ {
SZ_SEEK_SET = 0, SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1, SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2 SZ_SEEK_END = 2
} ESzSeek; } ESzSeek;
typedef struct ISeekInStream ISeekInStream; typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream struct ISeekInStream
{ {
SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
}; };
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) #define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) #define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct ILookInStream ILookInStream; typedef struct ILookInStream ILookInStream;
struct ILookInStream struct ILookInStream
{ {
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size); SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed (output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
SRes (*Skip)(const ILookInStream *p, size_t offset); SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */ /* offset must be <= output(*size) of Look */
SRes (*Read)(const ILookInStream *p, void *buf, size_t *size); SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */ /* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
}; };
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) #define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset) #define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size) #define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) #define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size); SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset); SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */ /* reads via ILookInStream::Read */
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType); SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size); SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
typedef struct typedef struct
{ {
ILookInStream vt; ILookInStream vt;
const ISeekInStream *realStream; const ISeekInStream *realStream;
size_t pos; size_t pos;
size_t size; /* it's data size */ size_t size; /* it's data size */
/* the following variables must be set outside */ /* the following variables must be set outside */
Byte *buf; Byte *buf;
size_t bufSize; size_t bufSize;
} CLookToRead2; } CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; } #define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
typedef struct typedef struct
{ {
ISeqInStream vt; ISeqInStream vt;
const ILookInStream *realStream; const ILookInStream *realStream;
} CSecToLook; } CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p); void SecToLook_CreateVTable(CSecToLook *p);
typedef struct typedef struct
{ {
ISeqInStream vt; ISeqInStream vt;
const ILookInStream *realStream; const ILookInStream *realStream;
} CSecToRead; } CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p); void SecToRead_CreateVTable(CSecToRead *p);
typedef struct ICompressProgress ICompressProgress; typedef struct ICompressProgress ICompressProgress;
struct ICompressProgress struct ICompressProgress
{ {
SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize); SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break. /* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */ Value (UInt64)(Int64)-1 for size means unknown value. */
}; };
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) #define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct ISzAlloc ISzAlloc; typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr; typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc struct ISzAlloc
{ {
void *(*Alloc)(ISzAllocPtr p, size_t size); void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */ void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
}; };
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size) #define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a) #define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */ /* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size) #define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a) #define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof #ifndef MY_offsetof
#ifdef offsetof #ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m) #define MY_offsetof(type, m) offsetof(type, m)
/* /*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m) #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/ */
#else #else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m)) #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif #endif
#endif #endif
#ifndef MY_container_of #ifndef MY_container_of
/* /*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m) #define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) #define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) #define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) #define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/ */
/* /*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly" GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members" GCC 4.8.1 : classes with non-public variable members"
*/ */
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m))) #define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif #endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr)) #define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/* /*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) #define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/ */
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m) #define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) #define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/* /*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m) #define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/ */
#ifdef _WIN32 #ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\' #define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\' #define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\" #define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\" #define WSTRING_PATH_SEPARATOR L"\\"
#else #else
#define CHAR_PATH_SEPARATOR '/' #define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/' #define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/" #define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/" #define WSTRING_PATH_SEPARATOR L"/"
#endif #endif
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,27 +1,27 @@
#define MY_VER_MAJOR 19 #define MY_VER_MAJOR 19
#define MY_VER_MINOR 00 #define MY_VER_MINOR 00
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "19.00 ZS v1.4.5 R1" #define MY_VERSION_NUMBERS "19.00 ZS v1.4.5 R1"
#define MY_VERSION MY_VERSION_NUMBERS #define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME #ifdef MY_CPU_NAME
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")" #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
#else #else
#define MY_VERSION_CPU MY_VERSION #define MY_VERSION_CPU MY_VERSION
#endif #endif
#define MY_DATE "2020-05-27" #define MY_DATE "2020-05-27"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov, Tino Reichardt" #define MY_AUTHOR_NAME "Igor Pavlov, Tino Reichardt"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2019 Igor Pavlov, 2016-2020 Tino Reichardt" #define MY_COPYRIGHT_CR "Copyright (c) 1999-2019 Igor Pavlov, 2016-2020 Tino Reichardt"
#ifdef USE_COPYRIGHT_CR #ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR
#else #else
#define MY_COPYRIGHT MY_COPYRIGHT_PD #define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif #endif
#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE #define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE

View File

@@ -1,55 +1,55 @@
#define MY_VS_FFI_FILEFLAGSMASK 0x0000003FL #define MY_VS_FFI_FILEFLAGSMASK 0x0000003FL
#define MY_VOS_NT_WINDOWS32 0x00040004L #define MY_VOS_NT_WINDOWS32 0x00040004L
#define MY_VOS_CE_WINDOWS32 0x00050004L #define MY_VOS_CE_WINDOWS32 0x00050004L
#define MY_VFT_APP 0x00000001L #define MY_VFT_APP 0x00000001L
#define MY_VFT_DLL 0x00000002L #define MY_VFT_DLL 0x00000002L
// #include <WinVer.h> // #include <WinVer.h>
#ifndef MY_VERSION #ifndef MY_VERSION
#include "7zVersion.h" #include "7zVersion.h"
#endif #endif
#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0 #define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0
#ifdef DEBUG #ifdef DEBUG
#define DBG_FL VS_FF_DEBUG #define DBG_FL VS_FF_DEBUG
#else #else
#define DBG_FL 0 #define DBG_FL 0
#endif #endif
#define MY_VERSION_INFO(fileType, descr, intName, origName) \ #define MY_VERSION_INFO(fileType, descr, intName, origName) \
LANGUAGE 9, 1 \ LANGUAGE 9, 1 \
1 VERSIONINFO \ 1 VERSIONINFO \
FILEVERSION MY_VER \ FILEVERSION MY_VER \
PRODUCTVERSION MY_VER \ PRODUCTVERSION MY_VER \
FILEFLAGSMASK MY_VS_FFI_FILEFLAGSMASK \ FILEFLAGSMASK MY_VS_FFI_FILEFLAGSMASK \
FILEFLAGS DBG_FL \ FILEFLAGS DBG_FL \
FILEOS MY_VOS_NT_WINDOWS32 \ FILEOS MY_VOS_NT_WINDOWS32 \
FILETYPE fileType \ FILETYPE fileType \
FILESUBTYPE 0x0L \ FILESUBTYPE 0x0L \
BEGIN \ BEGIN \
BLOCK "StringFileInfo" \ BLOCK "StringFileInfo" \
BEGIN \ BEGIN \
BLOCK "040904b0" \ BLOCK "040904b0" \
BEGIN \ BEGIN \
VALUE "CompanyName", "Igor Pavlov, Tino Reichardt" \ VALUE "CompanyName", "Igor Pavlov, Tino Reichardt" \
VALUE "FileDescription", descr \ VALUE "FileDescription", descr \
VALUE "FileVersion", MY_VERSION \ VALUE "FileVersion", MY_VERSION \
VALUE "InternalName", intName \ VALUE "InternalName", intName \
VALUE "LegalCopyright", MY_COPYRIGHT \ VALUE "LegalCopyright", MY_COPYRIGHT \
VALUE "OriginalFilename", origName \ VALUE "OriginalFilename", origName \
VALUE "ProductName", "7-Zip ZS" \ VALUE "ProductName", "7-Zip ZS" \
VALUE "ProductVersion", MY_VERSION \ VALUE "ProductVersion", MY_VERSION \
END \ END \
END \ END \
BLOCK "VarFileInfo" \ BLOCK "VarFileInfo" \
BEGIN \ BEGIN \
VALUE "Translation", 0x409, 1200 \ VALUE "Translation", 0x409, 1200 \
END \ END \
END END
#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(MY_VFT_APP, descr, intName, intName ".exe") #define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(MY_VFT_APP, descr, intName, intName ".exe")
#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(MY_VFT_DLL, descr, intName, intName ".dll") #define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(MY_VFT_DLL, descr, intName, intName ".dll")

View File

@@ -1,14 +1,14 @@
#include "7zVersion.h" #include "7zVersion.h"
#undef MY_AUTHOR_NAME #undef MY_AUTHOR_NAME
#define MY_AUTHOR_NAME "Tino Reichardt" #define MY_AUTHOR_NAME "Tino Reichardt"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#define MY_COPYRIGHT "Copyright (c) 2016 - 2020 Tino Reichardt" #define MY_COPYRIGHT "Copyright (c) 2016 - 2020 Tino Reichardt"
#undef MY_COPYRIGHT_DATE #undef MY_COPYRIGHT_DATE
#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE #define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE #define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE

612
C/Aes.c
View File

@@ -1,306 +1,306 @@
/* Aes.c -- AES encryption / decryption /* Aes.c -- AES encryption / decryption
2017-01-24 : Igor Pavlov : Public domain */ 2017-01-24 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Aes.h" #include "Aes.h"
#include "CpuArch.h" #include "CpuArch.h"
static UInt32 T[256 * 4]; static UInt32 T[256 * 4];
static const Byte Sbox[256] = { static const Byte Sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *ivAes, Byte *data, size_t numBlocks);
AES_CODE_FUNC g_AesCbc_Encode; AES_CODE_FUNC g_AesCbc_Encode;
AES_CODE_FUNC g_AesCbc_Decode; AES_CODE_FUNC g_AesCbc_Decode;
AES_CODE_FUNC g_AesCtr_Code; AES_CODE_FUNC g_AesCtr_Code;
static UInt32 D[256 * 4]; static UInt32 D[256 * 4];
static Byte InvS[256]; static Byte InvS[256];
static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) #define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) #define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24))
#define gb0(x) ( (x) & 0xFF) #define gb0(x) ( (x) & 0xFF)
#define gb1(x) (((x) >> ( 8)) & 0xFF) #define gb1(x) (((x) >> ( 8)) & 0xFF)
#define gb2(x) (((x) >> (16)) & 0xFF) #define gb2(x) (((x) >> (16)) & 0xFF)
#define gb3(x) (((x) >> (24))) #define gb3(x) (((x) >> (24)))
#define gb(n, x) gb ## n(x) #define gb(n, x) gb ## n(x)
#define TT(x) (T + (x << 8)) #define TT(x) (T + (x << 8))
#define DD(x) (D + (x << 8)) #define DD(x) (D + (x << 8))
void AesGenTables(void) void AesGenTables(void)
{ {
unsigned i; unsigned i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
InvS[Sbox[i]] = (Byte)i; InvS[Sbox[i]] = (Byte)i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
{ {
UInt32 a1 = Sbox[i]; UInt32 a1 = Sbox[i];
UInt32 a2 = xtime(a1); UInt32 a2 = xtime(a1);
UInt32 a3 = a2 ^ a1; UInt32 a3 = a2 ^ a1;
TT(0)[i] = Ui32(a2, a1, a1, a3); TT(0)[i] = Ui32(a2, a1, a1, a3);
TT(1)[i] = Ui32(a3, a2, a1, a1); TT(1)[i] = Ui32(a3, a2, a1, a1);
TT(2)[i] = Ui32(a1, a3, a2, a1); TT(2)[i] = Ui32(a1, a3, a2, a1);
TT(3)[i] = Ui32(a1, a1, a3, a2); TT(3)[i] = Ui32(a1, a1, a3, a2);
} }
{ {
UInt32 a1 = InvS[i]; UInt32 a1 = InvS[i];
UInt32 a2 = xtime(a1); UInt32 a2 = xtime(a1);
UInt32 a4 = xtime(a2); UInt32 a4 = xtime(a2);
UInt32 a8 = xtime(a4); UInt32 a8 = xtime(a4);
UInt32 a9 = a8 ^ a1; UInt32 a9 = a8 ^ a1;
UInt32 aB = a8 ^ a2 ^ a1; UInt32 aB = a8 ^ a2 ^ a1;
UInt32 aD = a8 ^ a4 ^ a1; UInt32 aD = a8 ^ a4 ^ a1;
UInt32 aE = a8 ^ a4 ^ a2; UInt32 aE = a8 ^ a4 ^ a2;
DD(0)[i] = Ui32(aE, a9, aD, aB); DD(0)[i] = Ui32(aE, a9, aD, aB);
DD(1)[i] = Ui32(aB, aE, a9, aD); DD(1)[i] = Ui32(aB, aE, a9, aD);
DD(2)[i] = Ui32(aD, aB, aE, a9); DD(2)[i] = Ui32(aD, aB, aE, a9);
DD(3)[i] = Ui32(a9, aD, aB, aE); DD(3)[i] = Ui32(a9, aD, aB, aE);
} }
} }
g_AesCbc_Encode = AesCbc_Encode; g_AesCbc_Encode = AesCbc_Encode;
g_AesCbc_Decode = AesCbc_Decode; g_AesCbc_Decode = AesCbc_Decode;
g_AesCtr_Code = AesCtr_Code; g_AesCtr_Code = AesCtr_Code;
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported()) if (CPU_Is_Aes_Supported())
{ {
g_AesCbc_Encode = AesCbc_Encode_Intel; g_AesCbc_Encode = AesCbc_Encode_Intel;
g_AesCbc_Decode = AesCbc_Decode_Intel; g_AesCbc_Decode = AesCbc_Decode_Intel;
g_AesCtr_Code = AesCtr_Code_Intel; g_AesCtr_Code = AesCtr_Code_Intel;
} }
#endif #endif
} }
#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])] #define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])]
#define HT4(m, i, s, p) m[i] = \ #define HT4(m, i, s, p) m[i] = \
HT(i, 0, s) ^ \ HT(i, 0, s) ^ \
HT(i, 1, s) ^ \ HT(i, 1, s) ^ \
HT(i, 2, s) ^ \ HT(i, 2, s) ^ \
HT(i, 3, s) ^ w[p + i] HT(i, 3, s) ^ w[p + i]
#define HT16(m, s, p) \ #define HT16(m, s, p) \
HT4(m, 0, s, p); \ HT4(m, 0, s, p); \
HT4(m, 1, s, p); \ HT4(m, 1, s, p); \
HT4(m, 2, s, p); \ HT4(m, 2, s, p); \
HT4(m, 3, s, p); \ HT4(m, 3, s, p); \
#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])] #define FT(i, x) Sbox[gb(x, m[(i + x) & 3])]
#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; #define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])] #define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])]
#define HD4(m, i, s, p) m[i] = \ #define HD4(m, i, s, p) m[i] = \
HD(i, 0, s) ^ \ HD(i, 0, s) ^ \
HD(i, 1, s) ^ \ HD(i, 1, s) ^ \
HD(i, 2, s) ^ \ HD(i, 2, s) ^ \
HD(i, 3, s) ^ w[p + i]; HD(i, 3, s) ^ w[p + i];
#define HD16(m, s, p) \ #define HD16(m, s, p) \
HD4(m, 0, s, p); \ HD4(m, 0, s, p); \
HD4(m, 1, s, p); \ HD4(m, 1, s, p); \
HD4(m, 2, s, p); \ HD4(m, 2, s, p); \
HD4(m, 3, s, p); \ HD4(m, 3, s, p); \
#define FD(i, x) InvS[gb(x, m[(i - x) & 3])] #define FD(i, x) InvS[gb(x, m[(i - x) & 3])]
#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; #define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
{ {
unsigned i, wSize; unsigned i, wSize;
wSize = keySize + 28; wSize = keySize + 28;
keySize /= 4; keySize /= 4;
w[0] = ((UInt32)keySize / 2) + 3; w[0] = ((UInt32)keySize / 2) + 3;
w += 4; w += 4;
for (i = 0; i < keySize; i++, key += 4) for (i = 0; i < keySize; i++, key += 4)
w[i] = GetUi32(key); w[i] = GetUi32(key);
for (; i < wSize; i++) for (; i < wSize; i++)
{ {
UInt32 t = w[(size_t)i - 1]; UInt32 t = w[(size_t)i - 1];
unsigned rem = i % keySize; unsigned rem = i % keySize;
if (rem == 0) if (rem == 0)
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
else if (keySize > 6 && rem == 4) else if (keySize > 6 && rem == 4)
t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
w[i] = w[i - keySize] ^ t; w[i] = w[i - keySize] ^ t;
} }
} }
void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
{ {
unsigned i, num; unsigned i, num;
Aes_SetKey_Enc(w, key, keySize); Aes_SetKey_Enc(w, key, keySize);
num = keySize + 20; num = keySize + 20;
w += 8; w += 8;
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
UInt32 r = w[i]; UInt32 r = w[i];
w[i] = w[i] =
DD(0)[Sbox[gb0(r)]] ^ DD(0)[Sbox[gb0(r)]] ^
DD(1)[Sbox[gb1(r)]] ^ DD(1)[Sbox[gb1(r)]] ^
DD(2)[Sbox[gb2(r)]] ^ DD(2)[Sbox[gb2(r)]] ^
DD(3)[Sbox[gb3(r)]]; DD(3)[Sbox[gb3(r)]];
} }
} }
/* Aes_Encode and Aes_Decode functions work with little-endian words. /* Aes_Encode and Aes_Decode functions work with little-endian words.
src and dest are pointers to 4 UInt32 words. src and dest are pointers to 4 UInt32 words.
src and dest can point to same block */ src and dest can point to same block */
static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
{ {
UInt32 s[4]; UInt32 s[4];
UInt32 m[4]; UInt32 m[4];
UInt32 numRounds2 = w[0]; UInt32 numRounds2 = w[0];
w += 4; w += 4;
s[0] = src[0] ^ w[0]; s[0] = src[0] ^ w[0];
s[1] = src[1] ^ w[1]; s[1] = src[1] ^ w[1];
s[2] = src[2] ^ w[2]; s[2] = src[2] ^ w[2];
s[3] = src[3] ^ w[3]; s[3] = src[3] ^ w[3];
w += 4; w += 4;
for (;;) for (;;)
{ {
HT16(m, s, 0); HT16(m, s, 0);
if (--numRounds2 == 0) if (--numRounds2 == 0)
break; break;
HT16(s, m, 4); HT16(s, m, 4);
w += 8; w += 8;
} }
w += 4; w += 4;
FT4(0); FT4(1); FT4(2); FT4(3); FT4(0); FT4(1); FT4(2); FT4(3);
} }
static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
{ {
UInt32 s[4]; UInt32 s[4];
UInt32 m[4]; UInt32 m[4];
UInt32 numRounds2 = w[0]; UInt32 numRounds2 = w[0];
w += 4 + numRounds2 * 8; w += 4 + numRounds2 * 8;
s[0] = src[0] ^ w[0]; s[0] = src[0] ^ w[0];
s[1] = src[1] ^ w[1]; s[1] = src[1] ^ w[1];
s[2] = src[2] ^ w[2]; s[2] = src[2] ^ w[2];
s[3] = src[3] ^ w[3]; s[3] = src[3] ^ w[3];
for (;;) for (;;)
{ {
w -= 8; w -= 8;
HD16(m, s, 4); HD16(m, s, 4);
if (--numRounds2 == 0) if (--numRounds2 == 0)
break; break;
HD16(s, m, 0); HD16(s, m, 0);
} }
FD4(0); FD4(1); FD4(2); FD4(3); FD4(0); FD4(1); FD4(2); FD4(3);
} }
void AesCbc_Init(UInt32 *p, const Byte *iv) void AesCbc_Init(UInt32 *p, const Byte *iv)
{ {
unsigned i; unsigned i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p[i] = GetUi32(iv + i * 4); p[i] = GetUi32(iv + i * 4);
} }
void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
{ {
for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
{ {
p[0] ^= GetUi32(data); p[0] ^= GetUi32(data);
p[1] ^= GetUi32(data + 4); p[1] ^= GetUi32(data + 4);
p[2] ^= GetUi32(data + 8); p[2] ^= GetUi32(data + 8);
p[3] ^= GetUi32(data + 12); p[3] ^= GetUi32(data + 12);
Aes_Encode(p + 4, p, p); Aes_Encode(p + 4, p, p);
SetUi32(data, p[0]); SetUi32(data, p[0]);
SetUi32(data + 4, p[1]); SetUi32(data + 4, p[1]);
SetUi32(data + 8, p[2]); SetUi32(data + 8, p[2]);
SetUi32(data + 12, p[3]); SetUi32(data + 12, p[3]);
} }
} }
void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
{ {
UInt32 in[4], out[4]; UInt32 in[4], out[4];
for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
{ {
in[0] = GetUi32(data); in[0] = GetUi32(data);
in[1] = GetUi32(data + 4); in[1] = GetUi32(data + 4);
in[2] = GetUi32(data + 8); in[2] = GetUi32(data + 8);
in[3] = GetUi32(data + 12); in[3] = GetUi32(data + 12);
Aes_Decode(p + 4, out, in); Aes_Decode(p + 4, out, in);
SetUi32(data, p[0] ^ out[0]); SetUi32(data, p[0] ^ out[0]);
SetUi32(data + 4, p[1] ^ out[1]); SetUi32(data + 4, p[1] ^ out[1]);
SetUi32(data + 8, p[2] ^ out[2]); SetUi32(data + 8, p[2] ^ out[2]);
SetUi32(data + 12, p[3] ^ out[3]); SetUi32(data + 12, p[3] ^ out[3]);
p[0] = in[0]; p[0] = in[0];
p[1] = in[1]; p[1] = in[1];
p[2] = in[2]; p[2] = in[2];
p[3] = in[3]; p[3] = in[3];
} }
} }
void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
{ {
for (; numBlocks != 0; numBlocks--) for (; numBlocks != 0; numBlocks--)
{ {
UInt32 temp[4]; UInt32 temp[4];
unsigned i; unsigned i;
if (++p[0] == 0) if (++p[0] == 0)
p[1]++; p[1]++;
Aes_Encode(p + 4, temp, p); Aes_Encode(p + 4, temp, p);
for (i = 0; i < 4; i++, data += 4) for (i = 0; i < 4; i++, data += 4)
{ {
UInt32 t = temp[i]; UInt32 t = temp[i];
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
*((UInt32 *)data) ^= t; *((UInt32 *)data) ^= t;
#else #else
data[0] ^= (t & 0xFF); data[0] ^= (t & 0xFF);
data[1] ^= ((t >> 8) & 0xFF); data[1] ^= ((t >> 8) & 0xFF);
data[2] ^= ((t >> 16) & 0xFF); data[2] ^= ((t >> 16) & 0xFF);
data[3] ^= ((t >> 24)); data[3] ^= ((t >> 24));
#endif #endif
} }
} }
} }

76
C/Aes.h
View File

@@ -1,38 +1,38 @@
/* Aes.h -- AES encryption / decryption /* Aes.h -- AES encryption / decryption
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __AES_H #ifndef __AES_H
#define __AES_H #define __AES_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define AES_BLOCK_SIZE 16 #define AES_BLOCK_SIZE 16
/* Call AesGenTables one time before other AES functions */ /* Call AesGenTables one time before other AES functions */
void AesGenTables(void); void AesGenTables(void);
/* UInt32 pointers must be 16-byte aligned */ /* UInt32 pointers must be 16-byte aligned */
/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ /* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */
#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) #define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4)
/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ /* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */
/* keySize = 16 or 24 or 32 (bytes) */ /* keySize = 16 or 24 or 32 (bytes) */
typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); typedef void (MY_FAST_CALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize);
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize);
void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize);
/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ /* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */
void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
/* data - 16-byte aligned pointer to data */ /* data - 16-byte aligned pointer to data */
/* numBlocks - the number of 16-byte blocks in data array */ /* numBlocks - the number of 16-byte blocks in data array */
typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); typedef void (MY_FAST_CALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks);
extern AES_CODE_FUNC g_AesCbc_Encode; extern AES_CODE_FUNC g_AesCbc_Encode;
extern AES_CODE_FUNC g_AesCbc_Decode; extern AES_CODE_FUNC g_AesCbc_Decode;
extern AES_CODE_FUNC g_AesCtr_Code; extern AES_CODE_FUNC g_AesCtr_Code;
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,184 +1,184 @@
/* AesOpt.c -- Intel's AES /* AesOpt.c -- Intel's AES
2017-06-08 : Igor Pavlov : Public domain */ 2017-06-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
#if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729) #if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729)
#define USE_INTEL_AES #define USE_INTEL_AES
#endif #endif
#endif #endif
#ifdef USE_INTEL_AES #ifdef USE_INTEL_AES
#include <wmmintrin.h> #include <wmmintrin.h>
void MY_FAST_CALL AesCbc_Encode_Intel(__m128i *p, __m128i *data, size_t numBlocks) void MY_FAST_CALL AesCbc_Encode_Intel(__m128i *p, __m128i *data, size_t numBlocks)
{ {
__m128i m = *p; __m128i m = *p;
for (; numBlocks != 0; numBlocks--, data++) for (; numBlocks != 0; numBlocks--, data++)
{ {
UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
const __m128i *w = p + 3; const __m128i *w = p + 3;
m = _mm_xor_si128(m, *data); m = _mm_xor_si128(m, *data);
m = _mm_xor_si128(m, p[2]); m = _mm_xor_si128(m, p[2]);
do do
{ {
m = _mm_aesenc_si128(m, w[0]); m = _mm_aesenc_si128(m, w[0]);
m = _mm_aesenc_si128(m, w[1]); m = _mm_aesenc_si128(m, w[1]);
w += 2; w += 2;
} }
while (--numRounds2 != 0); while (--numRounds2 != 0);
m = _mm_aesenc_si128(m, w[0]); m = _mm_aesenc_si128(m, w[0]);
m = _mm_aesenclast_si128(m, w[1]); m = _mm_aesenclast_si128(m, w[1]);
*data = m; *data = m;
} }
*p = m; *p = m;
} }
#define NUM_WAYS 3 #define NUM_WAYS 3
#define AES_OP_W(op, n) { \ #define AES_OP_W(op, n) { \
const __m128i t = w[n]; \ const __m128i t = w[n]; \
m0 = op(m0, t); \ m0 = op(m0, t); \
m1 = op(m1, t); \ m1 = op(m1, t); \
m2 = op(m2, t); \ m2 = op(m2, t); \
} }
#define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n) #define AES_DEC(n) AES_OP_W(_mm_aesdec_si128, n)
#define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n) #define AES_DEC_LAST(n) AES_OP_W(_mm_aesdeclast_si128, n)
#define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n) #define AES_ENC(n) AES_OP_W(_mm_aesenc_si128, n)
#define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n) #define AES_ENC_LAST(n) AES_OP_W(_mm_aesenclast_si128, n)
void MY_FAST_CALL AesCbc_Decode_Intel(__m128i *p, __m128i *data, size_t numBlocks) void MY_FAST_CALL AesCbc_Decode_Intel(__m128i *p, __m128i *data, size_t numBlocks)
{ {
__m128i iv = *p; __m128i iv = *p;
for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS) for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
{ {
UInt32 numRounds2 = *(const UInt32 *)(p + 1); UInt32 numRounds2 = *(const UInt32 *)(p + 1);
const __m128i *w = p + numRounds2 * 2; const __m128i *w = p + numRounds2 * 2;
__m128i m0, m1, m2; __m128i m0, m1, m2;
{ {
const __m128i t = w[2]; const __m128i t = w[2];
m0 = _mm_xor_si128(t, data[0]); m0 = _mm_xor_si128(t, data[0]);
m1 = _mm_xor_si128(t, data[1]); m1 = _mm_xor_si128(t, data[1]);
m2 = _mm_xor_si128(t, data[2]); m2 = _mm_xor_si128(t, data[2]);
} }
numRounds2--; numRounds2--;
do do
{ {
AES_DEC(1) AES_DEC(1)
AES_DEC(0) AES_DEC(0)
w -= 2; w -= 2;
} }
while (--numRounds2 != 0); while (--numRounds2 != 0);
AES_DEC(1) AES_DEC(1)
AES_DEC_LAST(0) AES_DEC_LAST(0)
{ {
__m128i t; __m128i t;
t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t; t = _mm_xor_si128(m0, iv); iv = data[0]; data[0] = t;
t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t; t = _mm_xor_si128(m1, iv); iv = data[1]; data[1] = t;
t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t; t = _mm_xor_si128(m2, iv); iv = data[2]; data[2] = t;
} }
} }
for (; numBlocks != 0; numBlocks--, data++) for (; numBlocks != 0; numBlocks--, data++)
{ {
UInt32 numRounds2 = *(const UInt32 *)(p + 1); UInt32 numRounds2 = *(const UInt32 *)(p + 1);
const __m128i *w = p + numRounds2 * 2; const __m128i *w = p + numRounds2 * 2;
__m128i m = _mm_xor_si128(w[2], *data); __m128i m = _mm_xor_si128(w[2], *data);
numRounds2--; numRounds2--;
do do
{ {
m = _mm_aesdec_si128(m, w[1]); m = _mm_aesdec_si128(m, w[1]);
m = _mm_aesdec_si128(m, w[0]); m = _mm_aesdec_si128(m, w[0]);
w -= 2; w -= 2;
} }
while (--numRounds2 != 0); while (--numRounds2 != 0);
m = _mm_aesdec_si128(m, w[1]); m = _mm_aesdec_si128(m, w[1]);
m = _mm_aesdeclast_si128(m, w[0]); m = _mm_aesdeclast_si128(m, w[0]);
m = _mm_xor_si128(m, iv); m = _mm_xor_si128(m, iv);
iv = *data; iv = *data;
*data = m; *data = m;
} }
*p = iv; *p = iv;
} }
void MY_FAST_CALL AesCtr_Code_Intel(__m128i *p, __m128i *data, size_t numBlocks) void MY_FAST_CALL AesCtr_Code_Intel(__m128i *p, __m128i *data, size_t numBlocks)
{ {
__m128i ctr = *p; __m128i ctr = *p;
__m128i one; __m128i one;
one.m128i_u64[0] = 1; one.m128i_u64[0] = 1;
one.m128i_u64[1] = 0; one.m128i_u64[1] = 0;
for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS) for (; numBlocks >= NUM_WAYS; numBlocks -= NUM_WAYS, data += NUM_WAYS)
{ {
UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
const __m128i *w = p; const __m128i *w = p;
__m128i m0, m1, m2; __m128i m0, m1, m2;
{ {
const __m128i t = w[2]; const __m128i t = w[2];
ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t); ctr = _mm_add_epi64(ctr, one); m0 = _mm_xor_si128(ctr, t);
ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t); ctr = _mm_add_epi64(ctr, one); m1 = _mm_xor_si128(ctr, t);
ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t); ctr = _mm_add_epi64(ctr, one); m2 = _mm_xor_si128(ctr, t);
} }
w += 3; w += 3;
do do
{ {
AES_ENC(0) AES_ENC(0)
AES_ENC(1) AES_ENC(1)
w += 2; w += 2;
} }
while (--numRounds2 != 0); while (--numRounds2 != 0);
AES_ENC(0) AES_ENC(0)
AES_ENC_LAST(1) AES_ENC_LAST(1)
data[0] = _mm_xor_si128(data[0], m0); data[0] = _mm_xor_si128(data[0], m0);
data[1] = _mm_xor_si128(data[1], m1); data[1] = _mm_xor_si128(data[1], m1);
data[2] = _mm_xor_si128(data[2], m2); data[2] = _mm_xor_si128(data[2], m2);
} }
for (; numBlocks != 0; numBlocks--, data++) for (; numBlocks != 0; numBlocks--, data++)
{ {
UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1;
const __m128i *w = p; const __m128i *w = p;
__m128i m; __m128i m;
ctr = _mm_add_epi64(ctr, one); ctr = _mm_add_epi64(ctr, one);
m = _mm_xor_si128(ctr, p[2]); m = _mm_xor_si128(ctr, p[2]);
w += 3; w += 3;
do do
{ {
m = _mm_aesenc_si128(m, w[0]); m = _mm_aesenc_si128(m, w[0]);
m = _mm_aesenc_si128(m, w[1]); m = _mm_aesenc_si128(m, w[1]);
w += 2; w += 2;
} }
while (--numRounds2 != 0); while (--numRounds2 != 0);
m = _mm_aesenc_si128(m, w[0]); m = _mm_aesenc_si128(m, w[0]);
m = _mm_aesenclast_si128(m, w[1]); m = _mm_aesenclast_si128(m, w[1]);
*data = _mm_xor_si128(*data, m); *data = _mm_xor_si128(*data, m);
} }
*p = ctr; *p = ctr;
} }
#else #else
void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCbc_Encode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCbc_Decode(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks); void MY_FAST_CALL AesCtr_Code(UInt32 *ivAes, Byte *data, size_t numBlocks);
void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks) void MY_FAST_CALL AesCbc_Encode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
{ {
AesCbc_Encode(p, data, numBlocks); AesCbc_Encode(p, data, numBlocks);
} }
void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks) void MY_FAST_CALL AesCbc_Decode_Intel(UInt32 *p, Byte *data, size_t numBlocks)
{ {
AesCbc_Decode(p, data, numBlocks); AesCbc_Decode(p, data, numBlocks);
} }
void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks) void MY_FAST_CALL AesCtr_Code_Intel(UInt32 *p, Byte *data, size_t numBlocks)
{ {
AesCtr_Code(p, data, numBlocks); AesCtr_Code(p, data, numBlocks);
} }
#endif #endif

910
C/Alloc.c
View File

@@ -1,455 +1,455 @@
/* Alloc.c -- Memory allocation functions /* Alloc.c -- Memory allocation functions
2018-04-27 : Igor Pavlov : Public domain */ 2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdio.h> #include <stdio.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include "Alloc.h" #include "Alloc.h"
/* #define _SZ_ALLOC_DEBUG */ /* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */ /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
#include <stdio.h> #include <stdio.h>
int g_allocCount = 0; int g_allocCount = 0;
int g_allocCountMid = 0; int g_allocCountMid = 0;
int g_allocCountBig = 0; int g_allocCountBig = 0;
#define CONVERT_INT_TO_STR(charType, tempSize) \ #define CONVERT_INT_TO_STR(charType, tempSize) \
unsigned char temp[tempSize]; unsigned i = 0; \ unsigned char temp[tempSize]; unsigned i = 0; \
while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \ while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
*s++ = (charType)('0' + (unsigned)val); \ *s++ = (charType)('0' + (unsigned)val); \
while (i != 0) { i--; *s++ = temp[i]; } \ while (i != 0) { i--; *s++ = temp[i]; } \
*s = 0; *s = 0;
static void ConvertUInt64ToString(UInt64 val, char *s) static void ConvertUInt64ToString(UInt64 val, char *s)
{ {
CONVERT_INT_TO_STR(char, 24); CONVERT_INT_TO_STR(char, 24);
} }
#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) #define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
static void ConvertUInt64ToHex(UInt64 val, char *s) static void ConvertUInt64ToHex(UInt64 val, char *s)
{ {
UInt64 v = val; UInt64 v = val;
unsigned i; unsigned i;
for (i = 1;; i++) for (i = 1;; i++)
{ {
v >>= 4; v >>= 4;
if (v == 0) if (v == 0)
break; break;
} }
s[i] = 0; s[i] = 0;
do do
{ {
unsigned t = (unsigned)(val & 0xF); unsigned t = (unsigned)(val & 0xF);
val >>= 4; val >>= 4;
s[--i] = GET_HEX_CHAR(t); s[--i] = GET_HEX_CHAR(t);
} }
while (i); while (i);
} }
#define DEBUG_OUT_STREAM stderr #define DEBUG_OUT_STREAM stderr
static void Print(const char *s) static void Print(const char *s)
{ {
fputs(s, DEBUG_OUT_STREAM); fputs(s, DEBUG_OUT_STREAM);
} }
static void PrintAligned(const char *s, size_t align) static void PrintAligned(const char *s, size_t align)
{ {
size_t len = strlen(s); size_t len = strlen(s);
for(;;) for(;;)
{ {
fputc(' ', DEBUG_OUT_STREAM); fputc(' ', DEBUG_OUT_STREAM);
if (len >= align) if (len >= align)
break; break;
++len; ++len;
} }
Print(s); Print(s);
} }
static void PrintLn() static void PrintLn()
{ {
Print("\n"); Print("\n");
} }
static void PrintHex(UInt64 v, size_t align) static void PrintHex(UInt64 v, size_t align)
{ {
char s[32]; char s[32];
ConvertUInt64ToHex(v, s); ConvertUInt64ToHex(v, s);
PrintAligned(s, align); PrintAligned(s, align);
} }
static void PrintDec(UInt64 v, size_t align) static void PrintDec(UInt64 v, size_t align)
{ {
char s[32]; char s[32];
ConvertUInt64ToString(v, s); ConvertUInt64ToString(v, s);
PrintAligned(s, align); PrintAligned(s, align);
} }
static void PrintAddr(void *p) static void PrintAddr(void *p)
{ {
PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12); PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
} }
#define PRINT_ALLOC(name, cnt, size, ptr) \ #define PRINT_ALLOC(name, cnt, size, ptr) \
Print(name " "); \ Print(name " "); \
PrintDec(cnt++, 10); \ PrintDec(cnt++, 10); \
PrintHex(size, 10); \ PrintHex(size, 10); \
PrintAddr(ptr); \ PrintAddr(ptr); \
PrintLn(); PrintLn();
#define PRINT_FREE(name, cnt, ptr) if (ptr) { \ #define PRINT_FREE(name, cnt, ptr) if (ptr) { \
Print(name " "); \ Print(name " "); \
PrintDec(--cnt, 10); \ PrintDec(--cnt, 10); \
PrintAddr(ptr); \ PrintAddr(ptr); \
PrintLn(); } PrintLn(); }
#else #else
#define PRINT_ALLOC(name, cnt, size, ptr) #define PRINT_ALLOC(name, cnt, size, ptr)
#define PRINT_FREE(name, cnt, ptr) #define PRINT_FREE(name, cnt, ptr)
#define Print(s) #define Print(s)
#define PrintLn() #define PrintLn()
#define PrintHex(v, align) #define PrintHex(v, align)
#define PrintDec(v, align) #define PrintDec(v, align)
#define PrintAddr(p) #define PrintAddr(p)
#endif #endif
void *MyAlloc(size_t size) void *MyAlloc(size_t size)
{ {
if (size == 0) if (size == 0)
return NULL; return NULL;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
{ {
void *p = malloc(size); void *p = malloc(size);
PRINT_ALLOC("Alloc ", g_allocCount, size, p); PRINT_ALLOC("Alloc ", g_allocCount, size, p);
return p; return p;
} }
#else #else
return malloc(size); return malloc(size);
#endif #endif
} }
void MyFree(void *address) void MyFree(void *address)
{ {
PRINT_FREE("Free ", g_allocCount, address); PRINT_FREE("Free ", g_allocCount, address);
free(address); free(address);
} }
#ifdef _WIN32 #ifdef _WIN32
void *MidAlloc(size_t size) void *MidAlloc(size_t size)
{ {
if (size == 0) if (size == 0)
return NULL; return NULL;
PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL); PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
} }
void MidFree(void *address) void MidFree(void *address)
{ {
PRINT_FREE("Free-Mid", g_allocCountMid, address); PRINT_FREE("Free-Mid", g_allocCountMid, address);
if (!address) if (!address)
return; return;
VirtualFree(address, 0, MEM_RELEASE); VirtualFree(address, 0, MEM_RELEASE);
} }
#ifndef MEM_LARGE_PAGES #ifndef MEM_LARGE_PAGES
#undef _7ZIP_LARGE_PAGES #undef _7ZIP_LARGE_PAGES
#endif #endif
#ifdef _7ZIP_LARGE_PAGES #ifdef _7ZIP_LARGE_PAGES
SIZE_T g_LargePageSize = 0; SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
#endif #endif
void SetLargePageSize() void SetLargePageSize()
{ {
#ifdef _7ZIP_LARGE_PAGES #ifdef _7ZIP_LARGE_PAGES
SIZE_T size; SIZE_T size;
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP) GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum"); GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
if (!largePageMinimum) if (!largePageMinimum)
return; return;
size = largePageMinimum(); size = largePageMinimum();
if (size == 0 || (size & (size - 1)) != 0) if (size == 0 || (size & (size - 1)) != 0)
return; return;
g_LargePageSize = size; g_LargePageSize = size;
#endif #endif
} }
void *BigAlloc(size_t size) void *BigAlloc(size_t size)
{ {
if (size == 0) if (size == 0)
return NULL; return NULL;
PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL); PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
#ifdef _7ZIP_LARGE_PAGES #ifdef _7ZIP_LARGE_PAGES
{ {
SIZE_T ps = g_LargePageSize; SIZE_T ps = g_LargePageSize;
if (ps != 0 && ps <= (1 << 30) && size > (ps / 2)) if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
{ {
size_t size2; size_t size2;
ps--; ps--;
size2 = (size + ps) & ~ps; size2 = (size + ps) & ~ps;
if (size2 >= size) if (size2 >= size)
{ {
void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE); void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
if (res) if (res)
return res; return res;
} }
} }
} }
#endif #endif
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
} }
void BigFree(void *address) void BigFree(void *address)
{ {
PRINT_FREE("Free-Big", g_allocCountBig, address); PRINT_FREE("Free-Big", g_allocCountBig, address);
if (!address) if (!address)
return; return;
VirtualFree(address, 0, MEM_RELEASE); VirtualFree(address, 0, MEM_RELEASE);
} }
#endif #endif
static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); } static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); } static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
const ISzAlloc g_Alloc = { SzAlloc, SzFree }; const ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); } static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); } static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree }; const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); } static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); } static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
/* /*
uintptr_t : <stdint.h> C99 (optional) uintptr_t : <stdint.h> C99 (optional)
: unsupported in VS6 : unsupported in VS6
*/ */
#ifdef _WIN32 #ifdef _WIN32
typedef UINT_PTR UIntPtr; typedef UINT_PTR UIntPtr;
#else #else
/* /*
typedef uintptr_t UIntPtr; typedef uintptr_t UIntPtr;
*/ */
typedef ptrdiff_t UIntPtr; typedef ptrdiff_t UIntPtr;
#endif #endif
#define ADJUST_ALLOC_SIZE 0 #define ADJUST_ALLOC_SIZE 0
/* /*
#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1) #define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
*/ */
/* /*
Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
MyAlloc() can return address that is NOT multiple of sizeof(void *). MyAlloc() can return address that is NOT multiple of sizeof(void *).
*/ */
/* /*
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1)))) #define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
*/ */
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1)))) #define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align) #define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32) #if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
#define USE_posix_memalign #define USE_posix_memalign
#endif #endif
/* /*
This posix_memalign() is for test purposes only. This posix_memalign() is for test purposes only.
We also need special Free() function instead of free(), We also need special Free() function instead of free(),
if this posix_memalign() is used. if this posix_memalign() is used.
*/ */
/* /*
static int posix_memalign(void **ptr, size_t align, size_t size) static int posix_memalign(void **ptr, size_t align, size_t size)
{ {
size_t newSize = size + align; size_t newSize = size + align;
void *p; void *p;
void *pAligned; void *pAligned;
*ptr = NULL; *ptr = NULL;
if (newSize < size) if (newSize < size)
return 12; // ENOMEM return 12; // ENOMEM
p = MyAlloc(newSize); p = MyAlloc(newSize);
if (!p) if (!p)
return 12; // ENOMEM return 12; // ENOMEM
pAligned = MY_ALIGN_PTR_UP_PLUS(p, align); pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
((void **)pAligned)[-1] = p; ((void **)pAligned)[-1] = p;
*ptr = pAligned; *ptr = pAligned;
return 0; return 0;
} }
*/ */
/* /*
ALLOC_ALIGN_SIZE >= sizeof(void *) ALLOC_ALIGN_SIZE >= sizeof(void *)
ALLOC_ALIGN_SIZE >= cache_line_size ALLOC_ALIGN_SIZE >= cache_line_size
*/ */
#define ALLOC_ALIGN_SIZE ((size_t)1 << 7) #define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size) static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
{ {
#ifndef USE_posix_memalign #ifndef USE_posix_memalign
void *p; void *p;
void *pAligned; void *pAligned;
size_t newSize; size_t newSize;
UNUSED_VAR(pp); UNUSED_VAR(pp);
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */ block to prevent cache line sharing with another allocated blocks */
newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE; newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
if (newSize < size) if (newSize < size)
return NULL; return NULL;
p = MyAlloc(newSize); p = MyAlloc(newSize);
if (!p) if (!p)
return NULL; return NULL;
pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE); pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
Print(" size="); PrintHex(size, 8); Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8); Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(p); Print(" ptr="); PrintAddr(p);
Print(" a_ptr="); PrintAddr(pAligned); Print(" a_ptr="); PrintAddr(pAligned);
PrintLn(); PrintLn();
((void **)pAligned)[-1] = p; ((void **)pAligned)[-1] = p;
return pAligned; return pAligned;
#else #else
void *p; void *p;
UNUSED_VAR(pp); UNUSED_VAR(pp);
if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size)) if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
return NULL; return NULL;
Print(" posix_memalign="); PrintAddr(p); Print(" posix_memalign="); PrintAddr(p);
PrintLn(); PrintLn();
return p; return p;
#endif #endif
} }
static void SzAlignedFree(ISzAllocPtr pp, void *address) static void SzAlignedFree(ISzAllocPtr pp, void *address)
{ {
UNUSED_VAR(pp); UNUSED_VAR(pp);
#ifndef USE_posix_memalign #ifndef USE_posix_memalign
if (address) if (address)
MyFree(((void **)address)[-1]); MyFree(((void **)address)[-1]);
#else #else
free(address); free(address);
#endif #endif
} }
const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree }; const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *)) #define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */ /* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1] #define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
/* /*
#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1] #define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
*/ */
static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size) static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
{ {
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt); CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
void *adr; void *adr;
void *pAligned; void *pAligned;
size_t newSize; size_t newSize;
size_t extra; size_t extra;
size_t alignSize = (size_t)1 << p->numAlignBits; size_t alignSize = (size_t)1 << p->numAlignBits;
if (alignSize < sizeof(void *)) if (alignSize < sizeof(void *))
alignSize = sizeof(void *); alignSize = sizeof(void *);
if (p->offset >= alignSize) if (p->offset >= alignSize)
return NULL; return NULL;
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */ block to prevent cache line sharing with another allocated blocks */
extra = p->offset & (sizeof(void *) - 1); extra = p->offset & (sizeof(void *) - 1);
newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE; newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
if (newSize < size) if (newSize < size)
return NULL; return NULL;
adr = ISzAlloc_Alloc(p->baseAlloc, newSize); adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
if (!adr) if (!adr)
return NULL; return NULL;
pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr + pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset; alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
PrintLn(); PrintLn();
Print("- Aligned: "); Print("- Aligned: ");
Print(" size="); PrintHex(size, 8); Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8); Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(adr); Print(" ptr="); PrintAddr(adr);
Print(" a_ptr="); PrintAddr(pAligned); Print(" a_ptr="); PrintAddr(pAligned);
PrintLn(); PrintLn();
REAL_BLOCK_PTR_VAR(pAligned) = adr; REAL_BLOCK_PTR_VAR(pAligned) = adr;
return pAligned; return pAligned;
} }
static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address) static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
{ {
if (address) if (address)
{ {
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt); CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
PrintLn(); PrintLn();
Print("- Aligned Free: "); Print("- Aligned Free: ");
PrintLn(); PrintLn();
ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address)); ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
} }
} }
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p) void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
{ {
p->vt.Alloc = AlignOffsetAlloc_Alloc; p->vt.Alloc = AlignOffsetAlloc_Alloc;
p->vt.Free = AlignOffsetAlloc_Free; p->vt.Free = AlignOffsetAlloc_Free;
} }

102
C/Alloc.h
View File

@@ -1,51 +1,51 @@
/* Alloc.h -- Memory allocation functions /* Alloc.h -- Memory allocation functions
2018-02-19 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H #ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H #define __COMMON_ALLOC_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
void *MyAlloc(size_t size); void *MyAlloc(size_t size);
void MyFree(void *address); void MyFree(void *address);
#ifdef _WIN32 #ifdef _WIN32
void SetLargePageSize(); void SetLargePageSize();
void *MidAlloc(size_t size); void *MidAlloc(size_t size);
void MidFree(void *address); void MidFree(void *address);
void *BigAlloc(size_t size); void *BigAlloc(size_t size);
void BigFree(void *address); void BigFree(void *address);
#else #else
#define MidAlloc(size) MyAlloc(size) #define MidAlloc(size) MyAlloc(size)
#define MidFree(address) MyFree(address) #define MidFree(address) MyFree(address)
#define BigAlloc(size) MyAlloc(size) #define BigAlloc(size) MyAlloc(size)
#define BigFree(address) MyFree(address) #define BigFree(address) MyFree(address)
#endif #endif
extern const ISzAlloc g_Alloc; extern const ISzAlloc g_Alloc;
extern const ISzAlloc g_BigAlloc; extern const ISzAlloc g_BigAlloc;
extern const ISzAlloc g_MidAlloc; extern const ISzAlloc g_MidAlloc;
extern const ISzAlloc g_AlignedAlloc; extern const ISzAlloc g_AlignedAlloc;
typedef struct typedef struct
{ {
ISzAlloc vt; ISzAlloc vt;
ISzAllocPtr baseAlloc; ISzAllocPtr baseAlloc;
unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */ unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */ size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
} CAlignOffsetAlloc; } CAlignOffsetAlloc;
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p); void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
EXTERN_C_END EXTERN_C_END
#endif #endif

514
C/Bcj2.c
View File

@@ -1,257 +1,257 @@
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2018-04-28 : Igor Pavlov : Public domain */ 2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "CpuArch.h" #include "CpuArch.h"
#define CProb UInt16 #define CProb UInt16
#define kTopValue ((UInt32)1 << 24) #define kTopValue ((UInt32)1 << 24)
#define kNumModelBits 11 #define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits) #define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5 #define kNumMoveBits 5
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
void Bcj2Dec_Init(CBcj2Dec *p) void Bcj2Dec_Init(CBcj2Dec *p)
{ {
unsigned i; unsigned i;
p->state = BCJ2_DEC_STATE_OK; p->state = BCJ2_DEC_STATE_OK;
p->ip = 0; p->ip = 0;
p->temp[3] = 0; p->temp[3] = 0;
p->range = 0; p->range = 0;
p->code = 0; p->code = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1; p->probs[i] = kBitModelTotal >> 1;
} }
SRes Bcj2Dec_Decode(CBcj2Dec *p) SRes Bcj2Dec_Decode(CBcj2Dec *p)
{ {
if (p->range <= 5) if (p->range <= 5)
{ {
p->state = BCJ2_DEC_STATE_OK; p->state = BCJ2_DEC_STATE_OK;
for (; p->range != 5; p->range++) for (; p->range != 5; p->range++)
{ {
if (p->range == 1 && p->code != 0) if (p->range == 1 && p->code != 0)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{ {
p->state = BCJ2_STREAM_RC; p->state = BCJ2_STREAM_RC;
return SZ_OK; return SZ_OK;
} }
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
} }
if (p->code == 0xFFFFFFFF) if (p->code == 0xFFFFFFFF)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
p->range = 0xFFFFFFFF; p->range = 0xFFFFFFFF;
} }
else if (p->state >= BCJ2_DEC_STATE_ORIG_0) else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{ {
while (p->state <= BCJ2_DEC_STATE_ORIG_3) while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{ {
Byte *dest = p->dest; Byte *dest = p->dest;
if (dest == p->destLim) if (dest == p->destLim)
return SZ_OK; return SZ_OK;
*dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
p->state++; p->state++;
p->dest = dest + 1; p->dest = dest + 1;
} }
} }
/* /*
if (BCJ2_IS_32BIT_STREAM(p->state)) if (BCJ2_IS_32BIT_STREAM(p->state))
{ {
const Byte *cur = p->bufs[p->state]; const Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state]) if (cur == p->lims[p->state])
return SZ_OK; return SZ_OK;
p->bufs[p->state] = cur + 4; p->bufs[p->state] = cur + 4;
{ {
UInt32 val; UInt32 val;
Byte *dest; Byte *dest;
SizeT rem; SizeT rem;
p->ip += 4; p->ip += 4;
val = GetBe32(cur) - p->ip; val = GetBe32(cur) - p->ip;
dest = p->dest; dest = p->dest;
rem = p->destLim - dest; rem = p->destLim - dest;
if (rem < 4) if (rem < 4)
{ {
SizeT i; SizeT i;
SetUi32(p->temp, val); SetUi32(p->temp, val);
for (i = 0; i < rem; i++) for (i = 0; i < rem; i++)
dest[i] = p->temp[i]; dest[i] = p->temp[i];
p->dest = dest + rem; p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
return SZ_OK; return SZ_OK;
} }
SetUi32(dest, val); SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24); p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4; p->dest = dest + 4;
p->state = BCJ2_DEC_STATE_OK; p->state = BCJ2_DEC_STATE_OK;
} }
} }
*/ */
for (;;) for (;;)
{ {
if (BCJ2_IS_32BIT_STREAM(p->state)) if (BCJ2_IS_32BIT_STREAM(p->state))
p->state = BCJ2_DEC_STATE_OK; p->state = BCJ2_DEC_STATE_OK;
else else
{ {
if (p->range < kTopValue) if (p->range < kTopValue)
{ {
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{ {
p->state = BCJ2_STREAM_RC; p->state = BCJ2_STREAM_RC;
return SZ_OK; return SZ_OK;
} }
p->range <<= 8; p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
} }
{ {
const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
const Byte *srcLim; const Byte *srcLim;
Byte *dest; Byte *dest;
SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
if (num == 0) if (num == 0)
{ {
p->state = BCJ2_STREAM_MAIN; p->state = BCJ2_STREAM_MAIN;
return SZ_OK; return SZ_OK;
} }
dest = p->dest; dest = p->dest;
if (num > (SizeT)(p->destLim - dest)) if (num > (SizeT)(p->destLim - dest))
{ {
num = p->destLim - dest; num = p->destLim - dest;
if (num == 0) if (num == 0)
{ {
p->state = BCJ2_DEC_STATE_ORIG; p->state = BCJ2_DEC_STATE_ORIG;
return SZ_OK; return SZ_OK;
} }
} }
srcLim = src + num; srcLim = src + num;
if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0]; *dest = src[0];
else for (;;) else for (;;)
{ {
Byte b = *src; Byte b = *src;
*dest = b; *dest = b;
if (b != 0x0F) if (b != 0x0F)
{ {
if ((b & 0xFE) == 0xE8) if ((b & 0xFE) == 0xE8)
break; break;
dest++; dest++;
if (++src != srcLim) if (++src != srcLim)
continue; continue;
break; break;
} }
dest++; dest++;
if (++src == srcLim) if (++src == srcLim)
break; break;
if ((*src & 0xF0) != 0x80) if ((*src & 0xF0) != 0x80)
continue; continue;
*dest = *src; *dest = *src;
break; break;
} }
num = src - p->bufs[BCJ2_STREAM_MAIN]; num = src - p->bufs[BCJ2_STREAM_MAIN];
if (src == srcLim) if (src == srcLim)
{ {
p->temp[3] = src[-1]; p->temp[3] = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = src; p->bufs[BCJ2_STREAM_MAIN] = src;
p->ip += (UInt32)num; p->ip += (UInt32)num;
p->dest += num; p->dest += num;
p->state = p->state =
p->bufs[BCJ2_STREAM_MAIN] == p->bufs[BCJ2_STREAM_MAIN] ==
p->lims[BCJ2_STREAM_MAIN] ? p->lims[BCJ2_STREAM_MAIN] ?
(unsigned)BCJ2_STREAM_MAIN : (unsigned)BCJ2_STREAM_MAIN :
(unsigned)BCJ2_DEC_STATE_ORIG; (unsigned)BCJ2_DEC_STATE_ORIG;
return SZ_OK; return SZ_OK;
} }
{ {
UInt32 bound, ttt; UInt32 bound, ttt;
CProb *prob; CProb *prob;
Byte b = src[0]; Byte b = src[0];
Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
p->temp[3] = b; p->temp[3] = b;
p->bufs[BCJ2_STREAM_MAIN] = src + 1; p->bufs[BCJ2_STREAM_MAIN] = src + 1;
num++; num++;
p->ip += (UInt32)num; p->ip += (UInt32)num;
p->dest += num; p->dest += num;
prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
_IF_BIT_0 _IF_BIT_0
{ {
_UPDATE_0 _UPDATE_0
continue; continue;
} }
_UPDATE_1 _UPDATE_1
} }
} }
} }
{ {
UInt32 val; UInt32 val;
unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
const Byte *cur = p->bufs[cj]; const Byte *cur = p->bufs[cj];
Byte *dest; Byte *dest;
SizeT rem; SizeT rem;
if (cur == p->lims[cj]) if (cur == p->lims[cj])
{ {
p->state = cj; p->state = cj;
break; break;
} }
val = GetBe32(cur); val = GetBe32(cur);
p->bufs[cj] = cur + 4; p->bufs[cj] = cur + 4;
p->ip += 4; p->ip += 4;
val -= p->ip; val -= p->ip;
dest = p->dest; dest = p->dest;
rem = p->destLim - dest; rem = p->destLim - dest;
if (rem < 4) if (rem < 4)
{ {
p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8; p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8; p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8; p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
p->temp[3] = (Byte)val; p->temp[3] = (Byte)val;
p->dest = dest + rem; p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break; break;
} }
SetUi32(dest, val); SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24); p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4; p->dest = dest + 4;
} }
} }
if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
{ {
p->range <<= 8; p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
} }
return SZ_OK; return SZ_OK;
} }

292
C/Bcj2.h
View File

@@ -1,146 +1,146 @@
/* Bcj2.h -- BCJ2 Converter for x86 code /* Bcj2.h -- BCJ2 Converter for x86 code
2014-11-10 : Igor Pavlov : Public domain */ 2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H #ifndef __BCJ2_H
#define __BCJ2_H #define __BCJ2_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define BCJ2_NUM_STREAMS 4 #define BCJ2_NUM_STREAMS 4
enum enum
{ {
BCJ2_STREAM_MAIN, BCJ2_STREAM_MAIN,
BCJ2_STREAM_CALL, BCJ2_STREAM_CALL,
BCJ2_STREAM_JUMP, BCJ2_STREAM_JUMP,
BCJ2_STREAM_RC BCJ2_STREAM_RC
}; };
enum enum
{ {
BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
BCJ2_DEC_STATE_ORIG_1, BCJ2_DEC_STATE_ORIG_1,
BCJ2_DEC_STATE_ORIG_2, BCJ2_DEC_STATE_ORIG_2,
BCJ2_DEC_STATE_ORIG_3, BCJ2_DEC_STATE_ORIG_3,
BCJ2_DEC_STATE_ORIG, BCJ2_DEC_STATE_ORIG,
BCJ2_DEC_STATE_OK BCJ2_DEC_STATE_OK
}; };
enum enum
{ {
BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
BCJ2_ENC_STATE_OK BCJ2_ENC_STATE_OK
}; };
#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
/* /*
CBcj2Dec / CBcj2Enc CBcj2Dec / CBcj2Enc
bufs sizes: bufs sizes:
BUF_SIZE(n) = lims[n] - bufs[n] BUF_SIZE(n) = lims[n] - bufs[n]
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
*/ */
/* /*
CBcj2Dec: CBcj2Dec:
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
bufs[BCJ2_STREAM_MAIN] >= dest && bufs[BCJ2_STREAM_MAIN] >= dest &&
bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
BUF_SIZE(BCJ2_STREAM_CALL) + BUF_SIZE(BCJ2_STREAM_CALL) +
BUF_SIZE(BCJ2_STREAM_JUMP) BUF_SIZE(BCJ2_STREAM_JUMP)
tempReserv = 0 : for first call of Bcj2Dec_Decode tempReserv = 0 : for first call of Bcj2Dec_Decode
tempReserv = 4 : for any other calls of Bcj2Dec_Decode tempReserv = 4 : for any other calls of Bcj2Dec_Decode
overlap with offset = 1 is not allowed overlap with offset = 1 is not allowed
*/ */
typedef struct typedef struct
{ {
const Byte *bufs[BCJ2_NUM_STREAMS]; const Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS]; const Byte *lims[BCJ2_NUM_STREAMS];
Byte *dest; Byte *dest;
const Byte *destLim; const Byte *destLim;
unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
UInt32 ip; UInt32 ip;
Byte temp[4]; Byte temp[4];
UInt32 range; UInt32 range;
UInt32 code; UInt32 code;
UInt16 probs[2 + 256]; UInt16 probs[2 + 256];
} CBcj2Dec; } CBcj2Dec;
void Bcj2Dec_Init(CBcj2Dec *p); void Bcj2Dec_Init(CBcj2Dec *p);
/* Returns: SZ_OK or SZ_ERROR_DATA */ /* Returns: SZ_OK or SZ_ERROR_DATA */
SRes Bcj2Dec_Decode(CBcj2Dec *p); SRes Bcj2Dec_Decode(CBcj2Dec *p);
#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) #define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
typedef enum typedef enum
{ {
BCJ2_ENC_FINISH_MODE_CONTINUE, BCJ2_ENC_FINISH_MODE_CONTINUE,
BCJ2_ENC_FINISH_MODE_END_BLOCK, BCJ2_ENC_FINISH_MODE_END_BLOCK,
BCJ2_ENC_FINISH_MODE_END_STREAM BCJ2_ENC_FINISH_MODE_END_STREAM
} EBcj2Enc_FinishMode; } EBcj2Enc_FinishMode;
typedef struct typedef struct
{ {
Byte *bufs[BCJ2_NUM_STREAMS]; Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS]; const Byte *lims[BCJ2_NUM_STREAMS];
const Byte *src; const Byte *src;
const Byte *srcLim; const Byte *srcLim;
unsigned state; unsigned state;
EBcj2Enc_FinishMode finishMode; EBcj2Enc_FinishMode finishMode;
Byte prevByte; Byte prevByte;
Byte cache; Byte cache;
UInt32 range; UInt32 range;
UInt64 low; UInt64 low;
UInt64 cacheSize; UInt64 cacheSize;
UInt32 ip; UInt32 ip;
/* 32-bit ralative offset in JUMP/CALL commands is /* 32-bit ralative offset in JUMP/CALL commands is
- (mod 4 GB) in 32-bit mode - (mod 4 GB) in 32-bit mode
- signed Int32 in 64-bit mode - signed Int32 in 64-bit mode
We use (mod 4 GB) check for fileSize. We use (mod 4 GB) check for fileSize.
Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
UInt32 fileIp; UInt32 fileIp;
UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */ UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
UInt32 tempTarget; UInt32 tempTarget;
unsigned tempPos; unsigned tempPos;
Byte temp[4 * 2]; Byte temp[4 * 2];
unsigned flushPos; unsigned flushPos;
UInt16 probs[2 + 256]; UInt16 probs[2 + 256];
} CBcj2Enc; } CBcj2Enc;
void Bcj2Enc_Init(CBcj2Enc *p); void Bcj2Enc_Init(CBcj2Enc *p);
void Bcj2Enc_Encode(CBcj2Enc *p); void Bcj2Enc_Encode(CBcj2Enc *p);
#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) #define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) #define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
#define BCJ2_RELAT_LIMIT_NUM_BITS 26 #define BCJ2_RELAT_LIMIT_NUM_BITS 26
#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) #define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
/* limit for CBcj2Enc::fileSize variable */ /* limit for CBcj2Enc::fileSize variable */
#define BCJ2_FileSize_MAX ((UInt32)1 << 31) #define BCJ2_FileSize_MAX ((UInt32)1 << 31)
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,311 +1,311 @@
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code) /* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
2019-02-02 : Igor Pavlov : Public domain */ 2019-02-02 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
/* #define SHOW_STAT */ /* #define SHOW_STAT */
#ifdef SHOW_STAT #ifdef SHOW_STAT
#include <stdio.h> #include <stdio.h>
#define PRF(x) x #define PRF(x) x
#else #else
#define PRF(x) #define PRF(x)
#endif #endif
#include <string.h> #include <string.h>
#include "Bcj2.h" #include "Bcj2.h"
#include "CpuArch.h" #include "CpuArch.h"
#define CProb UInt16 #define CProb UInt16
#define kTopValue ((UInt32)1 << 24) #define kTopValue ((UInt32)1 << 24)
#define kNumModelBits 11 #define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits) #define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5 #define kNumMoveBits 5
void Bcj2Enc_Init(CBcj2Enc *p) void Bcj2Enc_Init(CBcj2Enc *p)
{ {
unsigned i; unsigned i;
p->state = BCJ2_ENC_STATE_OK; p->state = BCJ2_ENC_STATE_OK;
p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
p->prevByte = 0; p->prevByte = 0;
p->cache = 0; p->cache = 0;
p->range = 0xFFFFFFFF; p->range = 0xFFFFFFFF;
p->low = 0; p->low = 0;
p->cacheSize = 1; p->cacheSize = 1;
p->ip = 0; p->ip = 0;
p->fileIp = 0; p->fileIp = 0;
p->fileSize = 0; p->fileSize = 0;
p->relatLimit = BCJ2_RELAT_LIMIT; p->relatLimit = BCJ2_RELAT_LIMIT;
p->tempPos = 0; p->tempPos = 0;
p->flushPos = 0; p->flushPos = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1; p->probs[i] = kBitModelTotal >> 1;
} }
static BoolInt MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p) static BoolInt MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p)
{ {
if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0) if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0)
{ {
Byte *buf = p->bufs[BCJ2_STREAM_RC]; Byte *buf = p->bufs[BCJ2_STREAM_RC];
do do
{ {
if (buf == p->lims[BCJ2_STREAM_RC]) if (buf == p->lims[BCJ2_STREAM_RC])
{ {
p->state = BCJ2_STREAM_RC; p->state = BCJ2_STREAM_RC;
p->bufs[BCJ2_STREAM_RC] = buf; p->bufs[BCJ2_STREAM_RC] = buf;
return True; return True;
} }
*buf++ = (Byte)(p->cache + (Byte)(p->low >> 32)); *buf++ = (Byte)(p->cache + (Byte)(p->low >> 32));
p->cache = 0xFF; p->cache = 0xFF;
} }
while (--p->cacheSize); while (--p->cacheSize);
p->bufs[BCJ2_STREAM_RC] = buf; p->bufs[BCJ2_STREAM_RC] = buf;
p->cache = (Byte)((UInt32)p->low >> 24); p->cache = (Byte)((UInt32)p->low >> 24);
} }
p->cacheSize++; p->cacheSize++;
p->low = (UInt32)p->low << 8; p->low = (UInt32)p->low << 8;
return False; return False;
} }
static void Bcj2Enc_Encode_2(CBcj2Enc *p) static void Bcj2Enc_Encode_2(CBcj2Enc *p)
{ {
if (BCJ2_IS_32BIT_STREAM(p->state)) if (BCJ2_IS_32BIT_STREAM(p->state))
{ {
Byte *cur = p->bufs[p->state]; Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state]) if (cur == p->lims[p->state])
return; return;
SetBe32(cur, p->tempTarget); SetBe32(cur, p->tempTarget);
p->bufs[p->state] = cur + 4; p->bufs[p->state] = cur + 4;
} }
p->state = BCJ2_ENC_STATE_ORIG; p->state = BCJ2_ENC_STATE_ORIG;
for (;;) for (;;)
{ {
if (p->range < kTopValue) if (p->range < kTopValue)
{ {
if (RangeEnc_ShiftLow(p)) if (RangeEnc_ShiftLow(p))
return; return;
p->range <<= 8; p->range <<= 8;
} }
{ {
{ {
const Byte *src = p->src; const Byte *src = p->src;
const Byte *srcLim; const Byte *srcLim;
Byte *dest; Byte *dest;
SizeT num = p->srcLim - src; SizeT num = p->srcLim - src;
if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE)
{ {
if (num <= 4) if (num <= 4)
return; return;
num -= 4; num -= 4;
} }
else if (num == 0) else if (num == 0)
break; break;
dest = p->bufs[BCJ2_STREAM_MAIN]; dest = p->bufs[BCJ2_STREAM_MAIN];
if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest)) if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest))
{ {
num = p->lims[BCJ2_STREAM_MAIN] - dest; num = p->lims[BCJ2_STREAM_MAIN] - dest;
if (num == 0) if (num == 0)
{ {
p->state = BCJ2_STREAM_MAIN; p->state = BCJ2_STREAM_MAIN;
return; return;
} }
} }
srcLim = src + num; srcLim = src + num;
if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80) if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0]; *dest = src[0];
else for (;;) else for (;;)
{ {
Byte b = *src; Byte b = *src;
*dest = b; *dest = b;
if (b != 0x0F) if (b != 0x0F)
{ {
if ((b & 0xFE) == 0xE8) if ((b & 0xFE) == 0xE8)
break; break;
dest++; dest++;
if (++src != srcLim) if (++src != srcLim)
continue; continue;
break; break;
} }
dest++; dest++;
if (++src == srcLim) if (++src == srcLim)
break; break;
if ((*src & 0xF0) != 0x80) if ((*src & 0xF0) != 0x80)
continue; continue;
*dest = *src; *dest = *src;
break; break;
} }
num = src - p->src; num = src - p->src;
if (src == srcLim) if (src == srcLim)
{ {
p->prevByte = src[-1]; p->prevByte = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = dest; p->bufs[BCJ2_STREAM_MAIN] = dest;
p->src = src; p->src = src;
p->ip += (UInt32)num; p->ip += (UInt32)num;
continue; continue;
} }
{ {
Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]); Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]);
BoolInt needConvert; BoolInt needConvert;
p->bufs[BCJ2_STREAM_MAIN] = dest + 1; p->bufs[BCJ2_STREAM_MAIN] = dest + 1;
p->ip += (UInt32)num + 1; p->ip += (UInt32)num + 1;
src++; src++;
needConvert = False; needConvert = False;
if ((SizeT)(p->srcLim - src) >= 4) if ((SizeT)(p->srcLim - src) >= 4)
{ {
UInt32 relatVal = GetUi32(src); UInt32 relatVal = GetUi32(src);
if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize) if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize)
&& ((relatVal + p->relatLimit) >> 1) < p->relatLimit) && ((relatVal + p->relatLimit) >> 1) < p->relatLimit)
needConvert = True; needConvert = True;
} }
{ {
UInt32 bound; UInt32 bound;
unsigned ttt; unsigned ttt;
Byte b = src[-1]; Byte b = src[-1];
CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0)); CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0));
ttt = *prob; ttt = *prob;
bound = (p->range >> kNumModelBits) * ttt; bound = (p->range >> kNumModelBits) * ttt;
if (!needConvert) if (!needConvert)
{ {
p->range = bound; p->range = bound;
*prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
p->src = src; p->src = src;
p->prevByte = b; p->prevByte = b;
continue; continue;
} }
p->low += bound; p->low += bound;
p->range -= bound; p->range -= bound;
*prob = (CProb)(ttt - (ttt >> kNumMoveBits)); *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
{ {
UInt32 relatVal = GetUi32(src); UInt32 relatVal = GetUi32(src);
UInt32 absVal; UInt32 absVal;
p->ip += 4; p->ip += 4;
absVal = p->ip + relatVal; absVal = p->ip + relatVal;
p->prevByte = src[3]; p->prevByte = src[3];
src += 4; src += 4;
p->src = src; p->src = src;
{ {
unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
Byte *cur = p->bufs[cj]; Byte *cur = p->bufs[cj];
if (cur == p->lims[cj]) if (cur == p->lims[cj])
{ {
p->state = cj; p->state = cj;
p->tempTarget = absVal; p->tempTarget = absVal;
return; return;
} }
SetBe32(cur, absVal); SetBe32(cur, absVal);
p->bufs[cj] = cur + 4; p->bufs[cj] = cur + 4;
} }
} }
} }
} }
} }
} }
} }
if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM)
return; return;
for (; p->flushPos < 5; p->flushPos++) for (; p->flushPos < 5; p->flushPos++)
if (RangeEnc_ShiftLow(p)) if (RangeEnc_ShiftLow(p))
return; return;
p->state = BCJ2_ENC_STATE_OK; p->state = BCJ2_ENC_STATE_OK;
} }
void Bcj2Enc_Encode(CBcj2Enc *p) void Bcj2Enc_Encode(CBcj2Enc *p)
{ {
PRF(printf("\n")); PRF(printf("\n"));
PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
if (p->tempPos != 0) if (p->tempPos != 0)
{ {
unsigned extra = 0; unsigned extra = 0;
for (;;) for (;;)
{ {
const Byte *src = p->src; const Byte *src = p->src;
const Byte *srcLim = p->srcLim; const Byte *srcLim = p->srcLim;
EBcj2Enc_FinishMode finishMode = p->finishMode; EBcj2Enc_FinishMode finishMode = p->finishMode;
p->src = p->temp; p->src = p->temp;
p->srcLim = p->temp + p->tempPos; p->srcLim = p->temp + p->tempPos;
if (src != srcLim) if (src != srcLim)
p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
Bcj2Enc_Encode_2(p); Bcj2Enc_Encode_2(p);
{ {
unsigned num = (unsigned)(p->src - p->temp); unsigned num = (unsigned)(p->src - p->temp);
unsigned tempPos = p->tempPos - num; unsigned tempPos = p->tempPos - num;
unsigned i; unsigned i;
p->tempPos = tempPos; p->tempPos = tempPos;
for (i = 0; i < tempPos; i++) for (i = 0; i < tempPos; i++)
p->temp[i] = p->temp[(size_t)i + num]; p->temp[i] = p->temp[(size_t)i + num];
p->src = src; p->src = src;
p->srcLim = srcLim; p->srcLim = srcLim;
p->finishMode = finishMode; p->finishMode = finishMode;
if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim) if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim)
return; return;
if (extra >= tempPos) if (extra >= tempPos)
{ {
p->src = src - tempPos; p->src = src - tempPos;
p->tempPos = 0; p->tempPos = 0;
break; break;
} }
p->temp[tempPos] = src[0]; p->temp[tempPos] = src[0];
p->tempPos = tempPos + 1; p->tempPos = tempPos + 1;
p->src = src + 1; p->src = src + 1;
extra++; extra++;
} }
} }
} }
PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src)); PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
Bcj2Enc_Encode_2(p); Bcj2Enc_Encode_2(p);
if (p->state == BCJ2_ENC_STATE_ORIG) if (p->state == BCJ2_ENC_STATE_ORIG)
{ {
const Byte *src = p->src; const Byte *src = p->src;
unsigned rem = (unsigned)(p->srcLim - src); unsigned rem = (unsigned)(p->srcLim - src);
unsigned i; unsigned i;
for (i = 0; i < rem; i++) for (i = 0; i < rem; i++)
p->temp[i] = src[i]; p->temp[i] = src[i];
p->tempPos = rem; p->tempPos = rem;
p->src = src + rem; p->src = src + rem;
} }
} }

View File

@@ -1,48 +1,48 @@
/* Blake2.h -- BLAKE2 Hash /* Blake2.h -- BLAKE2 Hash
2015-06-30 : Igor Pavlov : Public domain 2015-06-30 : Igor Pavlov : Public domain
2015 : Samuel Neves : Public domain */ 2015 : Samuel Neves : Public domain */
#ifndef __BLAKE2_H #ifndef __BLAKE2_H
#define __BLAKE2_H #define __BLAKE2_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define BLAKE2S_BLOCK_SIZE 64 #define BLAKE2S_BLOCK_SIZE 64
#define BLAKE2S_DIGEST_SIZE 32 #define BLAKE2S_DIGEST_SIZE 32
#define BLAKE2SP_PARALLEL_DEGREE 8 #define BLAKE2SP_PARALLEL_DEGREE 8
typedef struct typedef struct
{ {
UInt32 h[8]; UInt32 h[8];
UInt32 t[2]; UInt32 t[2];
UInt32 f[2]; UInt32 f[2];
Byte buf[BLAKE2S_BLOCK_SIZE]; Byte buf[BLAKE2S_BLOCK_SIZE];
UInt32 bufPos; UInt32 bufPos;
UInt32 lastNode_f1; UInt32 lastNode_f1;
UInt32 dummy[2]; /* for sizeof(CBlake2s) alignment */ UInt32 dummy[2]; /* for sizeof(CBlake2s) alignment */
} CBlake2s; } CBlake2s;
/* You need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */ /* You need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
/* /*
void Blake2s_Init0(CBlake2s *p); void Blake2s_Init0(CBlake2s *p);
void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size); void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size);
void Blake2s_Final(CBlake2s *p, Byte *digest); void Blake2s_Final(CBlake2s *p, Byte *digest);
*/ */
typedef struct typedef struct
{ {
CBlake2s S[BLAKE2SP_PARALLEL_DEGREE]; CBlake2s S[BLAKE2SP_PARALLEL_DEGREE];
unsigned bufPos; unsigned bufPos;
} CBlake2sp; } CBlake2sp;
void Blake2sp_Init(CBlake2sp *p); void Blake2sp_Init(CBlake2sp *p);
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size); void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size);
void Blake2sp_Final(CBlake2sp *p, Byte *digest); void Blake2sp_Final(CBlake2sp *p, Byte *digest);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,244 +1,244 @@
/* Blake2s.c -- BLAKE2s and BLAKE2sp Hash /* Blake2s.c -- BLAKE2s and BLAKE2sp Hash
2015-06-30 : Igor Pavlov : Public domain 2015-06-30 : Igor Pavlov : Public domain
2015 : Samuel Neves : Public domain */ 2015 : Samuel Neves : Public domain */
#include <string.h> #include <string.h>
#include "Blake2.h" #include "Blake2.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "RotateDefs.h" #include "RotateDefs.h"
#define rotr32 rotrFixed #define rotr32 rotrFixed
#define BLAKE2S_NUM_ROUNDS 10 #define BLAKE2S_NUM_ROUNDS 10
#define BLAKE2S_FINAL_FLAG (~(UInt32)0) #define BLAKE2S_FINAL_FLAG (~(UInt32)0)
static const UInt32 k_Blake2s_IV[8] = static const UInt32 k_Blake2s_IV[8] =
{ {
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
}; };
static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] = static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] =
{ {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
}; };
void Blake2s_Init0(CBlake2s *p) void Blake2s_Init0(CBlake2s *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
p->h[i] = k_Blake2s_IV[i]; p->h[i] = k_Blake2s_IV[i];
p->t[0] = 0; p->t[0] = 0;
p->t[1] = 0; p->t[1] = 0;
p->f[0] = 0; p->f[0] = 0;
p->f[1] = 0; p->f[1] = 0;
p->bufPos = 0; p->bufPos = 0;
p->lastNode_f1 = 0; p->lastNode_f1 = 0;
} }
static void Blake2s_Compress(CBlake2s *p) static void Blake2s_Compress(CBlake2s *p)
{ {
UInt32 m[16]; UInt32 m[16];
UInt32 v[16]; UInt32 v[16];
{ {
unsigned i; unsigned i;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
m[i] = GetUi32(p->buf + i * sizeof(m[i])); m[i] = GetUi32(p->buf + i * sizeof(m[i]));
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
v[i] = p->h[i]; v[i] = p->h[i];
} }
v[ 8] = k_Blake2s_IV[0]; v[ 8] = k_Blake2s_IV[0];
v[ 9] = k_Blake2s_IV[1]; v[ 9] = k_Blake2s_IV[1];
v[10] = k_Blake2s_IV[2]; v[10] = k_Blake2s_IV[2];
v[11] = k_Blake2s_IV[3]; v[11] = k_Blake2s_IV[3];
v[12] = p->t[0] ^ k_Blake2s_IV[4]; v[12] = p->t[0] ^ k_Blake2s_IV[4];
v[13] = p->t[1] ^ k_Blake2s_IV[5]; v[13] = p->t[1] ^ k_Blake2s_IV[5];
v[14] = p->f[0] ^ k_Blake2s_IV[6]; v[14] = p->f[0] ^ k_Blake2s_IV[6];
v[15] = p->f[1] ^ k_Blake2s_IV[7]; v[15] = p->f[1] ^ k_Blake2s_IV[7];
#define G(r,i,a,b,c,d) \ #define G(r,i,a,b,c,d) \
a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \ a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \
a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \ a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \
#define R(r) \ #define R(r) \
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
G(r,2,v[ 2],v[ 6],v[10],v[14]); \ G(r,2,v[ 2],v[ 6],v[10],v[14]); \
G(r,3,v[ 3],v[ 7],v[11],v[15]); \ G(r,3,v[ 3],v[ 7],v[11],v[15]); \
G(r,4,v[ 0],v[ 5],v[10],v[15]); \ G(r,4,v[ 0],v[ 5],v[10],v[15]); \
G(r,5,v[ 1],v[ 6],v[11],v[12]); \ G(r,5,v[ 1],v[ 6],v[11],v[12]); \
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
{ {
unsigned r; unsigned r;
for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++) for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++)
{ {
const Byte *sigma = k_Blake2s_Sigma[r]; const Byte *sigma = k_Blake2s_Sigma[r];
R(r); R(r);
} }
/* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */ /* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */
} }
#undef G #undef G
#undef R #undef R
{ {
unsigned i; unsigned i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
p->h[i] ^= v[i] ^ v[i + 8]; p->h[i] ^= v[i] ^ v[i + 8];
} }
} }
#define Blake2s_Increment_Counter(S, inc) \ #define Blake2s_Increment_Counter(S, inc) \
{ p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); } { p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); }
#define Blake2s_Set_LastBlock(p) \ #define Blake2s_Set_LastBlock(p) \
{ p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; } { p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; }
static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size) static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size)
{ {
while (size != 0) while (size != 0)
{ {
unsigned pos = (unsigned)p->bufPos; unsigned pos = (unsigned)p->bufPos;
unsigned rem = BLAKE2S_BLOCK_SIZE - pos; unsigned rem = BLAKE2S_BLOCK_SIZE - pos;
if (size <= rem) if (size <= rem)
{ {
memcpy(p->buf + pos, data, size); memcpy(p->buf + pos, data, size);
p->bufPos += (UInt32)size; p->bufPos += (UInt32)size;
return; return;
} }
memcpy(p->buf + pos, data, rem); memcpy(p->buf + pos, data, rem);
Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE); Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE);
Blake2s_Compress(p); Blake2s_Compress(p);
p->bufPos = 0; p->bufPos = 0;
data += rem; data += rem;
size -= rem; size -= rem;
} }
} }
static void Blake2s_Final(CBlake2s *p, Byte *digest) static void Blake2s_Final(CBlake2s *p, Byte *digest)
{ {
unsigned i; unsigned i;
Blake2s_Increment_Counter(S, (UInt32)p->bufPos); Blake2s_Increment_Counter(S, (UInt32)p->bufPos);
Blake2s_Set_LastBlock(p); Blake2s_Set_LastBlock(p);
memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos); memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos);
Blake2s_Compress(p); Blake2s_Compress(p);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]); SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]);
} }
/* ---------- BLAKE2s ---------- */ /* ---------- BLAKE2s ---------- */
/* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */ /* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
/* /*
typedef struct typedef struct
{ {
Byte digest_length; Byte digest_length;
Byte key_length; Byte key_length;
Byte fanout; Byte fanout;
Byte depth; Byte depth;
UInt32 leaf_length; UInt32 leaf_length;
Byte node_offset[6]; Byte node_offset[6];
Byte node_depth; Byte node_depth;
Byte inner_length; Byte inner_length;
Byte salt[BLAKE2S_SALTBYTES]; Byte salt[BLAKE2S_SALTBYTES];
Byte personal[BLAKE2S_PERSONALBYTES]; Byte personal[BLAKE2S_PERSONALBYTES];
} CBlake2sParam; } CBlake2sParam;
*/ */
static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth) static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth)
{ {
Blake2s_Init0(p); Blake2s_Init0(p);
p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24)); p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24));
p->h[2] ^= ((UInt32)node_offset); p->h[2] ^= ((UInt32)node_offset);
p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24); p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24);
/* /*
P->digest_length = BLAKE2S_DIGEST_SIZE; P->digest_length = BLAKE2S_DIGEST_SIZE;
P->key_length = 0; P->key_length = 0;
P->fanout = BLAKE2SP_PARALLEL_DEGREE; P->fanout = BLAKE2SP_PARALLEL_DEGREE;
P->depth = 2; P->depth = 2;
P->leaf_length = 0; P->leaf_length = 0;
store48(P->node_offset, node_offset); store48(P->node_offset, node_offset);
P->node_depth = node_depth; P->node_depth = node_depth;
P->inner_length = BLAKE2S_DIGEST_SIZE; P->inner_length = BLAKE2S_DIGEST_SIZE;
*/ */
} }
void Blake2sp_Init(CBlake2sp *p) void Blake2sp_Init(CBlake2sp *p)
{ {
unsigned i; unsigned i;
p->bufPos = 0; p->bufPos = 0;
for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++) for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
Blake2sp_Init_Spec(&p->S[i], i, 0); Blake2sp_Init_Spec(&p->S[i], i, 0);
p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG; p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG;
} }
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size) void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size)
{ {
unsigned pos = p->bufPos; unsigned pos = p->bufPos;
while (size != 0) while (size != 0)
{ {
unsigned index = pos / BLAKE2S_BLOCK_SIZE; unsigned index = pos / BLAKE2S_BLOCK_SIZE;
unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1)); unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1));
if (rem > size) if (rem > size)
rem = (unsigned)size; rem = (unsigned)size;
Blake2s_Update(&p->S[index], data, rem); Blake2s_Update(&p->S[index], data, rem);
size -= rem; size -= rem;
data += rem; data += rem;
pos += rem; pos += rem;
pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1); pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1);
} }
p->bufPos = pos; p->bufPos = pos;
} }
void Blake2sp_Final(CBlake2sp *p, Byte *digest) void Blake2sp_Final(CBlake2sp *p, Byte *digest)
{ {
CBlake2s R; CBlake2s R;
unsigned i; unsigned i;
Blake2sp_Init_Spec(&R, 0, 1); Blake2sp_Init_Spec(&R, 0, 1);
R.lastNode_f1 = BLAKE2S_FINAL_FLAG; R.lastNode_f1 = BLAKE2S_FINAL_FLAG;
for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++) for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
{ {
Byte hash[BLAKE2S_DIGEST_SIZE]; Byte hash[BLAKE2S_DIGEST_SIZE];
Blake2s_Final(&p->S[i], hash); Blake2s_Final(&p->S[i], hash);
Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE); Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE);
} }
Blake2s_Final(&R, digest); Blake2s_Final(&R, digest);
} }

460
C/Bra.c
View File

@@ -1,230 +1,230 @@
/* Bra.c -- Converters for RISC code /* Bra.c -- Converters for RISC code
2017-04-04 : Igor Pavlov : Public domain */ 2017-04-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "Bra.h" #include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
Byte *p; Byte *p;
const Byte *lim; const Byte *lim;
size &= ~(size_t)3; size &= ~(size_t)3;
ip += 4; ip += 4;
p = data; p = data;
lim = data + size; lim = data + size;
if (encoding) if (encoding)
for (;;) for (;;)
{ {
for (;;) for (;;)
{ {
if (p >= lim) if (p >= lim)
return p - data; return p - data;
p += 4; p += 4;
if (p[-1] == 0xEB) if (p[-1] == 0xEB)
break; break;
} }
{ {
UInt32 v = GetUi32(p - 4); UInt32 v = GetUi32(p - 4);
v <<= 2; v <<= 2;
v += ip + (UInt32)(p - data); v += ip + (UInt32)(p - data);
v >>= 2; v >>= 2;
v &= 0x00FFFFFF; v &= 0x00FFFFFF;
v |= 0xEB000000; v |= 0xEB000000;
SetUi32(p - 4, v); SetUi32(p - 4, v);
} }
} }
for (;;) for (;;)
{ {
for (;;) for (;;)
{ {
if (p >= lim) if (p >= lim)
return p - data; return p - data;
p += 4; p += 4;
if (p[-1] == 0xEB) if (p[-1] == 0xEB)
break; break;
} }
{ {
UInt32 v = GetUi32(p - 4); UInt32 v = GetUi32(p - 4);
v <<= 2; v <<= 2;
v -= ip + (UInt32)(p - data); v -= ip + (UInt32)(p - data);
v >>= 2; v >>= 2;
v &= 0x00FFFFFF; v &= 0x00FFFFFF;
v |= 0xEB000000; v |= 0xEB000000;
SetUi32(p - 4, v); SetUi32(p - 4, v);
} }
} }
} }
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
Byte *p; Byte *p;
const Byte *lim; const Byte *lim;
size &= ~(size_t)1; size &= ~(size_t)1;
p = data; p = data;
lim = data + size - 4; lim = data + size - 4;
if (encoding) if (encoding)
for (;;) for (;;)
{ {
UInt32 b1; UInt32 b1;
for (;;) for (;;)
{ {
UInt32 b3; UInt32 b3;
if (p > lim) if (p > lim)
return p - data; return p - data;
b1 = p[1]; b1 = p[1];
b3 = p[3]; b3 = p[3];
p += 2; p += 2;
b1 ^= 8; b1 ^= 8;
if ((b3 & b1) >= 0xF8) if ((b3 & b1) >= 0xF8)
break; break;
} }
{ {
UInt32 v = UInt32 v =
((UInt32)b1 << 19) ((UInt32)b1 << 19)
+ (((UInt32)p[1] & 0x7) << 8) + (((UInt32)p[1] & 0x7) << 8)
+ (((UInt32)p[-2] << 11)) + (((UInt32)p[-2] << 11))
+ (p[0]); + (p[0]);
p += 2; p += 2;
{ {
UInt32 cur = (ip + (UInt32)(p - data)) >> 1; UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
v += cur; v += cur;
} }
p[-4] = (Byte)(v >> 11); p[-4] = (Byte)(v >> 11);
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
p[-2] = (Byte)v; p[-2] = (Byte)v;
p[-1] = (Byte)(0xF8 | (v >> 8)); p[-1] = (Byte)(0xF8 | (v >> 8));
} }
} }
for (;;) for (;;)
{ {
UInt32 b1; UInt32 b1;
for (;;) for (;;)
{ {
UInt32 b3; UInt32 b3;
if (p > lim) if (p > lim)
return p - data; return p - data;
b1 = p[1]; b1 = p[1];
b3 = p[3]; b3 = p[3];
p += 2; p += 2;
b1 ^= 8; b1 ^= 8;
if ((b3 & b1) >= 0xF8) if ((b3 & b1) >= 0xF8)
break; break;
} }
{ {
UInt32 v = UInt32 v =
((UInt32)b1 << 19) ((UInt32)b1 << 19)
+ (((UInt32)p[1] & 0x7) << 8) + (((UInt32)p[1] & 0x7) << 8)
+ (((UInt32)p[-2] << 11)) + (((UInt32)p[-2] << 11))
+ (p[0]); + (p[0]);
p += 2; p += 2;
{ {
UInt32 cur = (ip + (UInt32)(p - data)) >> 1; UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
v -= cur; v -= cur;
} }
/* /*
SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
SetUi16(p - 2, (UInt16)(v | 0xF800)); SetUi16(p - 2, (UInt16)(v | 0xF800));
*/ */
p[-4] = (Byte)(v >> 11); p[-4] = (Byte)(v >> 11);
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
p[-2] = (Byte)v; p[-2] = (Byte)v;
p[-1] = (Byte)(0xF8 | (v >> 8)); p[-1] = (Byte)(0xF8 | (v >> 8));
} }
} }
} }
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
Byte *p; Byte *p;
const Byte *lim; const Byte *lim;
size &= ~(size_t)3; size &= ~(size_t)3;
ip -= 4; ip -= 4;
p = data; p = data;
lim = data + size; lim = data + size;
for (;;) for (;;)
{ {
for (;;) for (;;)
{ {
if (p >= lim) if (p >= lim)
return p - data; return p - data;
p += 4; p += 4;
/* if ((v & 0xFC000003) == 0x48000001) */ /* if ((v & 0xFC000003) == 0x48000001) */
if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
break; break;
} }
{ {
UInt32 v = GetBe32(p - 4); UInt32 v = GetBe32(p - 4);
if (encoding) if (encoding)
v += ip + (UInt32)(p - data); v += ip + (UInt32)(p - data);
else else
v -= ip + (UInt32)(p - data); v -= ip + (UInt32)(p - data);
v &= 0x03FFFFFF; v &= 0x03FFFFFF;
v |= 0x48000000; v |= 0x48000000;
SetBe32(p - 4, v); SetBe32(p - 4, v);
} }
} }
} }
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
Byte *p; Byte *p;
const Byte *lim; const Byte *lim;
size &= ~(size_t)3; size &= ~(size_t)3;
ip -= 4; ip -= 4;
p = data; p = data;
lim = data + size; lim = data + size;
for (;;) for (;;)
{ {
for (;;) for (;;)
{ {
if (p >= lim) if (p >= lim)
return p - data; return p - data;
/* /*
v = GetBe32(p); v = GetBe32(p);
p += 4; p += 4;
m = v + ((UInt32)5 << 29); m = v + ((UInt32)5 << 29);
m ^= (UInt32)7 << 29; m ^= (UInt32)7 << 29;
m += (UInt32)1 << 22; m += (UInt32)1 << 22;
if ((m & ((UInt32)0x1FF << 23)) == 0) if ((m & ((UInt32)0x1FF << 23)) == 0)
break; break;
*/ */
p += 4; p += 4;
if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
(p[-4] == 0x7F && (p[-3] >= 0xC0))) (p[-4] == 0x7F && (p[-3] >= 0xC0)))
break; break;
} }
{ {
UInt32 v = GetBe32(p - 4); UInt32 v = GetBe32(p - 4);
v <<= 2; v <<= 2;
if (encoding) if (encoding)
v += ip + (UInt32)(p - data); v += ip + (UInt32)(p - data);
else else
v -= ip + (UInt32)(p - data); v -= ip + (UInt32)(p - data);
v &= 0x01FFFFFF; v &= 0x01FFFFFF;
v -= (UInt32)1 << 24; v -= (UInt32)1 << 24;
v ^= 0xFF000000; v ^= 0xFF000000;
v >>= 2; v >>= 2;
v |= 0x40000000; v |= 0x40000000;
SetBe32(p - 4, v); SetBe32(p - 4, v);
} }
} }
} }

128
C/Bra.h
View File

@@ -1,64 +1,64 @@
/* Bra.h -- Branch converters for executables /* Bra.h -- Branch converters for executables
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BRA_H #ifndef __BRA_H
#define __BRA_H #define __BRA_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* /*
These functions convert relative addresses to absolute addresses These functions convert relative addresses to absolute addresses
in CALL instructions to increase the compression ratio. in CALL instructions to increase the compression ratio.
In: In:
data - data buffer data - data buffer
size - size of data size - size of data
ip - current virtual Instruction Pinter (IP) value ip - current virtual Instruction Pinter (IP) value
state - state variable for x86 converter state - state variable for x86 converter
encoding - 0 (for decoding), 1 (for encoding) encoding - 0 (for decoding), 1 (for encoding)
Out: Out:
state - state variable for x86 converter state - state variable for x86 converter
Returns: Returns:
The number of processed bytes. If you call these functions with multiple calls, The number of processed bytes. If you call these functions with multiple calls,
you must start next call with first byte after block of processed bytes. you must start next call with first byte after block of processed bytes.
Type Endian Alignment LookAhead Type Endian Alignment LookAhead
x86 little 1 4 x86 little 1 4
ARMT little 2 2 ARMT little 2 2
ARM little 4 0 ARM little 4 0
PPC big 4 0 PPC big 4 0
SPARC big 4 0 SPARC big 4 0
IA64 little 16 0 IA64 little 16 0
size must be >= Alignment + LookAhead, if it's not last block. size must be >= Alignment + LookAhead, if it's not last block.
If (size < Alignment + LookAhead), converter returns 0. If (size < Alignment + LookAhead), converter returns 0.
Example: Example:
UInt32 ip = 0; UInt32 ip = 0;
for () for ()
{ {
; size must be >= Alignment + LookAhead, if it's not last block ; size must be >= Alignment + LookAhead, if it's not last block
SizeT processed = Convert(data, size, ip, 1); SizeT processed = Convert(data, size, ip, 1);
data += processed; data += processed;
size -= processed; size -= processed;
ip += processed; ip += processed;
} }
*/ */
#define x86_Convert_Init(state) { state = 0; } #define x86_Convert_Init(state) { state = 0; }
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
EXTERN_C_END EXTERN_C_END
#endif #endif

164
C/Bra86.c
View File

@@ -1,82 +1,82 @@
/* Bra86.c -- Converter for x86 code (BCJ) /* Bra86.c -- Converter for x86 code (BCJ)
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Bra.h" #include "Bra.h"
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
{ {
SizeT pos = 0; SizeT pos = 0;
UInt32 mask = *state & 7; UInt32 mask = *state & 7;
if (size < 5) if (size < 5)
return 0; return 0;
size -= 4; size -= 4;
ip += 5; ip += 5;
for (;;) for (;;)
{ {
Byte *p = data + pos; Byte *p = data + pos;
const Byte *limit = data + size; const Byte *limit = data + size;
for (; p < limit; p++) for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8) if ((*p & 0xFE) == 0xE8)
break; break;
{ {
SizeT d = (SizeT)(p - data - pos); SizeT d = (SizeT)(p - data - pos);
pos = (SizeT)(p - data); pos = (SizeT)(p - data);
if (p >= limit) if (p >= limit)
{ {
*state = (d > 2 ? 0 : mask >> (unsigned)d); *state = (d > 2 ? 0 : mask >> (unsigned)d);
return pos; return pos;
} }
if (d > 2) if (d > 2)
mask = 0; mask = 0;
else else
{ {
mask >>= (unsigned)d; mask >>= (unsigned)d;
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
{ {
mask = (mask >> 1) | 4; mask = (mask >> 1) | 4;
pos++; pos++;
continue; continue;
} }
} }
} }
if (Test86MSByte(p[4])) if (Test86MSByte(p[4]))
{ {
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 cur = ip + (UInt32)pos; UInt32 cur = ip + (UInt32)pos;
pos += 5; pos += 5;
if (encoding) if (encoding)
v += cur; v += cur;
else else
v -= cur; v -= cur;
if (mask != 0) if (mask != 0)
{ {
unsigned sh = (mask & 6) << 2; unsigned sh = (mask & 6) << 2;
if (Test86MSByte((Byte)(v >> sh))) if (Test86MSByte((Byte)(v >> sh)))
{ {
v ^= (((UInt32)0x100 << sh) - 1); v ^= (((UInt32)0x100 << sh) - 1);
if (encoding) if (encoding)
v += cur; v += cur;
else else
v -= cur; v -= cur;
} }
mask = 0; mask = 0;
} }
p[1] = (Byte)v; p[1] = (Byte)v;
p[2] = (Byte)(v >> 8); p[2] = (Byte)(v >> 8);
p[3] = (Byte)(v >> 16); p[3] = (Byte)(v >> 16);
p[4] = (Byte)(0 - ((v >> 24) & 1)); p[4] = (Byte)(0 - ((v >> 24) & 1));
} }
else else
{ {
mask = (mask >> 1) | 4; mask = (mask >> 1) | 4;
pos++; pos++;
} }
} }
} }

View File

@@ -1,53 +1,53 @@
/* BraIA64.c -- Converter for IA-64 code /* BraIA64.c -- Converter for IA-64 code
2017-01-26 : Igor Pavlov : Public domain */ 2017-01-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "Bra.h" #include "Bra.h"
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; SizeT i;
if (size < 16) if (size < 16)
return 0; return 0;
size -= 16; size -= 16;
i = 0; i = 0;
do do
{ {
unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3; unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
if (m) if (m)
{ {
m++; m++;
do do
{ {
Byte *p = data + (i + (size_t)m * 5 - 8); Byte *p = data + (i + (size_t)m * 5 - 8);
if (((p[3] >> m) & 15) == 5 if (((p[3] >> m) & 15) == 5
&& (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0) && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
{ {
unsigned raw = GetUi32(p); unsigned raw = GetUi32(p);
unsigned v = raw >> m; unsigned v = raw >> m;
v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3); v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
v <<= 4; v <<= 4;
if (encoding) if (encoding)
v += ip + (UInt32)i; v += ip + (UInt32)i;
else else
v -= ip + (UInt32)i; v -= ip + (UInt32)i;
v >>= 4; v >>= 4;
v &= 0x1FFFFF; v &= 0x1FFFFF;
v += 0x700000; v += 0x700000;
v &= 0x8FFFFF; v &= 0x8FFFFF;
raw &= ~((UInt32)0x8FFFFF << m); raw &= ~((UInt32)0x8FFFFF << m);
raw |= (v << m); raw |= (v << m);
SetUi32(p, raw); SetUi32(p, raw);
} }
} }
while (++m <= 4); while (++m <= 4);
} }
i += 16; i += 16;
} }
while (i <= size); while (i <= size);
return i; return i;
} }

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,26 @@
/* BwtSort.h -- BWT block sorting /* BwtSort.h -- BWT block sorting
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BWT_SORT_H #ifndef __BWT_SORT_H
#define __BWT_SORT_H #define __BWT_SORT_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ /* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */
/* #define BLOCK_SORT_EXTERNAL_FLAGS */ /* #define BLOCK_SORT_EXTERNAL_FLAGS */
#ifdef BLOCK_SORT_EXTERNAL_FLAGS #ifdef BLOCK_SORT_EXTERNAL_FLAGS
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5)) #define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5))
#else #else
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0 #define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0
#endif #endif
#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16)) #define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16))
UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,33 +1,33 @@
/* Compiler.h /* Compiler.h
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H #ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H #define __7Z_COMPILER_H
#ifdef _MSC_VER #ifdef _MSC_VER
#ifdef UNDER_CE #ifdef UNDER_CE
#define RPC_NO_WINDOWS_H #define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
#endif #endif
#if _MSC_VER >= 1300 #if _MSC_VER >= 1300
#pragma warning(disable : 4996) // This function or variable may be unsafe #pragma warning(disable : 4996) // This function or variable may be unsafe
#else #else
#pragma warning(disable : 4511) // copy constructor could not be generated #pragma warning(disable : 4511) // copy constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated #pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4514) // unreferenced inline function has been removed #pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined #pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4714) // function marked as __forceinline not inlined #pragma warning(disable : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif #endif
#endif #endif
#define UNUSED_VAR(x) (void)x; #define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */ /* #define UNUSED_VAR(x) x=x; */
#endif #endif

View File

@@ -1,218 +1,218 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2018-02-18: Igor Pavlov : Public domain */ 2018-02-18: Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
#define USE_ASM #define USE_ASM
#endif #endif
#if !defined(USE_ASM) && _MSC_VER >= 1500 #if !defined(USE_ASM) && _MSC_VER >= 1500
#include <intrin.h> #include <intrin.h>
#endif #endif
#if defined(USE_ASM) && !defined(MY_CPU_AMD64) #if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag) static UInt32 CheckFlag(UInt32 flag)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
__asm pushfd; __asm pushfd;
__asm pop EAX; __asm pop EAX;
__asm mov EDX, EAX; __asm mov EDX, EAX;
__asm xor EAX, flag; __asm xor EAX, flag;
__asm push EAX; __asm push EAX;
__asm popfd; __asm popfd;
__asm pushfd; __asm pushfd;
__asm pop EAX; __asm pop EAX;
__asm xor EAX, EDX; __asm xor EAX, EDX;
__asm push EDX; __asm push EDX;
__asm popfd; __asm popfd;
__asm and flag, EAX; __asm and flag, EAX;
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
"pushf\n\t" "pushf\n\t"
"pop %%EAX\n\t" "pop %%EAX\n\t"
"movl %%EAX,%%EDX\n\t" "movl %%EAX,%%EDX\n\t"
"xorl %0,%%EAX\n\t" "xorl %0,%%EAX\n\t"
"push %%EAX\n\t" "push %%EAX\n\t"
"popf\n\t" "popf\n\t"
"pushf\n\t" "pushf\n\t"
"pop %%EAX\n\t" "pop %%EAX\n\t"
"xorl %%EDX,%%EAX\n\t" "xorl %%EDX,%%EAX\n\t"
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t": "andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag) : "=c" (flag) : "c" (flag) :
"%eax", "%edx"); "%eax", "%edx");
#endif #endif
return flag; return flag;
} }
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; #define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
#else #else
#define CHECK_CPUID_IS_SUPPORTED #define CHECK_CPUID_IS_SUPPORTED
#endif #endif
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{ {
#ifdef USE_ASM #ifdef USE_ASM
#ifdef _MSC_VER #ifdef _MSC_VER
UInt32 a2, b2, c2, d2; UInt32 a2, b2, c2, d2;
__asm xor EBX, EBX; __asm xor EBX, EBX;
__asm xor ECX, ECX; __asm xor ECX, ECX;
__asm xor EDX, EDX; __asm xor EDX, EDX;
__asm mov EAX, function; __asm mov EAX, function;
__asm cpuid; __asm cpuid;
__asm mov a2, EAX; __asm mov a2, EAX;
__asm mov b2, EBX; __asm mov b2, EBX;
__asm mov c2, ECX; __asm mov c2, ECX;
__asm mov d2, EDX; __asm mov d2, EDX;
*a = a2; *a = a2;
*b = b2; *b = b2;
*c = c2; *c = c2;
*d = d2; *d = d2;
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
#if defined(MY_CPU_AMD64) && defined(__PIC__) #if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;" "mov %%rbx, %%rdi;"
"cpuid;" "cpuid;"
"xchg %%rbx, %%rdi;" "xchg %%rbx, %%rdi;"
: "=a" (*a) , : "=a" (*a) ,
"=D" (*b) , "=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__) #elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;" "mov %%ebx, %%edi;"
"cpuid;" "cpuid;"
"xchgl %%ebx, %%edi;" "xchgl %%ebx, %%edi;"
: "=a" (*a) , : "=a" (*a) ,
"=D" (*b) , "=D" (*b) ,
#else #else
"cpuid" "cpuid"
: "=a" (*a) , : "=a" (*a) ,
"=b" (*b) , "=b" (*b) ,
#endif #endif
"=c" (*c) , "=c" (*c) ,
"=d" (*d) "=d" (*d)
: "0" (function)) ; : "0" (function)) ;
#endif #endif
#else #else
int CPUInfo[4]; int CPUInfo[4];
__cpuid(CPUInfo, function); __cpuid(CPUInfo, function);
*a = CPUInfo[0]; *a = CPUInfo[0];
*b = CPUInfo[1]; *b = CPUInfo[1];
*c = CPUInfo[2]; *c = CPUInfo[2];
*d = CPUInfo[3]; *d = CPUInfo[3];
#endif #endif
} }
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p) BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
{ {
CHECK_CPUID_IS_SUPPORTED CHECK_CPUID_IS_SUPPORTED
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
return True; return True;
} }
static const UInt32 kVendors[][3] = static const UInt32 kVendors[][3] =
{ {
{ 0x756E6547, 0x49656E69, 0x6C65746E}, { 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163}, { 0x68747541, 0x69746E65, 0x444D4163},
{ 0x746E6543, 0x48727561, 0x736C7561} { 0x746E6543, 0x48727561, 0x736C7561}
}; };
int x86cpuid_GetFirm(const Cx86cpuid *p) int x86cpuid_GetFirm(const Cx86cpuid *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
{ {
const UInt32 *v = kVendors[i]; const UInt32 *v = kVendors[i];
if (v[0] == p->vendor[0] && if (v[0] == p->vendor[0] &&
v[1] == p->vendor[1] && v[1] == p->vendor[1] &&
v[2] == p->vendor[2]) v[2] == p->vendor[2])
return (int)i; return (int)i;
} }
return -1; return -1;
} }
BoolInt CPU_Is_InOrder() BoolInt CPU_Is_InOrder()
{ {
Cx86cpuid p; Cx86cpuid p;
int firm; int firm;
UInt32 family, model; UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p)) if (!x86cpuid_CheckAndRead(&p))
return True; return True;
family = x86cpuid_GetFamily(p.ver); family = x86cpuid_GetFamily(p.ver);
model = x86cpuid_GetModel(p.ver); model = x86cpuid_GetModel(p.ver);
firm = x86cpuid_GetFirm(&p); firm = x86cpuid_GetFirm(&p);
switch (firm) switch (firm)
{ {
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* In-Order Atom CPU */ /* In-Order Atom CPU */
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x26 /* 45 nm, Z6xx */ || model == 0x26 /* 45 nm, Z6xx */
|| model == 0x27 /* 32 nm, Z2460 */ || model == 0x27 /* 32 nm, Z2460 */
|| model == 0x35 /* 32 nm, Z2760 */ || model == 0x35 /* 32 nm, Z2760 */
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */ || model == 0x36 /* 32 nm, N2xxx, D2xxx */
))); )));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
} }
return True; return True;
} }
#if !defined(MY_CPU_AMD64) && defined(_WIN32) #if !defined(MY_CPU_AMD64) && defined(_WIN32)
#include <windows.h> #include <windows.h>
static BoolInt CPU_Sys_Is_SSE_Supported() static BoolInt CPU_Sys_Is_SSE_Supported()
{ {
OSVERSIONINFO vi; OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi); vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionEx(&vi)) if (!GetVersionEx(&vi))
return False; return False;
return (vi.dwMajorVersion >= 5); return (vi.dwMajorVersion >= 5);
} }
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
#else #else
#define CHECK_SYS_SSE_SUPPORT #define CHECK_SYS_SSE_SUPPORT
#endif #endif
BoolInt CPU_Is_Aes_Supported() BoolInt CPU_Is_Aes_Supported()
{ {
Cx86cpuid p; Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT CHECK_SYS_SSE_SUPPORT
if (!x86cpuid_CheckAndRead(&p)) if (!x86cpuid_CheckAndRead(&p))
return False; return False;
return (p.c >> 25) & 1; return (p.c >> 25) & 1;
} }
BoolInt CPU_IsSupported_PageGB() BoolInt CPU_IsSupported_PageGB()
{ {
Cx86cpuid cpuid; Cx86cpuid cpuid;
if (!x86cpuid_CheckAndRead(&cpuid)) if (!x86cpuid_CheckAndRead(&cpuid))
return False; return False;
{ {
UInt32 d[4] = { 0 }; UInt32 d[4] = { 0 };
MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]); MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
if (d[0] < 0x80000001) if (d[0] < 0x80000001)
return False; return False;
} }
{ {
UInt32 d[4] = { 0 }; UInt32 d[4] = { 0 };
MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]); MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
return (d[3] >> 26) & 1; return (d[3] >> 26) & 1;
} }
} }
#endif #endif

View File

@@ -1,336 +1,336 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2018-02-18 : Igor Pavlov : Public domain */ 2018-02-18 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* /*
MY_CPU_LE means that CPU is LITTLE ENDIAN. MY_CPU_LE means that CPU is LITTLE ENDIAN.
MY_CPU_BE means that CPU is BIG ENDIAN. MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform. If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
*/ */
#if defined(_M_X64) \ #if defined(_M_X64) \
|| defined(_M_AMD64) \ || defined(_M_AMD64) \
|| defined(__x86_64__) \ || defined(__x86_64__) \
|| defined(__AMD64__) \ || defined(__AMD64__) \
|| defined(__amd64__) || defined(__amd64__)
#define MY_CPU_AMD64 #define MY_CPU_AMD64
#ifdef __ILP32__ #ifdef __ILP32__
#define MY_CPU_NAME "x32" #define MY_CPU_NAME "x32"
#else #else
#define MY_CPU_NAME "x64" #define MY_CPU_NAME "x64"
#endif #endif
#define MY_CPU_64BIT #define MY_CPU_64BIT
#endif #endif
#if defined(_M_IX86) \ #if defined(_M_IX86) \
|| defined(__i386__) || defined(__i386__)
#define MY_CPU_X86 #define MY_CPU_X86
#define MY_CPU_NAME "x86" #define MY_CPU_NAME "x86"
#define MY_CPU_32BIT #define MY_CPU_32BIT
#endif #endif
#if defined(_M_ARM64) \ #if defined(_M_ARM64) \
|| defined(__AARCH64EL__) \ || defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \ || defined(__AARCH64EB__) \
|| defined(__aarch64__) || defined(__aarch64__)
#define MY_CPU_ARM64 #define MY_CPU_ARM64
#define MY_CPU_NAME "arm64" #define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT #define MY_CPU_64BIT
#endif #endif
#if defined(_M_ARM) \ #if defined(_M_ARM) \
|| defined(_M_ARM_NT) \ || defined(_M_ARM_NT) \
|| defined(_M_ARMT) \ || defined(_M_ARMT) \
|| defined(__arm__) \ || defined(__arm__) \
|| defined(__thumb__) \ || defined(__thumb__) \
|| defined(__ARMEL__) \ || defined(__ARMEL__) \
|| defined(__ARMEB__) \ || defined(__ARMEB__) \
|| defined(__THUMBEL__) \ || defined(__THUMBEL__) \
|| defined(__THUMBEB__) || defined(__THUMBEB__)
#define MY_CPU_ARM #define MY_CPU_ARM
#define MY_CPU_NAME "arm" #define MY_CPU_NAME "arm"
#define MY_CPU_32BIT #define MY_CPU_32BIT
#endif #endif
#if defined(_M_IA64) \ #if defined(_M_IA64) \
|| defined(__ia64__) || defined(__ia64__)
#define MY_CPU_IA64 #define MY_CPU_IA64
#define MY_CPU_NAME "ia64" #define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT #define MY_CPU_64BIT
#endif #endif
#if defined(__mips64) \ #if defined(__mips64) \
|| defined(__mips64__) \ || defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3)) || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64" #define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT #define MY_CPU_64BIT
#elif defined(__mips__) #elif defined(__mips__)
#define MY_CPU_NAME "mips" #define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */ /* #define MY_CPU_32BIT */
#endif #endif
#if defined(__ppc64__) \ #if defined(__ppc64__) \
|| defined(__powerpc64__) || defined(__powerpc64__)
#ifdef __ILP32__ #ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32" #define MY_CPU_NAME "ppc64-32"
#else #else
#define MY_CPU_NAME "ppc64" #define MY_CPU_NAME "ppc64"
#endif #endif
#define MY_CPU_64BIT #define MY_CPU_64BIT
#elif defined(__ppc__) \ #elif defined(__ppc__) \
|| defined(__powerpc__) || defined(__powerpc__)
#define MY_CPU_NAME "ppc" #define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT #define MY_CPU_32BIT
#endif #endif
#if defined(__sparc64__) #if defined(__sparc64__)
#define MY_CPU_NAME "sparc64" #define MY_CPU_NAME "sparc64"
#define MY_CPU_64BIT #define MY_CPU_64BIT
#elif defined(__sparc__) #elif defined(__sparc__)
#define MY_CPU_NAME "sparc" #define MY_CPU_NAME "sparc"
/* #define MY_CPU_32BIT */ /* #define MY_CPU_32BIT */
#endif #endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64 #define MY_CPU_X86_OR_AMD64
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#ifdef MY_CPU_ARM #ifdef MY_CPU_ARM
#define MY_CPU_ARM_LE #define MY_CPU_ARM_LE
#endif #endif
#ifdef MY_CPU_ARM64 #ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE #define MY_CPU_ARM64_LE
#endif #endif
#ifdef _M_IA64 #ifdef _M_IA64
#define MY_CPU_IA64_LE #define MY_CPU_IA64_LE
#endif #endif
#endif #endif
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \ || defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \ || defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \ || defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \ || defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \ || defined(__ARMEL__) \
|| defined(__THUMBEL__) \ || defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \ || defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \ || defined(__MIPSEL__) \
|| defined(__MIPSEL) \ || defined(__MIPSEL) \
|| defined(_MIPSEL) \ || defined(_MIPSEL) \
|| defined(__BFIN__) \ || defined(__BFIN__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE #define MY_CPU_LE
#endif #endif
#if defined(__BIG_ENDIAN__) \ #if defined(__BIG_ENDIAN__) \
|| defined(__ARMEB__) \ || defined(__ARMEB__) \
|| defined(__THUMBEB__) \ || defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \ || defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \ || defined(__MIPSEB__) \
|| defined(__MIPSEB) \ || defined(__MIPSEB) \
|| defined(_MIPSEB) \ || defined(_MIPSEB) \
|| defined(__m68k__) \ || defined(__m68k__) \
|| defined(__s390__) \ || defined(__s390__) \
|| defined(__s390x__) \ || defined(__s390x__) \
|| defined(__zarch__) \ || defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE) #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
#error Stop_Compiling_Bad_Endian #error Stop_Compiling_Bad_Endian
#endif #endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) #if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT #error Stop_Compiling_Bad_32_64_BIT
#endif #endif
#ifndef MY_CPU_NAME #ifndef MY_CPU_NAME
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
#define MY_CPU_NAME "LE" #define MY_CPU_NAME "LE"
#elif defined(MY_CPU_BE) #elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE" #define MY_CPU_NAME "BE"
#else #else
/* /*
#define MY_CPU_NAME "" #define MY_CPU_NAME ""
*/ */
#endif #endif
#endif #endif
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM64) \ || defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED) || defined(__ARM_FEATURE_UNALIGNED)
#define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN
#endif #endif
#endif #endif
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) #define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) #define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) #define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, v) { *(UInt16 *)(p) = (v); } #define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
#define SetUi32(p, v) { *(UInt32 *)(p) = (v); } #define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); } #define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#else #else
#define GetUi16(p) ( (UInt16) ( \ #define GetUi16(p) ( (UInt16) ( \
((const Byte *)(p))[0] | \ ((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8) )) ((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \ #define GetUi32(p) ( \
((const Byte *)(p))[0] | \ ((const Byte *)(p))[0] | \
((UInt32)((const Byte *)(p))[1] << 8) | \ ((UInt32)((const Byte *)(p))[1] << 8) | \
((UInt32)((const Byte *)(p))[2] << 16) | \ ((UInt32)((const Byte *)(p))[2] << 16) | \
((UInt32)((const Byte *)(p))[3] << 24)) ((UInt32)((const Byte *)(p))[3] << 24))
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ #define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \ _ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); } _ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ #define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \ _ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); \ _ppp_[1] = (Byte)(_vvv_ >> 8); \
_ppp_[2] = (Byte)(_vvv_ >> 16); \ _ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); } _ppp_[3] = (Byte)(_vvv_ >> 24); }
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(_ppp2_ , (UInt32)_vvv2_); \ SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); } SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif #endif
#ifdef __has_builtin #ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x) #define MY__has_builtin(x) __has_builtin(x)
#else #else
#define MY__has_builtin(x) 0 #define MY__has_builtin(x) 0
#endif #endif
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
/* Note: we use bswap instruction, that is unsupported in 386 cpu */ /* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h> #include <stdlib.h>
#pragma intrinsic(_byteswap_ushort) #pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64) #pragma intrinsic(_byteswap_uint64)
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */ /* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && ( \ #elif defined(MY_CPU_LE_UNALIGN) && ( \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) ) || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */ /* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v) #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
#else #else
#define GetBe32(p) ( \ #define GetBe32(p) ( \
((UInt32)((const Byte *)(p))[0] << 24) | \ ((UInt32)((const Byte *)(p))[0] << 24) | \
((UInt32)((const Byte *)(p))[1] << 16) | \ ((UInt32)((const Byte *)(p))[1] << 16) | \
((UInt32)((const Byte *)(p))[2] << 8) | \ ((UInt32)((const Byte *)(p))[2] << 8) | \
((const Byte *)(p))[3] ) ((const Byte *)(p))[3] )
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ #define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \ _ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \ _ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \ _ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; } _ppp_[3] = (Byte)_vvv_; }
#endif #endif
#ifndef GetBe16 #ifndef GetBe16
#define GetBe16(p) ( (UInt16) ( \ #define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \ ((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] )) ((const Byte *)(p))[1] ))
#endif #endif
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
typedef struct typedef struct
{ {
UInt32 maxFunc; UInt32 maxFunc;
UInt32 vendor[3]; UInt32 vendor[3];
UInt32 ver; UInt32 ver;
UInt32 b; UInt32 b;
UInt32 c; UInt32 c;
UInt32 d; UInt32 d;
} Cx86cpuid; } Cx86cpuid;
enum enum
{ {
CPU_FIRM_INTEL, CPU_FIRM_INTEL,
CPU_FIRM_AMD, CPU_FIRM_AMD,
CPU_FIRM_VIA CPU_FIRM_VIA
}; };
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d); void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p); BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p); int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF)) #define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF)) #define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
#define x86cpuid_GetStepping(ver) (ver & 0xF) #define x86cpuid_GetStepping(ver) (ver & 0xF)
BoolInt CPU_Is_InOrder(); BoolInt CPU_Is_InOrder();
BoolInt CPU_Is_Aes_Supported(); BoolInt CPU_Is_Aes_Supported();
BoolInt CPU_IsSupported_PageGB(); BoolInt CPU_IsSupported_PageGB();
#endif #endif
EXTERN_C_END EXTERN_C_END
#endif #endif

128
C/Delta.c
View File

@@ -1,64 +1,64 @@
/* Delta.c -- Delta converter /* Delta.c -- Delta converter
2009-05-26 : Igor Pavlov : Public domain */ 2009-05-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Delta.h" #include "Delta.h"
void Delta_Init(Byte *state) void Delta_Init(Byte *state)
{ {
unsigned i; unsigned i;
for (i = 0; i < DELTA_STATE_SIZE; i++) for (i = 0; i < DELTA_STATE_SIZE; i++)
state[i] = 0; state[i] = 0;
} }
static void MyMemCpy(Byte *dest, const Byte *src, unsigned size) static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
{ {
unsigned i; unsigned i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
dest[i] = src[i]; dest[i] = src[i];
} }
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size) void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
{ {
Byte buf[DELTA_STATE_SIZE]; Byte buf[DELTA_STATE_SIZE];
unsigned j = 0; unsigned j = 0;
MyMemCpy(buf, state, delta); MyMemCpy(buf, state, delta);
{ {
SizeT i; SizeT i;
for (i = 0; i < size;) for (i = 0; i < size;)
{ {
for (j = 0; j < delta && i < size; i++, j++) for (j = 0; j < delta && i < size; i++, j++)
{ {
Byte b = data[i]; Byte b = data[i];
data[i] = (Byte)(b - buf[j]); data[i] = (Byte)(b - buf[j]);
buf[j] = b; buf[j] = b;
} }
} }
} }
if (j == delta) if (j == delta)
j = 0; j = 0;
MyMemCpy(state, buf + j, delta - j); MyMemCpy(state, buf + j, delta - j);
MyMemCpy(state + delta - j, buf, j); MyMemCpy(state + delta - j, buf, j);
} }
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size) void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
{ {
Byte buf[DELTA_STATE_SIZE]; Byte buf[DELTA_STATE_SIZE];
unsigned j = 0; unsigned j = 0;
MyMemCpy(buf, state, delta); MyMemCpy(buf, state, delta);
{ {
SizeT i; SizeT i;
for (i = 0; i < size;) for (i = 0; i < size;)
{ {
for (j = 0; j < delta && i < size; i++, j++) for (j = 0; j < delta && i < size; i++, j++)
{ {
buf[j] = data[i] = (Byte)(buf[j] + data[i]); buf[j] = data[i] = (Byte)(buf[j] + data[i]);
} }
} }
} }
if (j == delta) if (j == delta)
j = 0; j = 0;
MyMemCpy(state, buf + j, delta - j); MyMemCpy(state, buf + j, delta - j);
MyMemCpy(state + delta - j, buf, j); MyMemCpy(state + delta - j, buf, j);
} }

View File

@@ -1,19 +1,19 @@
/* Delta.h -- Delta converter /* Delta.h -- Delta converter
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __DELTA_H #ifndef __DELTA_H
#define __DELTA_H #define __DELTA_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define DELTA_STATE_SIZE 256 #define DELTA_STATE_SIZE 256
void Delta_Init(Byte *state); void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,108 +1,108 @@
/* DllSecur.c -- DLL loading security /* DllSecur.c -- DLL loading security
2018-02-21 : Igor Pavlov : Public domain */ 2018-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include "DllSecur.h" #include "DllSecur.h"
#ifndef UNDER_CE #ifndef UNDER_CE
typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags); typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags);
#define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400 #define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400
#define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 #define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800
static const char * const g_Dlls = static const char * const g_Dlls =
#ifndef _CONSOLE #ifndef _CONSOLE
"UXTHEME\0" "UXTHEME\0"
#endif #endif
"USERENV\0" "USERENV\0"
"SETUPAPI\0" "SETUPAPI\0"
"APPHELP\0" "APPHELP\0"
"PROPSYS\0" "PROPSYS\0"
"DWMAPI\0" "DWMAPI\0"
"CRYPTBASE\0" "CRYPTBASE\0"
"OLEACC\0" "OLEACC\0"
"CLBCATQ\0" "CLBCATQ\0"
"VERSION\0" "VERSION\0"
; ;
#endif #endif
void My_SetDefaultDllDirectories() void My_SetDefaultDllDirectories()
{ {
#ifndef UNDER_CE #ifndef UNDER_CE
OSVERSIONINFO vi; OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi); vi.dwOSVersionInfoSize = sizeof(vi);
GetVersionEx(&vi); GetVersionEx(&vi);
if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0) if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0)
{ {
Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories) Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories"); GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
if (setDllDirs) if (setDllDirs)
if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS))
return; return;
} }
#endif #endif
} }
void LoadSecurityDlls() void LoadSecurityDlls()
{ {
#ifndef UNDER_CE #ifndef UNDER_CE
wchar_t buf[MAX_PATH + 100]; wchar_t buf[MAX_PATH + 100];
{ {
// at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ???
OSVERSIONINFO vi; OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi); vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0) if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0)
{ {
Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories) Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories"); GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
if (setDllDirs) if (setDllDirs)
if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS))
return; return;
} }
} }
{ {
unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2); unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2);
if (len == 0 || len > MAX_PATH) if (len == 0 || len > MAX_PATH)
return; return;
} }
{ {
const char *dll; const char *dll;
unsigned pos = (unsigned)lstrlenW(buf); unsigned pos = (unsigned)lstrlenW(buf);
if (buf[pos - 1] != '\\') if (buf[pos - 1] != '\\')
buf[pos++] = '\\'; buf[pos++] = '\\';
for (dll = g_Dlls; dll[0] != 0;) for (dll = g_Dlls; dll[0] != 0;)
{ {
unsigned k = 0; unsigned k = 0;
for (;;) for (;;)
{ {
char c = *dll++; char c = *dll++;
buf[pos + k] = (Byte)c; buf[pos + k] = (Byte)c;
k++; k++;
if (c == 0) if (c == 0)
break; break;
} }
lstrcatW(buf, L".dll"); lstrcatW(buf, L".dll");
LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
} }
} }
#endif #endif
} }
#endif #endif

View File

@@ -1,20 +1,20 @@
/* DllSecur.h -- DLL loading for security /* DllSecur.h -- DLL loading for security
2018-02-19 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __DLL_SECUR_H #ifndef __DLL_SECUR_H
#define __DLL_SECUR_H #define __DLL_SECUR_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#ifdef _WIN32 #ifdef _WIN32
void My_SetDefaultDllDirectories(); void My_SetDefaultDllDirectories();
void LoadSecurityDlls(); void LoadSecurityDlls();
#endif #endif
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,148 +1,148 @@
/* HuffEnc.c -- functions for Huffman encoding /* HuffEnc.c -- functions for Huffman encoding
2017-04-03 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "HuffEnc.h" #include "HuffEnc.h"
#include "Sort.h" #include "Sort.h"
#define kMaxLen 16 #define kMaxLen 16
#define NUM_BITS 10 #define NUM_BITS 10
#define MASK ((1 << NUM_BITS) - 1) #define MASK ((1 << NUM_BITS) - 1)
#define NUM_COUNTERS 64 #define NUM_COUNTERS 64
#define HUFFMAN_SPEED_OPT #define HUFFMAN_SPEED_OPT
void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen) void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen)
{ {
UInt32 num = 0; UInt32 num = 0;
/* if (maxLen > 10) maxLen = 10; */ /* if (maxLen > 10) maxLen = 10; */
{ {
UInt32 i; UInt32 i;
#ifdef HUFFMAN_SPEED_OPT #ifdef HUFFMAN_SPEED_OPT
UInt32 counters[NUM_COUNTERS]; UInt32 counters[NUM_COUNTERS];
for (i = 0; i < NUM_COUNTERS; i++) for (i = 0; i < NUM_COUNTERS; i++)
counters[i] = 0; counters[i] = 0;
for (i = 0; i < numSymbols; i++) for (i = 0; i < numSymbols; i++)
{ {
UInt32 freq = freqs[i]; UInt32 freq = freqs[i];
counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++; counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
} }
for (i = 1; i < NUM_COUNTERS; i++) for (i = 1; i < NUM_COUNTERS; i++)
{ {
UInt32 temp = counters[i]; UInt32 temp = counters[i];
counters[i] = num; counters[i] = num;
num += temp; num += temp;
} }
for (i = 0; i < numSymbols; i++) for (i = 0; i < numSymbols; i++)
{ {
UInt32 freq = freqs[i]; UInt32 freq = freqs[i];
if (freq == 0) if (freq == 0)
lens[i] = 0; lens[i] = 0;
else else
p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS); p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS);
} }
counters[0] = 0; counters[0] = 0;
HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]); HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]);
#else #else
for (i = 0; i < numSymbols; i++) for (i = 0; i < numSymbols; i++)
{ {
UInt32 freq = freqs[i]; UInt32 freq = freqs[i];
if (freq == 0) if (freq == 0)
lens[i] = 0; lens[i] = 0;
else else
p[num++] = i | (freq << NUM_BITS); p[num++] = i | (freq << NUM_BITS);
} }
HeapSort(p, num); HeapSort(p, num);
#endif #endif
} }
if (num < 2) if (num < 2)
{ {
unsigned minCode = 0; unsigned minCode = 0;
unsigned maxCode = 1; unsigned maxCode = 1;
if (num == 1) if (num == 1)
{ {
maxCode = (unsigned)p[0] & MASK; maxCode = (unsigned)p[0] & MASK;
if (maxCode == 0) if (maxCode == 0)
maxCode++; maxCode++;
} }
p[minCode] = 0; p[minCode] = 0;
p[maxCode] = 1; p[maxCode] = 1;
lens[minCode] = lens[maxCode] = 1; lens[minCode] = lens[maxCode] = 1;
return; return;
} }
{ {
UInt32 b, e, i; UInt32 b, e, i;
i = b = e = 0; i = b = e = 0;
do do
{ {
UInt32 n, m, freq; UInt32 n, m, freq;
n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
freq = (p[n] & ~MASK); freq = (p[n] & ~MASK);
p[n] = (p[n] & MASK) | (e << NUM_BITS); p[n] = (p[n] & MASK) | (e << NUM_BITS);
m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++; m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
freq += (p[m] & ~MASK); freq += (p[m] & ~MASK);
p[m] = (p[m] & MASK) | (e << NUM_BITS); p[m] = (p[m] & MASK) | (e << NUM_BITS);
p[e] = (p[e] & MASK) | freq; p[e] = (p[e] & MASK) | freq;
e++; e++;
} }
while (num - e > 1); while (num - e > 1);
{ {
UInt32 lenCounters[kMaxLen + 1]; UInt32 lenCounters[kMaxLen + 1];
for (i = 0; i <= kMaxLen; i++) for (i = 0; i <= kMaxLen; i++)
lenCounters[i] = 0; lenCounters[i] = 0;
p[--e] &= MASK; p[--e] &= MASK;
lenCounters[1] = 2; lenCounters[1] = 2;
while (e > 0) while (e > 0)
{ {
UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1; UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
p[e] = (p[e] & MASK) | (len << NUM_BITS); p[e] = (p[e] & MASK) | (len << NUM_BITS);
if (len >= maxLen) if (len >= maxLen)
for (len = maxLen - 1; lenCounters[len] == 0; len--); for (len = maxLen - 1; lenCounters[len] == 0; len--);
lenCounters[len]--; lenCounters[len]--;
lenCounters[(size_t)len + 1] += 2; lenCounters[(size_t)len + 1] += 2;
} }
{ {
UInt32 len; UInt32 len;
i = 0; i = 0;
for (len = maxLen; len != 0; len--) for (len = maxLen; len != 0; len--)
{ {
UInt32 k; UInt32 k;
for (k = lenCounters[len]; k != 0; k--) for (k = lenCounters[len]; k != 0; k--)
lens[p[i++] & MASK] = (Byte)len; lens[p[i++] & MASK] = (Byte)len;
} }
} }
{ {
UInt32 nextCodes[kMaxLen + 1]; UInt32 nextCodes[kMaxLen + 1];
{ {
UInt32 code = 0; UInt32 code = 0;
UInt32 len; UInt32 len;
for (len = 1; len <= kMaxLen; len++) for (len = 1; len <= kMaxLen; len++)
nextCodes[len] = code = (code + lenCounters[(size_t)len - 1]) << 1; nextCodes[len] = code = (code + lenCounters[(size_t)len - 1]) << 1;
} }
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
{ {
UInt32 k; UInt32 k;
for (k = 0; k < numSymbols; k++) for (k = 0; k < numSymbols; k++)
p[k] = nextCodes[lens[k]]++; p[k] = nextCodes[lens[k]]++;
} }
} }
} }
} }
} }

View File

@@ -1,23 +1,23 @@
/* HuffEnc.h -- Huffman encoding /* HuffEnc.h -- Huffman encoding
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __HUFF_ENC_H #ifndef __HUFF_ENC_H
#define __HUFF_ENC_H #define __HUFF_ENC_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* /*
Conditions: Conditions:
num <= 1024 = 2 ^ NUM_BITS num <= 1024 = 2 ^ NUM_BITS
Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS) Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS)
maxLen <= 16 = kMaxLen maxLen <= 16 = kMaxLen
Num_Items(p) >= HUFFMAN_TEMP_SIZE(num) Num_Items(p) >= HUFFMAN_TEMP_SIZE(num)
*/ */
void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen); void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen);
EXTERN_C_END EXTERN_C_END
#endif #endif

2254
C/LzFind.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,121 +1,121 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2017-06-10 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
typedef UInt32 CLzRef; typedef UInt32 CLzRef;
typedef struct _CMatchFinder typedef struct _CMatchFinder
{ {
Byte *buffer; Byte *buffer;
UInt32 pos; UInt32 pos;
UInt32 posLimit; UInt32 posLimit;
UInt32 streamPos; UInt32 streamPos;
UInt32 lenLimit; UInt32 lenLimit;
UInt32 cyclicBufferPos; UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
Byte streamEndWasReached; Byte streamEndWasReached;
Byte btMode; Byte btMode;
Byte bigHash; Byte bigHash;
Byte directInput; Byte directInput;
UInt32 matchMaxLen; UInt32 matchMaxLen;
CLzRef *hash; CLzRef *hash;
CLzRef *son; CLzRef *son;
UInt32 hashMask; UInt32 hashMask;
UInt32 cutValue; UInt32 cutValue;
Byte *bufferBase; Byte *bufferBase;
ISeqInStream *stream; ISeqInStream *stream;
UInt32 blockSize; UInt32 blockSize;
UInt32 keepSizeBefore; UInt32 keepSizeBefore;
UInt32 keepSizeAfter; UInt32 keepSizeAfter;
UInt32 numHashBytes; UInt32 numHashBytes;
size_t directInputRem; size_t directInputRem;
UInt32 historySize; UInt32 historySize;
UInt32 fixedHashSize; UInt32 fixedHashSize;
UInt32 hashSizeSum; UInt32 hashSizeSum;
SRes result; SRes result;
UInt32 crc[256]; UInt32 crc[256];
size_t numRefs; size_t numRefs;
UInt64 expectedDataSize; UInt64 expectedDataSize;
} CMatchFinder; } CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
#define Inline_MatchFinder_IsFinishedOK(p) \ #define Inline_MatchFinder_IsFinishedOK(p) \
((p)->streamEndWasReached \ ((p)->streamEndWasReached \
&& (p)->streamPos == (p)->pos \ && (p)->streamPos == (p)->pos \
&& (!(p)->directInput || (p)->directInputRem == 0)) && (!(p)->directInput || (p)->directInputRem == 0))
int MatchFinder_NeedMove(CMatchFinder *p); int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p); void MatchFinder_MoveBlock(CMatchFinder *p);
void MatchFinder_ReadIfRequired(CMatchFinder *p); void MatchFinder_ReadIfRequired(CMatchFinder *p);
void MatchFinder_Construct(CMatchFinder *p); void MatchFinder_Construct(CMatchFinder *p);
/* Conditions: /* Conditions:
historySize <= 3 GB historySize <= 3 GB
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
*/ */
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAllocPtr alloc); ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 maxLen); UInt32 *distances, UInt32 maxLen);
/* /*
Conditions: Conditions:
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
*/ */
typedef void (*Mf_Init_Func)(void *object); typedef void (*Mf_Init_Func)(void *object);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
typedef void (*Mf_Skip_Func)(void *object, UInt32); typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder typedef struct _IMatchFinder
{ {
Mf_Init_Func Init; Mf_Init_Func Init;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches; Mf_GetMatches_Func GetMatches;
Mf_Skip_Func Skip; Mf_Skip_Func Skip;
} IMatchFinder; } IMatchFinder;
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_LowHash(CMatchFinder *p); void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p); void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_3(CMatchFinder *p, int readData); void MatchFinder_Init_3(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p); void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,101 +1,101 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2018-07-04 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H #ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H #define __LZ_FIND_MT_H
#include "LzFind.h" #include "LzFind.h"
#include "Threads.h" #include "Threads.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define kMtHashBlockSize (1 << 13) #define kMtHashBlockSize (1 << 13)
#define kMtHashNumBlocks (1 << 3) #define kMtHashNumBlocks (1 << 3)
#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1) #define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
#define kMtBtBlockSize (1 << 14) #define kMtBtBlockSize (1 << 14)
#define kMtBtNumBlocks (1 << 6) #define kMtBtNumBlocks (1 << 6)
#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1) #define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
typedef struct _CMtSync typedef struct _CMtSync
{ {
BoolInt wasCreated; BoolInt wasCreated;
BoolInt needStart; BoolInt needStart;
BoolInt exit; BoolInt exit;
BoolInt stopWriting; BoolInt stopWriting;
CThread thread; CThread thread;
CAutoResetEvent canStart; CAutoResetEvent canStart;
CAutoResetEvent wasStarted; CAutoResetEvent wasStarted;
CAutoResetEvent wasStopped; CAutoResetEvent wasStopped;
CSemaphore freeSemaphore; CSemaphore freeSemaphore;
CSemaphore filledSemaphore; CSemaphore filledSemaphore;
BoolInt csWasInitialized; BoolInt csWasInitialized;
BoolInt csWasEntered; BoolInt csWasEntered;
CCriticalSection cs; CCriticalSection cs;
UInt32 numProcessedBlocks; UInt32 numProcessedBlocks;
} CMtSync; } CMtSync;
typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */ /* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
#define kMtCacheLineDummy 128 #define kMtCacheLineDummy 128
typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
typedef struct _CMatchFinderMt typedef struct _CMatchFinderMt
{ {
/* LZ */ /* LZ */
const Byte *pointerToCurPos; const Byte *pointerToCurPos;
UInt32 *btBuf; UInt32 *btBuf;
UInt32 btBufPos; UInt32 btBufPos;
UInt32 btBufPosLimit; UInt32 btBufPosLimit;
UInt32 lzPos; UInt32 lzPos;
UInt32 btNumAvailBytes; UInt32 btNumAvailBytes;
UInt32 *hash; UInt32 *hash;
UInt32 fixedHashSize; UInt32 fixedHashSize;
UInt32 historySize; UInt32 historySize;
const UInt32 *crc; const UInt32 *crc;
Mf_Mix_Matches MixMatchesFunc; Mf_Mix_Matches MixMatchesFunc;
/* LZ + BT */ /* LZ + BT */
CMtSync btSync; CMtSync btSync;
Byte btDummy[kMtCacheLineDummy]; Byte btDummy[kMtCacheLineDummy];
/* BT */ /* BT */
UInt32 *hashBuf; UInt32 *hashBuf;
UInt32 hashBufPos; UInt32 hashBufPos;
UInt32 hashBufPosLimit; UInt32 hashBufPosLimit;
UInt32 hashNumAvail; UInt32 hashNumAvail;
CLzRef *son; CLzRef *son;
UInt32 matchMaxLen; UInt32 matchMaxLen;
UInt32 numHashBytes; UInt32 numHashBytes;
UInt32 pos; UInt32 pos;
const Byte *buffer; const Byte *buffer;
UInt32 cyclicBufferPos; UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be historySize + 1 */ UInt32 cyclicBufferSize; /* it must be historySize + 1 */
UInt32 cutValue; UInt32 cutValue;
/* BT + Hash */ /* BT + Hash */
CMtSync hashSync; CMtSync hashSync;
/* Byte hashDummy[kMtCacheLineDummy]; */ /* Byte hashDummy[kMtCacheLineDummy]; */
/* Hash */ /* Hash */
Mf_GetHeads GetHeadsFunc; Mf_GetHeads GetHeadsFunc;
CMatchFinder *MatchFinder; CMatchFinder *MatchFinder;
} CMatchFinderMt; } CMatchFinderMt;
void MatchFinderMt_Construct(CMatchFinderMt *p); void MatchFinderMt_Construct(CMatchFinderMt *p);
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc); void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc); UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,57 +1,57 @@
/* LzHash.h -- HASH functions for LZ algorithms /* LzHash.h -- HASH functions for LZ algorithms
2015-04-12 : Igor Pavlov : Public domain */ 2015-04-12 : Igor Pavlov : Public domain */
#ifndef __LZ_HASH_H #ifndef __LZ_HASH_H
#define __LZ_HASH_H #define __LZ_HASH_H
#define kHash2Size (1 << 10) #define kHash2Size (1 << 10)
#define kHash3Size (1 << 16) #define kHash3Size (1 << 16)
#define kHash4Size (1 << 20) #define kHash4Size (1 << 20)
#define kFix3HashSize (kHash2Size) #define kFix3HashSize (kHash2Size)
#define kFix4HashSize (kHash2Size + kHash3Size) #define kFix4HashSize (kHash2Size + kHash3Size)
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8); #define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8);
#define HASH3_CALC { \ #define HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \ h2 = temp & (kHash2Size - 1); \
hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \ #define HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \ h2 = temp & (kHash2Size - 1); \
temp ^= ((UInt32)cur[2] << 8); \ temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \ h3 = temp & (kHash3Size - 1); \
hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; } hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \ #define HASH5_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \ h2 = temp & (kHash2Size - 1); \
temp ^= ((UInt32)cur[2] << 8); \ temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \ h3 = temp & (kHash3Size - 1); \
temp ^= (p->crc[cur[3]] << 5); \ temp ^= (p->crc[cur[3]] << 5); \
h4 = temp & (kHash4Size - 1); \ h4 = temp & (kHash4Size - 1); \
hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; } hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; }
/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ /* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; #define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \ #define MT_HASH2_CALC \
h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \ #define MT_HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \ h2 = temp & (kHash2Size - 1); \
h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \ #define MT_HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \ h2 = temp & (kHash2Size - 1); \
temp ^= ((UInt32)cur[2] << 8); \ temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \ h3 = temp & (kHash3Size - 1); \
h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
#endif #endif

View File

@@ -1,488 +1,488 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2019-02-02 : Igor Pavlov : Public domain */ 2019-02-02 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
#include "Precomp.h" #include "Precomp.h"
#ifdef SHOW_DEBUG_INFO #ifdef SHOW_DEBUG_INFO
#include <stdio.h> #include <stdio.h>
#endif #endif
#include <string.h> #include <string.h>
#include "Lzma2Dec.h" #include "Lzma2Dec.h"
/* /*
00000000 - End of data 00000000 - End of data
00000001 U U - Uncompressed, reset dic, need reset state and set new prop 00000001 U U - Uncompressed, reset dic, need reset state and set new prop
00000010 U U - Uncompressed, no reset 00000010 U U - Uncompressed, no reset
100uuuuu U U P P - LZMA, no reset 100uuuuu U U P P - LZMA, no reset
101uuuuu U U P P - LZMA, reset state 101uuuuu U U P P - LZMA, reset state
110uuuuu U U P P S - LZMA, reset state + set new prop 110uuuuu U U P P S - LZMA, reset state + set new prop
111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic 111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
u, U - Unpack Size u, U - Unpack Size
P - Pack Size P - Pack Size
S - Props S - Props
*/ */
#define LZMA2_CONTROL_COPY_RESET_DIC 1 #define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0) #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
#define LZMA2_LCLP_MAX 4 #define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO #ifdef SHOW_DEBUG_INFO
#define PRF(x) x #define PRF(x) x
#else #else
#define PRF(x) #define PRF(x)
#endif #endif
typedef enum typedef enum
{ {
LZMA2_STATE_CONTROL, LZMA2_STATE_CONTROL,
LZMA2_STATE_UNPACK0, LZMA2_STATE_UNPACK0,
LZMA2_STATE_UNPACK1, LZMA2_STATE_UNPACK1,
LZMA2_STATE_PACK0, LZMA2_STATE_PACK0,
LZMA2_STATE_PACK1, LZMA2_STATE_PACK1,
LZMA2_STATE_PROP, LZMA2_STATE_PROP,
LZMA2_STATE_DATA, LZMA2_STATE_DATA,
LZMA2_STATE_DATA_CONT, LZMA2_STATE_DATA_CONT,
LZMA2_STATE_FINISHED, LZMA2_STATE_FINISHED,
LZMA2_STATE_ERROR LZMA2_STATE_ERROR
} ELzma2State; } ELzma2State;
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
{ {
UInt32 dicSize; UInt32 dicSize;
if (prop > 40) if (prop > 40)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
props[0] = (Byte)LZMA2_LCLP_MAX; props[0] = (Byte)LZMA2_LCLP_MAX;
props[1] = (Byte)(dicSize); props[1] = (Byte)(dicSize);
props[2] = (Byte)(dicSize >> 8); props[2] = (Byte)(dicSize >> 8);
props[3] = (Byte)(dicSize >> 16); props[3] = (Byte)(dicSize >> 16);
props[4] = (Byte)(dicSize >> 24); props[4] = (Byte)(dicSize >> 24);
return SZ_OK; return SZ_OK;
} }
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
void Lzma2Dec_Init(CLzma2Dec *p) void Lzma2Dec_Init(CLzma2Dec *p)
{ {
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
p->needInitLevel = 0xE0; p->needInitLevel = 0xE0;
p->isExtraMode = False; p->isExtraMode = False;
p->unpackSize = 0; p->unpackSize = 0;
// p->decoder.dicPos = 0; // we can use it instead of full init // p->decoder.dicPos = 0; // we can use it instead of full init
LzmaDec_Init(&p->decoder); LzmaDec_Init(&p->decoder);
} }
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{ {
switch (p->state) switch (p->state)
{ {
case LZMA2_STATE_CONTROL: case LZMA2_STATE_CONTROL:
p->isExtraMode = False; p->isExtraMode = False;
p->control = b; p->control = b;
PRF(printf("\n %8X", (unsigned)p->decoder.dicPos)); PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
PRF(printf(" %02X", (unsigned)b)); PRF(printf(" %02X", (unsigned)b));
if (b == 0) if (b == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if (b == LZMA2_CONTROL_COPY_RESET_DIC) if (b == LZMA2_CONTROL_COPY_RESET_DIC)
p->needInitLevel = 0xC0; p->needInitLevel = 0xC0;
else if (b > 2 || p->needInitLevel == 0xE0) else if (b > 2 || p->needInitLevel == 0xE0)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
} }
else else
{ {
if (b < p->needInitLevel) if (b < p->needInitLevel)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
p->needInitLevel = 0; p->needInitLevel = 0;
p->unpackSize = (UInt32)(b & 0x1F) << 16; p->unpackSize = (UInt32)(b & 0x1F) << 16;
} }
return LZMA2_STATE_UNPACK0; return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0: case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8; p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1; return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1: case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b; p->unpackSize |= (UInt32)b;
p->unpackSize++; p->unpackSize++;
PRF(printf(" %7u", (unsigned)p->unpackSize)); PRF(printf(" %7u", (unsigned)p->unpackSize));
return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8; p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1; return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1: case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b; p->packSize |= (UInt32)b;
p->packSize++; p->packSize++;
// if (p->packSize < 5) return LZMA2_STATE_ERROR; // if (p->packSize < 5) return LZMA2_STATE_ERROR;
PRF(printf(" %5u", (unsigned)p->packSize)); PRF(printf(" %5u", (unsigned)p->packSize));
return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA; return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
case LZMA2_STATE_PROP: case LZMA2_STATE_PROP:
{ {
unsigned lc, lp; unsigned lc, lp;
if (b >= (9 * 5 * 5)) if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
lc = b % 9; lc = b % 9;
b /= 9; b /= 9;
p->decoder.prop.pb = (Byte)(b / 5); p->decoder.prop.pb = (Byte)(b / 5);
lp = b % 5; lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX) if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
p->decoder.prop.lc = (Byte)lc; p->decoder.prop.lc = (Byte)lc;
p->decoder.prop.lp = (Byte)lp; p->decoder.prop.lp = (Byte)lp;
return LZMA2_STATE_DATA; return LZMA2_STATE_DATA;
} }
} }
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
} }
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
{ {
memcpy(p->dic + p->dicPos, src, size); memcpy(p->dic + p->dicPos, src, size);
p->dicPos += size; p->dicPos += size;
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
p->processedPos += (UInt32)size; p->processedPos += (UInt32)size;
} }
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState); void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
*srcLen = 0; *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_ERROR) while (p->state != LZMA2_STATE_ERROR)
{ {
SizeT dicPos; SizeT dicPos;
if (p->state == LZMA2_STATE_FINISHED) if (p->state == LZMA2_STATE_FINISHED)
{ {
*status = LZMA_STATUS_FINISHED_WITH_MARK; *status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK; return SZ_OK;
} }
dicPos = p->decoder.dicPos; dicPos = p->decoder.dicPos;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK; return SZ_OK;
} }
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{ {
if (*srcLen == inSize) if (*srcLen == inSize)
{ {
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
(*srcLen)++; (*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++); p->state = Lzma2Dec_UpdateState(p, *src++);
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED) if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
break; break;
continue; continue;
} }
{ {
SizeT inCur = inSize - *srcLen; SizeT inCur = inSize - *srcLen;
SizeT outCur = dicLimit - dicPos; SizeT outCur = dicLimit - dicPos;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (outCur >= p->unpackSize) if (outCur >= p->unpackSize)
{ {
outCur = (SizeT)p->unpackSize; outCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END; curFinishMode = LZMA_FINISH_END;
} }
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if (inCur == 0) if (inCur == 0)
{ {
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
LzmaDec_InitDicAndState(&p->decoder, initDic, False); LzmaDec_InitDicAndState(&p->decoder, initDic, False);
} }
if (inCur > outCur) if (inCur > outCur)
inCur = outCur; inCur = outCur;
if (inCur == 0) if (inCur == 0)
break; break;
LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur); LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
src += inCur; src += inCur;
*srcLen += inCur; *srcLen += inCur;
p->unpackSize -= (UInt32)inCur; p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
} }
else else
{ {
SRes res; SRes res;
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
BoolInt initDic = (p->control >= 0xE0); BoolInt initDic = (p->control >= 0xE0);
BoolInt initState = (p->control >= 0xA0); BoolInt initState = (p->control >= 0xA0);
LzmaDec_InitDicAndState(&p->decoder, initDic, initState); LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->state = LZMA2_STATE_DATA_CONT; p->state = LZMA2_STATE_DATA_CONT;
} }
if (inCur > p->packSize) if (inCur > p->packSize)
inCur = (SizeT)p->packSize; inCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status); res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
src += inCur; src += inCur;
*srcLen += inCur; *srcLen += inCur;
p->packSize -= (UInt32)inCur; p->packSize -= (UInt32)inCur;
outCur = p->decoder.dicPos - dicPos; outCur = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outCur; p->unpackSize -= (UInt32)outCur;
if (res != 0) if (res != 0)
break; break;
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
{ {
if (p->packSize == 0) if (p->packSize == 0)
break; break;
return SZ_OK; return SZ_OK;
} }
if (inCur == 0 && outCur == 0) if (inCur == 0 && outCur == 0)
{ {
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0 || p->unpackSize != 0
|| p->packSize != 0) || p->packSize != 0)
break; break;
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
} }
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
} }
} }
} }
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
p->state = LZMA2_STATE_ERROR; p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} }
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize, SizeT outSize,
const Byte *src, SizeT *srcLen, const Byte *src, SizeT *srcLen,
int checkFinishBlock) int checkFinishBlock)
{ {
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
*srcLen = 0; *srcLen = 0;
while (p->state != LZMA2_STATE_ERROR) while (p->state != LZMA2_STATE_ERROR)
{ {
if (p->state == LZMA2_STATE_FINISHED) if (p->state == LZMA2_STATE_FINISHED)
return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK; return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
if (outSize == 0 && !checkFinishBlock) if (outSize == 0 && !checkFinishBlock)
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{ {
if (*srcLen == inSize) if (*srcLen == inSize)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
(*srcLen)++; (*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++); p->state = Lzma2Dec_UpdateState(p, *src++);
if (p->state == LZMA2_STATE_UNPACK0) if (p->state == LZMA2_STATE_UNPACK0)
{ {
// if (p->decoder.dicPos != 0) // if (p->decoder.dicPos != 0)
if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0) if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
return LZMA2_PARSE_STATUS_NEW_BLOCK; return LZMA2_PARSE_STATUS_NEW_BLOCK;
// if (outSize == 0) return LZMA_STATUS_NOT_FINISHED; // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
} }
// The following code can be commented. // The following code can be commented.
// It's not big problem, if we read additional input bytes. // It's not big problem, if we read additional input bytes.
// It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state. // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
if (outSize == 0 && p->state != LZMA2_STATE_FINISHED) if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
{ {
// checkFinishBlock is true. So we expect that block must be finished, // checkFinishBlock is true. So we expect that block must be finished,
// We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
// break; // break;
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
} }
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
return LZMA2_PARSE_STATUS_NEW_CHUNK; return LZMA2_PARSE_STATUS_NEW_CHUNK;
continue; continue;
} }
if (outSize == 0) if (outSize == 0)
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED; return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
{ {
SizeT inCur = inSize - *srcLen; SizeT inCur = inSize - *srcLen;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if (inCur == 0) if (inCur == 0)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
if (inCur > p->unpackSize) if (inCur > p->unpackSize)
inCur = p->unpackSize; inCur = p->unpackSize;
if (inCur > outSize) if (inCur > outSize)
inCur = outSize; inCur = outSize;
p->decoder.dicPos += inCur; p->decoder.dicPos += inCur;
src += inCur; src += inCur;
*srcLen += inCur; *srcLen += inCur;
outSize -= inCur; outSize -= inCur;
p->unpackSize -= (UInt32)inCur; p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
} }
else else
{ {
p->isExtraMode = True; p->isExtraMode = True;
if (inCur == 0) if (inCur == 0)
{ {
if (p->packSize != 0) if (p->packSize != 0)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT; return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
} }
else if (p->state == LZMA2_STATE_DATA) else if (p->state == LZMA2_STATE_DATA)
{ {
p->state = LZMA2_STATE_DATA_CONT; p->state = LZMA2_STATE_DATA_CONT;
if (*src != 0) if (*src != 0)
{ {
// first byte of lzma chunk must be Zero // first byte of lzma chunk must be Zero
*srcLen += 1; *srcLen += 1;
p->packSize--; p->packSize--;
break; break;
} }
} }
if (inCur > p->packSize) if (inCur > p->packSize)
inCur = (SizeT)p->packSize; inCur = (SizeT)p->packSize;
src += inCur; src += inCur;
*srcLen += inCur; *srcLen += inCur;
p->packSize -= (UInt32)inCur; p->packSize -= (UInt32)inCur;
if (p->packSize == 0) if (p->packSize == 0)
{ {
SizeT rem = outSize; SizeT rem = outSize;
if (rem > p->unpackSize) if (rem > p->unpackSize)
rem = p->unpackSize; rem = p->unpackSize;
p->decoder.dicPos += rem; p->decoder.dicPos += rem;
p->unpackSize -= (UInt32)rem; p->unpackSize -= (UInt32)rem;
outSize -= rem; outSize -= rem;
if (p->unpackSize == 0) if (p->unpackSize == 0)
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
} }
} }
} }
} }
p->state = LZMA2_STATE_ERROR; p->state = LZMA2_STATE_ERROR;
return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED; return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
} }
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) for (;;)
{ {
SizeT inCur = inSize, outCur, dicPos; SizeT inCur = inSize, outCur, dicPos;
ELzmaFinishMode curFinishMode; ELzmaFinishMode curFinishMode;
SRes res; SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize) if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0; p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos; dicPos = p->decoder.dicPos;
curFinishMode = LZMA_FINISH_ANY; curFinishMode = LZMA_FINISH_ANY;
outCur = p->decoder.dicBufSize - dicPos; outCur = p->decoder.dicBufSize - dicPos;
if (outCur >= outSize) if (outCur >= outSize)
{ {
outCur = outSize; outCur = outSize;
curFinishMode = finishMode; curFinishMode = finishMode;
} }
res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status); res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
src += inCur; src += inCur;
inSize -= inCur; inSize -= inCur;
*srcLen += inCur; *srcLen += inCur;
outCur = p->decoder.dicPos - dicPos; outCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outCur); memcpy(dest, p->decoder.dic + dicPos, outCur);
dest += outCur; dest += outCur;
outSize -= outCur; outSize -= outCur;
*destLen += outCur; *destLen += outCur;
if (res != 0) if (res != 0)
return res; return res;
if (outCur == 0 || outSize == 0) if (outCur == 0 || outSize == 0)
return SZ_OK; return SZ_OK;
} }
} }
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc) Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
{ {
CLzma2Dec p; CLzma2Dec p;
SRes res; SRes res;
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
*destLen = *srcLen = 0; *destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
Lzma2Dec_Construct(&p); Lzma2Dec_Construct(&p);
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest; p.decoder.dic = dest;
p.decoder.dicBufSize = outSize; p.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&p); Lzma2Dec_Init(&p);
*srcLen = inSize; *srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.decoder.dicPos; *destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF; res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc); Lzma2Dec_FreeProbs(&p, alloc);
return res; return res;
} }

View File

@@ -1,120 +1,120 @@
/* Lzma2Dec.h -- LZMA2 Decoder /* Lzma2Dec.h -- LZMA2 Decoder
2018-02-19 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H #ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H #define __LZMA2_DEC_H
#include "LzmaDec.h" #include "LzmaDec.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* ---------- State Interface ---------- */ /* ---------- State Interface ---------- */
typedef struct typedef struct
{ {
unsigned state; unsigned state;
Byte control; Byte control;
Byte needInitLevel; Byte needInitLevel;
Byte isExtraMode; Byte isExtraMode;
Byte _pad_; Byte _pad_;
UInt32 packSize; UInt32 packSize;
UInt32 unpackSize; UInt32 unpackSize;
CLzmaDec decoder; CLzmaDec decoder;
} CLzma2Dec; } CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) #define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p); void Lzma2Dec_Init(CLzma2Dec *p);
/* /*
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit). It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
LZMA_FINISH_ANY - use smallest number of input bytes LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding LZMA_FINISH_END - read EndOfStream marker after decoding
Returns: Returns:
SZ_OK SZ_OK
status: status:
LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT LZMA_STATUS_NEEDS_MORE_INPUT
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- LZMA2 block and chunk parsing ---------- */ /* ---------- LZMA2 block and chunk parsing ---------- */
/* /*
Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data. Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code: It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
- LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input. - LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
- LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read. - LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
CLzma2Dec::unpackSize contains unpack size of that chunk CLzma2Dec::unpackSize contains unpack size of that chunk
*/ */
typedef enum typedef enum
{ {
/* /*
LZMA_STATUS_NOT_SPECIFIED // data error LZMA_STATUS_NOT_SPECIFIED // data error
LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED // LZMA_STATUS_NOT_FINISHED //
LZMA_STATUS_NEEDS_MORE_INPUT LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
*/ */
LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1, LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
LZMA2_PARSE_STATUS_NEW_CHUNK LZMA2_PARSE_STATUS_NEW_CHUNK
} ELzma2ParseStatus; } ELzma2ParseStatus;
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p, ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize, // output size SizeT outSize, // output size
const Byte *src, SizeT *srcLen, const Byte *src, SizeT *srcLen,
int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position. int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position.
); );
/* /*
LZMA2 parser doesn't decode LZMA chunks, so we must read LZMA2 parser doesn't decode LZMA chunks, so we must read
full input LZMA chunk to decode some part of LZMA chunk. full input LZMA chunk to decode some part of LZMA chunk.
Lzma2Dec_GetUnpackExtra() returns the value that shows Lzma2Dec_GetUnpackExtra() returns the value that shows
max possible number of output bytes that can be output by decoder max possible number of output bytes that can be output by decoder
at current input positon. at current input positon.
*/ */
#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0); #define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
/* /*
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen). It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - use smallest number of input bytes LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding LZMA_FINISH_END - read EndOfStream marker after decoding
Returns: Returns:
SZ_OK SZ_OK
status: status:
LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED LZMA_STATUS_NOT_FINISHED
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/ */
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc); Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +1,79 @@
/* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread /* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread
2018-02-17 : Igor Pavlov : Public domain */ 2018-02-17 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_MT_H #ifndef __LZMA2_DEC_MT_H
#define __LZMA2_DEC_MT_H #define __LZMA2_DEC_MT_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
typedef struct typedef struct
{ {
size_t inBufSize_ST; size_t inBufSize_ST;
size_t outStep_ST; size_t outStep_ST;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
unsigned numThreads; unsigned numThreads;
size_t inBufSize_MT; size_t inBufSize_MT;
size_t outBlockMax; size_t outBlockMax;
size_t inBlockMax; size_t inBlockMax;
#endif #endif
} CLzma2DecMtProps; } CLzma2DecMtProps;
/* init to single-thread mode */ /* init to single-thread mode */
void Lzma2DecMtProps_Init(CLzma2DecMtProps *p); void Lzma2DecMtProps_Init(CLzma2DecMtProps *p);
/* ---------- CLzma2DecMtHandle Interface ---------- */ /* ---------- CLzma2DecMtHandle Interface ---------- */
/* Lzma2DecMt_ * functions can return the following exit codes: /* Lzma2DecMt_ * functions can return the following exit codes:
SRes: SRes:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error SZ_ERROR_WRITE - ISeqOutStream write callback error
// SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output // SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/ */
typedef void * CLzma2DecMtHandle; typedef void * CLzma2DecMtHandle;
CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid);
void Lzma2DecMt_Destroy(CLzma2DecMtHandle p); void Lzma2DecMt_Destroy(CLzma2DecMtHandle p);
SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p,
Byte prop, Byte prop,
const CLzma2DecMtProps *props, const CLzma2DecMtProps *props,
ISeqOutStream *outStream, ISeqOutStream *outStream,
const UInt64 *outDataSize, // NULL means undefined const UInt64 *outDataSize, // NULL means undefined
int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished
// Byte *outBuf, size_t *outBufSize, // Byte *outBuf, size_t *outBufSize,
ISeqInStream *inStream, ISeqInStream *inStream,
// const Byte *inData, size_t inDataSize, // const Byte *inData, size_t inDataSize,
// out variables: // out variables:
UInt64 *inProcessed, UInt64 *inProcessed,
int *isMT, /* out: (*isMT == 0), if single thread decoding was used */ int *isMT, /* out: (*isMT == 0), if single thread decoding was used */
// UInt64 *outProcessed, // UInt64 *outProcessed,
ICompressProgress *progress); ICompressProgress *progress);
/* ---------- Read from CLzma2DecMtHandle Interface ---------- */ /* ---------- Read from CLzma2DecMtHandle Interface ---------- */
SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp, SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp,
Byte prop, Byte prop,
const CLzma2DecMtProps *props, const CLzma2DecMtProps *props,
const UInt64 *outDataSize, int finishMode, const UInt64 *outDataSize, int finishMode,
ISeqInStream *inStream); ISeqInStream *inStream);
SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp, SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp,
Byte *data, size_t *outSize, Byte *data, size_t *outSize,
UInt64 *inStreamProcessed); UInt64 *inStreamProcessed);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +1,55 @@
/* Lzma2Enc.h -- LZMA2 Encoder /* Lzma2Enc.h -- LZMA2 Encoder
2017-07-27 : Igor Pavlov : Public domain */ 2017-07-27 : Igor Pavlov : Public domain */
#ifndef __LZMA2_ENC_H #ifndef __LZMA2_ENC_H
#define __LZMA2_ENC_H #define __LZMA2_ENC_H
#include "LzmaEnc.h" #include "LzmaEnc.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0 #define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0
#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1) #define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1)
typedef struct typedef struct
{ {
CLzmaEncProps lzmaProps; CLzmaEncProps lzmaProps;
UInt64 blockSize; UInt64 blockSize;
int numBlockThreads_Reduced; int numBlockThreads_Reduced;
int numBlockThreads_Max; int numBlockThreads_Max;
int numTotalThreads; int numTotalThreads;
} CLzma2EncProps; } CLzma2EncProps;
void Lzma2EncProps_Init(CLzma2EncProps *p); void Lzma2EncProps_Init(CLzma2EncProps *p);
void Lzma2EncProps_Normalize(CLzma2EncProps *p); void Lzma2EncProps_Normalize(CLzma2EncProps *p);
/* ---------- CLzmaEnc2Handle Interface ---------- */ /* ---------- CLzmaEnc2Handle Interface ---------- */
/* Lzma2Enc_* functions can return the following exit codes: /* Lzma2Enc_* functions can return the following exit codes:
SRes: SRes:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/ */
typedef void * CLzma2EncHandle; typedef void * CLzma2EncHandle;
CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
void Lzma2Enc_Destroy(CLzma2EncHandle p); void Lzma2Enc_Destroy(CLzma2EncHandle p);
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize); void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize);
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
SRes Lzma2Enc_Encode2(CLzma2EncHandle p, SRes Lzma2Enc_Encode2(CLzma2EncHandle p,
ISeqOutStream *outStream, ISeqOutStream *outStream,
Byte *outBuf, size_t *outBufSize, Byte *outBuf, size_t *outBufSize,
ISeqInStream *inStream, ISeqInStream *inStream,
const Byte *inData, size_t inDataSize, const Byte *inData, size_t inDataSize,
ICompressProgress *progress); ICompressProgress *progress);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,111 +1,111 @@
/* Lzma86.h -- LZMA + x86 (BCJ) Filter /* Lzma86.h -- LZMA + x86 (BCJ) Filter
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA86_H #ifndef __LZMA86_H
#define __LZMA86_H #define __LZMA86_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define LZMA86_SIZE_OFFSET (1 + 5) #define LZMA86_SIZE_OFFSET (1 + 5)
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) #define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
/* /*
It's an example for LZMA + x86 Filter use. It's an example for LZMA + x86 Filter use.
You can use .lzma86 extension, if you write that stream to file. You can use .lzma86 extension, if you write that stream to file.
.lzma86 header adds one additional byte to standard .lzma header. .lzma86 header adds one additional byte to standard .lzma header.
.lzma86 header (14 bytes): .lzma86 header (14 bytes):
Offset Size Description Offset Size Description
0 1 = 0 - no filter, pure LZMA 0 1 = 0 - no filter, pure LZMA
= 1 - x86 filter + LZMA = 1 - x86 filter + LZMA
1 1 lc, lp and pb in encoded form 1 1 lc, lp and pb in encoded form
2 4 dictSize (little endian) 2 4 dictSize (little endian)
6 8 uncompressed size (little endian) 6 8 uncompressed size (little endian)
Lzma86_Encode Lzma86_Encode
------------- -------------
level - compression level: 0 <= level <= 9, the default value for "level" is 5. level - compression level: 0 <= level <= 9, the default value for "level" is 5.
dictSize - The dictionary size in bytes. The maximum value is dictSize - The dictionary size in bytes. The maximum value is
128 MB = (1 << 27) bytes for 32-bit version 128 MB = (1 << 27) bytes for 32-bit version
1 GB = (1 << 30) bytes for 64-bit version 1 GB = (1 << 30) bytes for 64-bit version
The default value is 16 MB = (1 << 24) bytes, for level = 5. The default value is 16 MB = (1 << 24) bytes, for level = 5.
It's recommended to use the dictionary that is larger than 4 KB and It's recommended to use the dictionary that is larger than 4 KB and
that can be calculated as (1 << N) or (3 << N) sizes. that can be calculated as (1 << N) or (3 << N) sizes.
For better compression ratio dictSize must be >= inSize. For better compression ratio dictSize must be >= inSize.
filterMode: filterMode:
SZ_FILTER_NO - no Filter SZ_FILTER_NO - no Filter
SZ_FILTER_YES - x86 Filter SZ_FILTER_YES - x86 Filter
SZ_FILTER_AUTO - it tries both alternatives to select best. SZ_FILTER_AUTO - it tries both alternatives to select best.
Encoder will use 2 or 3 passes: Encoder will use 2 or 3 passes:
2 passes when FILTER_NO provides better compression. 2 passes when FILTER_NO provides better compression.
3 passes when FILTER_YES provides better compression. 3 passes when FILTER_YES provides better compression.
Lzma86Encode allocates Data with MyAlloc functions. Lzma86Encode allocates Data with MyAlloc functions.
RAM Requirements for compressing: RAM Requirements for compressing:
RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
filterMode FilterBlockSize filterMode FilterBlockSize
SZ_FILTER_NO 0 SZ_FILTER_NO 0
SZ_FILTER_YES inSize SZ_FILTER_YES inSize
SZ_FILTER_AUTO inSize SZ_FILTER_AUTO inSize
Return code: Return code:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/ */
enum ESzFilterMode enum ESzFilterMode
{ {
SZ_FILTER_NO, SZ_FILTER_NO,
SZ_FILTER_YES, SZ_FILTER_YES,
SZ_FILTER_AUTO SZ_FILTER_AUTO
}; };
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode); int level, UInt32 dictSize, int filterMode);
/* /*
Lzma86_GetUnpackSize: Lzma86_GetUnpackSize:
In: In:
src - input data src - input data
srcLen - input data size srcLen - input data size
Out: Out:
unpackSize - size of uncompressed stream unpackSize - size of uncompressed stream
Return code: Return code:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_INPUT_EOF - Error in headers SZ_ERROR_INPUT_EOF - Error in headers
*/ */
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
/* /*
Lzma86_Decode: Lzma86_Decode:
In: In:
dest - output data dest - output data
destLen - output data size destLen - output data size
src - input data src - input data
srcLen - input data size srcLen - input data size
Out: Out:
destLen - processed output size destLen - processed output size
srcLen - processed input size srcLen - processed input size
Return code: Return code:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - unsupported file SZ_ERROR_UNSUPPORTED - unsupported file
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
*/ */
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,54 +1,54 @@
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder /* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
2016-05-16 : Igor Pavlov : Public domain */ 2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Lzma86.h" #include "Lzma86.h"
#include "Alloc.h" #include "Alloc.h"
#include "Bra.h" #include "Bra.h"
#include "LzmaDec.h" #include "LzmaDec.h"
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
{ {
unsigned i; unsigned i;
if (srcLen < LZMA86_HEADER_SIZE) if (srcLen < LZMA86_HEADER_SIZE)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
*unpackSize = 0; *unpackSize = 0;
for (i = 0; i < sizeof(UInt64); i++) for (i = 0; i < sizeof(UInt64); i++)
*unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i);
return SZ_OK; return SZ_OK;
} }
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
{ {
SRes res; SRes res;
int useFilter; int useFilter;
SizeT inSizePure; SizeT inSizePure;
ELzmaStatus status; ELzmaStatus status;
if (*srcLen < LZMA86_HEADER_SIZE) if (*srcLen < LZMA86_HEADER_SIZE)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
useFilter = src[0]; useFilter = src[0];
if (useFilter > 1) if (useFilter > 1)
{ {
*destLen = 0; *destLen = 0;
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
inSizePure = *srcLen - LZMA86_HEADER_SIZE; inSizePure = *srcLen - LZMA86_HEADER_SIZE;
res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure,
src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc);
*srcLen = inSizePure + LZMA86_HEADER_SIZE; *srcLen = inSizePure + LZMA86_HEADER_SIZE;
if (res != SZ_OK) if (res != SZ_OK)
return res; return res;
if (useFilter == 1) if (useFilter == 1)
{ {
UInt32 x86State; UInt32 x86State;
x86_Convert_Init(x86State); x86_Convert_Init(x86State);
x86_Convert(dest, *destLen, 0, &x86State, 0); x86_Convert(dest, *destLen, 0, &x86State, 0);
} }
return SZ_OK; return SZ_OK;
} }

View File

@@ -1,106 +1,106 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2018-07-04 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <string.h> #include <string.h>
#include "Lzma86.h" #include "Lzma86.h"
#include "Alloc.h" #include "Alloc.h"
#include "Bra.h" #include "Bra.h"
#include "LzmaEnc.h" #include "LzmaEnc.h"
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode) int level, UInt32 dictSize, int filterMode)
{ {
size_t outSize2 = *destLen; size_t outSize2 = *destLen;
Byte *filteredStream; Byte *filteredStream;
BoolInt useFilter; BoolInt useFilter;
int mainResult = SZ_ERROR_OUTPUT_EOF; int mainResult = SZ_ERROR_OUTPUT_EOF;
CLzmaEncProps props; CLzmaEncProps props;
LzmaEncProps_Init(&props); LzmaEncProps_Init(&props);
props.level = level; props.level = level;
props.dictSize = dictSize; props.dictSize = dictSize;
*destLen = 0; *destLen = 0;
if (outSize2 < LZMA86_HEADER_SIZE) if (outSize2 < LZMA86_HEADER_SIZE)
return SZ_ERROR_OUTPUT_EOF; return SZ_ERROR_OUTPUT_EOF;
{ {
int i; int i;
UInt64 t = srcLen; UInt64 t = srcLen;
for (i = 0; i < 8; i++, t >>= 8) for (i = 0; i < 8; i++, t >>= 8)
dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
} }
filteredStream = 0; filteredStream = 0;
useFilter = (filterMode != SZ_FILTER_NO); useFilter = (filterMode != SZ_FILTER_NO);
if (useFilter) if (useFilter)
{ {
if (srcLen != 0) if (srcLen != 0)
{ {
filteredStream = (Byte *)MyAlloc(srcLen); filteredStream = (Byte *)MyAlloc(srcLen);
if (filteredStream == 0) if (filteredStream == 0)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
memcpy(filteredStream, src, srcLen); memcpy(filteredStream, src, srcLen);
} }
{ {
UInt32 x86State; UInt32 x86State;
x86_Convert_Init(x86State); x86_Convert_Init(x86State);
x86_Convert(filteredStream, srcLen, 0, &x86State, 1); x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
} }
} }
{ {
size_t minSize = 0; size_t minSize = 0;
BoolInt bestIsFiltered = False; BoolInt bestIsFiltered = False;
/* passes for SZ_FILTER_AUTO: /* passes for SZ_FILTER_AUTO:
0 - BCJ + LZMA 0 - BCJ + LZMA
1 - LZMA 1 - LZMA
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
*/ */
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
int i; int i;
for (i = 0; i < numPasses; i++) for (i = 0; i < numPasses; i++)
{ {
size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
size_t outPropsSize = 5; size_t outPropsSize = 5;
SRes curRes; SRes curRes;
BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
if (curModeIsFiltered && !bestIsFiltered) if (curModeIsFiltered && !bestIsFiltered)
break; break;
if (useFilter && i == 0) if (useFilter && i == 0)
curModeIsFiltered = True; curModeIsFiltered = True;
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
curModeIsFiltered ? filteredStream : src, srcLen, curModeIsFiltered ? filteredStream : src, srcLen,
&props, dest + 1, &outPropsSize, 0, &props, dest + 1, &outPropsSize, 0,
NULL, &g_Alloc, &g_Alloc); NULL, &g_Alloc, &g_Alloc);
if (curRes != SZ_ERROR_OUTPUT_EOF) if (curRes != SZ_ERROR_OUTPUT_EOF)
{ {
if (curRes != SZ_OK) if (curRes != SZ_OK)
{ {
mainResult = curRes; mainResult = curRes;
break; break;
} }
if (outSizeProcessed <= minSize || mainResult != SZ_OK) if (outSizeProcessed <= minSize || mainResult != SZ_OK)
{ {
minSize = outSizeProcessed; minSize = outSizeProcessed;
bestIsFiltered = curModeIsFiltered; bestIsFiltered = curModeIsFiltered;
mainResult = SZ_OK; mainResult = SZ_OK;
} }
} }
} }
dest[0] = (Byte)(bestIsFiltered ? 1 : 0); dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
*destLen = LZMA86_HEADER_SIZE + minSize; *destLen = LZMA86_HEADER_SIZE + minSize;
} }
if (useFilter) if (useFilter)
MyFree(filteredStream); MyFree(filteredStream);
return mainResult; return mainResult;
} }

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,234 +1,234 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2018-04-21 : Igor Pavlov : Public domain */ 2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H #ifndef __LZMA_DEC_H
#define __LZMA_DEC_H #define __LZMA_DEC_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* #define _LZMA_PROB32 */ /* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs, /* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */ but memory usage for CLzmaDec::probs will be doubled in that case */
typedef typedef
#ifdef _LZMA_PROB32 #ifdef _LZMA_PROB32
UInt32 UInt32
#else #else
UInt16 UInt16
#endif #endif
CLzmaProb; CLzmaProb;
/* ---------- LZMA Properties ---------- */ /* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5 #define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps typedef struct _CLzmaProps
{ {
Byte lc; Byte lc;
Byte lp; Byte lp;
Byte pb; Byte pb;
Byte _pad_; Byte _pad_;
UInt32 dicSize; UInt32 dicSize;
} CLzmaProps; } CLzmaProps;
/* LzmaProps_Decode - decodes properties /* LzmaProps_Decode - decodes properties
Returns: Returns:
SZ_OK SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */ /* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20 #define LZMA_REQUIRED_INPUT_MAX 20
typedef struct typedef struct
{ {
/* Don't change this structure. ASM code can use it. */ /* Don't change this structure. ASM code can use it. */
CLzmaProps prop; CLzmaProps prop;
CLzmaProb *probs; CLzmaProb *probs;
CLzmaProb *probs_1664; CLzmaProb *probs_1664;
Byte *dic; Byte *dic;
SizeT dicBufSize; SizeT dicBufSize;
SizeT dicPos; SizeT dicPos;
const Byte *buf; const Byte *buf;
UInt32 range; UInt32 range;
UInt32 code; UInt32 code;
UInt32 processedPos; UInt32 processedPos;
UInt32 checkDicSize; UInt32 checkDicSize;
UInt32 reps[4]; UInt32 reps[4];
UInt32 state; UInt32 state;
UInt32 remainLen; UInt32 remainLen;
UInt32 numProbs; UInt32 numProbs;
unsigned tempBufSize; unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; } #define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams: /* There are two types of LZMA streams:
- Stream with end mark. That end mark adds about 6 bytes to compressed size. - Stream with end mark. That end mark adds about 6 bytes to compressed size.
- Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum typedef enum
{ {
LZMA_FINISH_ANY, /* finish at any point */ LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */ LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode; } ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit. and output value of destLen will be less than output buffer size limit.
You can check status result also. You can check status result also.
You can use multiple checks to test data integrity after full decompression: You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable. 1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize. 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */ You must use correct finish mode in that case. */
typedef enum typedef enum
{ {
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus; } ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */ /* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */ /* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces: /* There are 3 levels of interfaces:
1) Dictionary Interface 1) Dictionary Interface
2) Buffer Interface 2) Buffer Interface
3) One Call Interface 3) One Call Interface
You can select any of these interfaces, but don't mix functions from different You can select any of these interfaces, but don't mix functions from different
groups for same object. */ groups for same object. */
/* There are two variants to allocate state for Dictionary Interface: /* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free 1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually. You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1. For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return: LzmaDec_Allocate* can return:
SZ_OK SZ_OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc); SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc); void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */ /* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from /* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer. dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface. You must work with CLzmaDec variables directly in this interface.
STEPS: STEPS:
LzmaDec_Construct() LzmaDec_Construct()
LzmaDec_Allocate() LzmaDec_Allocate()
for (each new stream) for (each new stream)
{ {
LzmaDec_Init() LzmaDec_Init()
while (it needs more decompression) while (it needs more decompression)
{ {
LzmaDec_DecodeToDic() LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos use data from CLzmaDec::dic and update CLzmaDec::dicPos
} }
} }
LzmaDec_Free() LzmaDec_Free()
*/ */
/* LzmaDec_DecodeToDic /* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic). The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (dicLimit). It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes. LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit. LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns: Returns:
SZ_OK SZ_OK
status: status:
LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */ /* ---------- Buffer Interface ---------- */
/* It's zlib-like interface. /* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results, See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually. to work with CLzmaDec variables manually.
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen). It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes. LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen). LZMA_FINISH_END - Stream must be finished after (*destLen).
*/ */
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
/* LzmaDecode /* LzmaDecode
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen). It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes. LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen). LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns: Returns:
SZ_OK SZ_OK
status: status:
LZMA_STATUS_FINISHED_WITH_MARK LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/ */
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAllocPtr alloc); ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,76 +1,76 @@
/* LzmaEnc.h -- LZMA Encoder /* LzmaEnc.h -- LZMA Encoder
2017-07-27 : Igor Pavlov : Public domain */ 2017-07-27 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H #ifndef __LZMA_ENC_H
#define __LZMA_ENC_H #define __LZMA_ENC_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define LZMA_PROPS_SIZE 5 #define LZMA_PROPS_SIZE 5
typedef struct _CLzmaEncProps typedef struct _CLzmaEncProps
{ {
int level; /* 0 <= level <= 9 */ int level; /* 0 <= level <= 9 */
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (3 << 29) for 64-bit version (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
default = (1 << 24) */ default = (1 << 24) */
int lc; /* 0 <= lc <= 8, default = 3 */ int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */ int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */ int pb; /* 0 <= pb <= 4, default = 2 */
int algo; /* 0 - fast, 1 - normal, default = 1 */ int algo; /* 0 - fast, 1 - normal, default = 1 */
int fb; /* 5 <= fb <= 273, default = 32 */ int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */ int numHashBytes; /* 2, 3 or 4, default = 4 */
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */ int numThreads; /* 1 or 2, default = 2 */
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
Encoder uses this value to reduce dictionary size */ Encoder uses this value to reduce dictionary size */
} CLzmaEncProps; } CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p); void LzmaEncProps_Init(CLzmaEncProps *p);
void LzmaEncProps_Normalize(CLzmaEncProps *p); void LzmaEncProps_Normalize(CLzmaEncProps *p);
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */ /* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc* functions can return the following exit codes: /* LzmaEnc* functions can return the following exit codes:
SRes: SRes:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/ */
typedef void * CLzmaEncHandle; typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize); void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,40 +1,40 @@
/* LzmaLib.c -- LZMA library wrapper /* LzmaLib.c -- LZMA library wrapper
2015-06-13 : Igor Pavlov : Public domain */ 2015-06-13 : Igor Pavlov : Public domain */
#include "Alloc.h" #include "Alloc.h"
#include "LzmaDec.h" #include "LzmaDec.h"
#include "LzmaEnc.h" #include "LzmaEnc.h"
#include "LzmaLib.h" #include "LzmaLib.h"
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, unsigned char *outProps, size_t *outPropsSize,
int level, /* 0 <= level <= 9, default = 5 */ int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
int lc, /* 0 <= lc <= 8, default = 3 */ int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */ int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */ int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */ int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */ int numThreads /* 1 or 2, default = 2 */
) )
{ {
CLzmaEncProps props; CLzmaEncProps props;
LzmaEncProps_Init(&props); LzmaEncProps_Init(&props);
props.level = level; props.level = level;
props.dictSize = dictSize; props.dictSize = dictSize;
props.lc = lc; props.lc = lc;
props.lp = lp; props.lp = lp;
props.pb = pb; props.pb = pb;
props.fb = fb; props.fb = fb;
props.numThreads = numThreads; props.numThreads = numThreads;
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
NULL, &g_Alloc, &g_Alloc); NULL, &g_Alloc, &g_Alloc);
} }
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize) const unsigned char *props, size_t propsSize)
{ {
ELzmaStatus status; ELzmaStatus status;
return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
} }

View File

@@ -1,131 +1,131 @@
/* LzmaLib.h -- LZMA library interface /* LzmaLib.h -- LZMA library interface
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_LIB_H #ifndef __LZMA_LIB_H
#define __LZMA_LIB_H #define __LZMA_LIB_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define MY_STDAPI int MY_STD_CALL #define MY_STDAPI int MY_STD_CALL
#define LZMA_PROPS_SIZE 5 #define LZMA_PROPS_SIZE 5
/* /*
RAM requirements for LZMA: RAM requirements for LZMA:
for compression: (dictSize * 11.5 + 6 MB) + state_size for compression: (dictSize * 11.5 + 6 MB) + state_size
for decompression: dictSize + state_size for decompression: dictSize + state_size
state_size = (4 + (1.5 << (lc + lp))) KB state_size = (4 + (1.5 << (lc + lp))) KB
by default (lc=3, lp=0), state_size = 16 KB. by default (lc=3, lp=0), state_size = 16 KB.
LZMA properties (5 bytes) format LZMA properties (5 bytes) format
Offset Size Description Offset Size Description
0 1 lc, lp and pb in encoded form. 0 1 lc, lp and pb in encoded form.
1 4 dictSize (little endian). 1 4 dictSize (little endian).
*/ */
/* /*
LzmaCompress LzmaCompress
------------ ------------
outPropsSize - outPropsSize -
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
LZMA Encoder will use defult values for any parameter, if it is LZMA Encoder will use defult values for any parameter, if it is
-1 for any from: level, loc, lp, pb, fb, numThreads -1 for any from: level, loc, lp, pb, fb, numThreads
0 for dictSize 0 for dictSize
level - compression level: 0 <= level <= 9; level - compression level: 0 <= level <= 9;
level dictSize algo fb level dictSize algo fb
0: 16 KB 0 32 0: 16 KB 0 32
1: 64 KB 0 32 1: 64 KB 0 32
2: 256 KB 0 32 2: 256 KB 0 32
3: 1 MB 0 32 3: 1 MB 0 32
4: 4 MB 0 32 4: 4 MB 0 32
5: 16 MB 1 32 5: 16 MB 1 32
6: 32 MB 1 32 6: 32 MB 1 32
7+: 64 MB 1 64 7+: 64 MB 1 64
The default value for "level" is 5. The default value for "level" is 5.
algo = 0 means fast method algo = 0 means fast method
algo = 1 means normal method algo = 1 means normal method
dictSize - The dictionary size in bytes. The maximum value is dictSize - The dictionary size in bytes. The maximum value is
128 MB = (1 << 27) bytes for 32-bit version 128 MB = (1 << 27) bytes for 32-bit version
1 GB = (1 << 30) bytes for 64-bit version 1 GB = (1 << 30) bytes for 64-bit version
The default value is 16 MB = (1 << 24) bytes. The default value is 16 MB = (1 << 24) bytes.
It's recommended to use the dictionary that is larger than 4 KB and It's recommended to use the dictionary that is larger than 4 KB and
that can be calculated as (1 << N) or (3 << N) sizes. that can be calculated as (1 << N) or (3 << N) sizes.
lc - The number of literal context bits (high bits of previous literal). lc - The number of literal context bits (high bits of previous literal).
It can be in the range from 0 to 8. The default value is 3. It can be in the range from 0 to 8. The default value is 3.
Sometimes lc=4 gives the gain for big files. Sometimes lc=4 gives the gain for big files.
lp - The number of literal pos bits (low bits of current position for literals). lp - The number of literal pos bits (low bits of current position for literals).
It can be in the range from 0 to 4. The default value is 0. It can be in the range from 0 to 4. The default value is 0.
The lp switch is intended for periodical data when the period is equal to 2^lp. The lp switch is intended for periodical data when the period is equal to 2^lp.
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
better to set lc=0, if you change lp switch. better to set lc=0, if you change lp switch.
pb - The number of pos bits (low bits of current position). pb - The number of pos bits (low bits of current position).
It can be in the range from 0 to 4. The default value is 2. It can be in the range from 0 to 4. The default value is 2.
The pb switch is intended for periodical data when the period is equal 2^pb. The pb switch is intended for periodical data when the period is equal 2^pb.
fb - Word size (the number of fast bytes). fb - Word size (the number of fast bytes).
It can be in the range from 5 to 273. The default value is 32. It can be in the range from 5 to 273. The default value is 32.
Usually, a big number gives a little bit better compression ratio and Usually, a big number gives a little bit better compression ratio and
slower compression process. slower compression process.
numThreads - The number of thereads. 1 or 2. The default value is 2. numThreads - The number of thereads. 1 or 2. The default value is 2.
Fast mode (algo = 0) can use only 1 thread. Fast mode (algo = 0) can use only 1 thread.
Out: Out:
destLen - processed output size destLen - processed output size
Returns: Returns:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/ */
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */ int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */ unsigned dictSize, /* default = (1 << 24) */
int lc, /* 0 <= lc <= 8, default = 3 */ int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */ int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */ int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */ int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */ int numThreads /* 1 or 2, default = 2 */
); );
/* /*
LzmaUncompress LzmaUncompress
-------------- --------------
In: In:
dest - output data dest - output data
destLen - output data size destLen - output data size
src - input data src - input data
srcLen - input data size srcLen - input data size
Out: Out:
destLen - processed output size destLen - processed output size
srcLen - processed input size srcLen - processed input size
Returns: Returns:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation arror SZ_ERROR_MEM - Memory allocation arror
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
*/ */
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize); const unsigned char *props, size_t propsSize);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,141 +1,141 @@
/* MtCoder.h -- Multi-thread Coder /* MtCoder.h -- Multi-thread Coder
2018-07-04 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#ifndef __MT_CODER_H #ifndef __MT_CODER_H
#define __MT_CODER_H #define __MT_CODER_H
#include "MtDec.h" #include "MtDec.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* /*
if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream
if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
*/ */
/* #define MTCODER__USE_WRITE_THREAD */ /* #define MTCODER__USE_WRITE_THREAD */
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
#define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1) #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
#define MTCODER__THREADS_MAX 64 #define MTCODER__THREADS_MAX 64
#define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3) #define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3)
#else #else
#define MTCODER__THREADS_MAX 1 #define MTCODER__THREADS_MAX 1
#define MTCODER__BLOCKS_MAX 1 #define MTCODER__BLOCKS_MAX 1
#endif #endif
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
typedef struct typedef struct
{ {
ICompressProgress vt; ICompressProgress vt;
CMtProgress *mtProgress; CMtProgress *mtProgress;
UInt64 inSize; UInt64 inSize;
UInt64 outSize; UInt64 outSize;
} CMtProgressThunk; } CMtProgressThunk;
void MtProgressThunk_CreateVTable(CMtProgressThunk *p); void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; } #define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
struct _CMtCoder; struct _CMtCoder;
typedef struct typedef struct
{ {
struct _CMtCoder *mtCoder; struct _CMtCoder *mtCoder;
unsigned index; unsigned index;
int stop; int stop;
Byte *inBuf; Byte *inBuf;
CAutoResetEvent startEvent; CAutoResetEvent startEvent;
CThread thread; CThread thread;
} CMtCoderThread; } CMtCoderThread;
typedef struct typedef struct
{ {
SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex, SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
const Byte *src, size_t srcSize, int finished); const Byte *src, size_t srcSize, int finished);
SRes (*Write)(void *p, unsigned outBufIndex); SRes (*Write)(void *p, unsigned outBufIndex);
} IMtCoderCallback2; } IMtCoderCallback2;
typedef struct typedef struct
{ {
SRes res; SRes res;
unsigned bufIndex; unsigned bufIndex;
BoolInt finished; BoolInt finished;
} CMtCoderBlock; } CMtCoderBlock;
typedef struct _CMtCoder typedef struct _CMtCoder
{ {
/* input variables */ /* input variables */
size_t blockSize; /* size of input block */ size_t blockSize; /* size of input block */
unsigned numThreadsMax; unsigned numThreadsMax;
UInt64 expectedDataSize; UInt64 expectedDataSize;
ISeqInStream *inStream; ISeqInStream *inStream;
const Byte *inData; const Byte *inData;
size_t inDataSize; size_t inDataSize;
ICompressProgress *progress; ICompressProgress *progress;
ISzAllocPtr allocBig; ISzAllocPtr allocBig;
IMtCoderCallback2 *mtCallback; IMtCoderCallback2 *mtCallback;
void *mtCallbackObject; void *mtCallbackObject;
/* internal variables */ /* internal variables */
size_t allocatedBufsSize; size_t allocatedBufsSize;
CAutoResetEvent readEvent; CAutoResetEvent readEvent;
CSemaphore blocksSemaphore; CSemaphore blocksSemaphore;
BoolInt stopReading; BoolInt stopReading;
SRes readRes; SRes readRes;
#ifdef MTCODER__USE_WRITE_THREAD #ifdef MTCODER__USE_WRITE_THREAD
CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX]; CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX];
#else #else
CAutoResetEvent finishedEvent; CAutoResetEvent finishedEvent;
SRes writeRes; SRes writeRes;
unsigned writeIndex; unsigned writeIndex;
Byte ReadyBlocks[MTCODER__BLOCKS_MAX]; Byte ReadyBlocks[MTCODER__BLOCKS_MAX];
LONG numFinishedThreads; LONG numFinishedThreads;
#endif #endif
unsigned numStartedThreadsLimit; unsigned numStartedThreadsLimit;
unsigned numStartedThreads; unsigned numStartedThreads;
unsigned numBlocksMax; unsigned numBlocksMax;
unsigned blockIndex; unsigned blockIndex;
UInt64 readProcessed; UInt64 readProcessed;
CCriticalSection cs; CCriticalSection cs;
unsigned freeBlockHead; unsigned freeBlockHead;
unsigned freeBlockList[MTCODER__BLOCKS_MAX]; unsigned freeBlockList[MTCODER__BLOCKS_MAX];
CMtProgress mtProgress; CMtProgress mtProgress;
CMtCoderBlock blocks[MTCODER__BLOCKS_MAX]; CMtCoderBlock blocks[MTCODER__BLOCKS_MAX];
CMtCoderThread threads[MTCODER__THREADS_MAX]; CMtCoderThread threads[MTCODER__THREADS_MAX];
} CMtCoder; } CMtCoder;
void MtCoder_Construct(CMtCoder *p); void MtCoder_Construct(CMtCoder *p);
void MtCoder_Destruct(CMtCoder *p); void MtCoder_Destruct(CMtCoder *p);
SRes MtCoder_Code(CMtCoder *p); SRes MtCoder_Code(CMtCoder *p);
#endif #endif
EXTERN_C_END EXTERN_C_END
#endif #endif

2276
C/MtDec.c
View File

File diff suppressed because it is too large Load Diff

402
C/MtDec.h
View File

@@ -1,201 +1,201 @@
/* MtDec.h -- Multi-thread Decoder /* MtDec.h -- Multi-thread Decoder
2018-07-04 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#ifndef __MT_DEC_H #ifndef __MT_DEC_H
#define __MT_DEC_H #define __MT_DEC_H
#include "7zTypes.h" #include "7zTypes.h"
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
#include "Threads.h" #include "Threads.h"
#endif #endif
EXTERN_C_BEGIN EXTERN_C_BEGIN
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
#define MTDEC__THREADS_MAX 32 #define MTDEC__THREADS_MAX 32
#else #else
#define MTDEC__THREADS_MAX 1 #define MTDEC__THREADS_MAX 1
#endif #endif
typedef struct typedef struct
{ {
ICompressProgress *progress; ICompressProgress *progress;
SRes res; SRes res;
UInt64 totalInSize; UInt64 totalInSize;
UInt64 totalOutSize; UInt64 totalOutSize;
CCriticalSection cs; CCriticalSection cs;
} CMtProgress; } CMtProgress;
void MtProgress_Init(CMtProgress *p, ICompressProgress *progress); void MtProgress_Init(CMtProgress *p, ICompressProgress *progress);
SRes MtProgress_Progress_ST(CMtProgress *p); SRes MtProgress_Progress_ST(CMtProgress *p);
SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize); SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);
SRes MtProgress_GetError(CMtProgress *p); SRes MtProgress_GetError(CMtProgress *p);
void MtProgress_SetError(CMtProgress *p, SRes res); void MtProgress_SetError(CMtProgress *p, SRes res);
struct _CMtDec; struct _CMtDec;
typedef struct typedef struct
{ {
struct _CMtDec *mtDec; struct _CMtDec *mtDec;
unsigned index; unsigned index;
void *inBuf; void *inBuf;
size_t inDataSize_Start; // size of input data in start block size_t inDataSize_Start; // size of input data in start block
UInt64 inDataSize; // total size of input data in all blocks UInt64 inDataSize; // total size of input data in all blocks
CThread thread; CThread thread;
CAutoResetEvent canRead; CAutoResetEvent canRead;
CAutoResetEvent canWrite; CAutoResetEvent canWrite;
void *allocaPtr; void *allocaPtr;
} CMtDecThread; } CMtDecThread;
void MtDecThread_FreeInBufs(CMtDecThread *t); void MtDecThread_FreeInBufs(CMtDecThread *t);
typedef enum typedef enum
{ {
MTDEC_PARSE_CONTINUE, // continue this block with more input data MTDEC_PARSE_CONTINUE, // continue this block with more input data
MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread
MTDEC_PARSE_NEW, // new block MTDEC_PARSE_NEW, // new block
MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue) MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue)
} EMtDecParseState; } EMtDecParseState;
typedef struct typedef struct
{ {
// in // in
int startCall; int startCall;
const Byte *src; const Byte *src;
size_t srcSize; size_t srcSize;
// in : (srcSize == 0) is allowed // in : (srcSize == 0) is allowed
// out : it's allowed to return less that actually was used ? // out : it's allowed to return less that actually was used ?
int srcFinished; int srcFinished;
// out // out
EMtDecParseState state; EMtDecParseState state;
BoolInt canCreateNewThread; BoolInt canCreateNewThread;
UInt64 outPos; // check it (size_t) UInt64 outPos; // check it (size_t)
} CMtDecCallbackInfo; } CMtDecCallbackInfo;
typedef struct typedef struct
{ {
void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci); void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);
// PreCode() and Code(): // PreCode() and Code():
// (SRes_return_result != SZ_OK) means stop decoding, no need another blocks // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
SRes (*PreCode)(void *p, unsigned coderIndex); SRes (*PreCode)(void *p, unsigned coderIndex);
SRes (*Code)(void *p, unsigned coderIndex, SRes (*Code)(void *p, unsigned coderIndex,
const Byte *src, size_t srcSize, int srcFinished, const Byte *src, size_t srcSize, int srcFinished,
UInt64 *inCodePos, UInt64 *outCodePos, int *stop); UInt64 *inCodePos, UInt64 *outCodePos, int *stop);
// stop - means stop another Code calls // stop - means stop another Code calls
/* Write() must be called, if Parse() was called /* Write() must be called, if Parse() was called
set (needWrite) if set (needWrite) if
{ {
&& (was not interrupted by progress) && (was not interrupted by progress)
&& (was not interrupted in previous block) && (was not interrupted in previous block)
} }
out: out:
if (*needContinue), decoder still need to continue decoding with new iteration, if (*needContinue), decoder still need to continue decoding with new iteration,
even after MTDEC_PARSE_END even after MTDEC_PARSE_END
if (*canRecode), we didn't flush current block data, so we still can decode current block later. if (*canRecode), we didn't flush current block data, so we still can decode current block later.
*/ */
SRes (*Write)(void *p, unsigned coderIndex, SRes (*Write)(void *p, unsigned coderIndex,
BoolInt needWriteToStream, BoolInt needWriteToStream,
const Byte *src, size_t srcSize, const Byte *src, size_t srcSize,
// int srcFinished, // int srcFinished,
BoolInt *needContinue, BoolInt *needContinue,
BoolInt *canRecode); BoolInt *canRecode);
} IMtDecCallback; } IMtDecCallback;
typedef struct _CMtDec typedef struct _CMtDec
{ {
/* input variables */ /* input variables */
size_t inBufSize; /* size of input block */ size_t inBufSize; /* size of input block */
unsigned numThreadsMax; unsigned numThreadsMax;
// size_t inBlockMax; // size_t inBlockMax;
unsigned numThreadsMax_2; unsigned numThreadsMax_2;
ISeqInStream *inStream; ISeqInStream *inStream;
// const Byte *inData; // const Byte *inData;
// size_t inDataSize; // size_t inDataSize;
ICompressProgress *progress; ICompressProgress *progress;
ISzAllocPtr alloc; ISzAllocPtr alloc;
IMtDecCallback *mtCallback; IMtDecCallback *mtCallback;
void *mtCallbackObject; void *mtCallbackObject;
/* internal variables */ /* internal variables */
size_t allocatedBufsSize; size_t allocatedBufsSize;
BoolInt exitThread; BoolInt exitThread;
WRes exitThreadWRes; WRes exitThreadWRes;
UInt64 blockIndex; UInt64 blockIndex;
BoolInt isAllocError; BoolInt isAllocError;
BoolInt overflow; BoolInt overflow;
SRes threadingErrorSRes; SRes threadingErrorSRes;
BoolInt needContinue; BoolInt needContinue;
// CAutoResetEvent finishedEvent; // CAutoResetEvent finishedEvent;
SRes readRes; SRes readRes;
SRes codeRes; SRes codeRes;
BoolInt wasInterrupted; BoolInt wasInterrupted;
unsigned numStartedThreads_Limit; unsigned numStartedThreads_Limit;
unsigned numStartedThreads; unsigned numStartedThreads;
Byte *crossBlock; Byte *crossBlock;
size_t crossStart; size_t crossStart;
size_t crossEnd; size_t crossEnd;
UInt64 readProcessed; UInt64 readProcessed;
BoolInt readWasFinished; BoolInt readWasFinished;
UInt64 inProcessed; UInt64 inProcessed;
unsigned filledThreadStart; unsigned filledThreadStart;
unsigned numFilledThreads; unsigned numFilledThreads;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
BoolInt needInterrupt; BoolInt needInterrupt;
UInt64 interruptIndex; UInt64 interruptIndex;
CMtProgress mtProgress; CMtProgress mtProgress;
CMtDecThread threads[MTDEC__THREADS_MAX]; CMtDecThread threads[MTDEC__THREADS_MAX];
#endif #endif
} CMtDec; } CMtDec;
void MtDec_Construct(CMtDec *p); void MtDec_Construct(CMtDec *p);
void MtDec_Destruct(CMtDec *p); void MtDec_Destruct(CMtDec *p);
/* /*
MtDec_Code() returns: MtDec_Code() returns:
SZ_OK - in most cases SZ_OK - in most cases
MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
*/ */
SRes MtDec_Code(CMtDec *p); SRes MtDec_Code(CMtDec *p);
Byte *MtDec_GetCrossBuff(CMtDec *p); Byte *MtDec_GetCrossBuff(CMtDec *p);
int MtDec_PrepareRead(CMtDec *p); int MtDec_PrepareRead(CMtDec *p);
const Byte *MtDec_Read(CMtDec *p, size_t *inLim); const Byte *MtDec_Read(CMtDec *p, size_t *inLim);
#endif #endif
EXTERN_C_END EXTERN_C_END
#endif #endif

170
C/Ppmd.h
View File

@@ -1,85 +1,85 @@
/* Ppmd.h -- PPMD codec common code /* Ppmd.h -- PPMD codec common code
2017-04-03 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
#define __PPMD_H #define __PPMD_H
#include "CpuArch.h" #include "CpuArch.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#ifdef MY_CPU_32BIT #ifdef MY_CPU_32BIT
#define PPMD_32BIT #define PPMD_32BIT
#endif #endif
#define PPMD_INT_BITS 7 #define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7 #define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) #define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) #define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) #define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) #define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) #define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
#define PPMD_N1 4 #define PPMD_N1 4
#define PPMD_N2 4 #define PPMD_N2 4
#define PPMD_N3 4 #define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) #define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) #define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
#pragma pack(push, 1) #pragma pack(push, 1)
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */ /* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
/* SEE-contexts for PPM-contexts with masked symbols */ /* SEE-contexts for PPM-contexts with masked symbols */
typedef struct typedef struct
{ {
UInt16 Summ; /* Freq */ UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */ Byte Shift; /* Speed of Freq change; low Shift is for fast change */
Byte Count; /* Count to next change of Shift */ Byte Count; /* Count to next change of Shift */
} CPpmd_See; } CPpmd_See;
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ #define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
typedef struct typedef struct
{ {
Byte Symbol; Byte Symbol;
Byte Freq; Byte Freq;
UInt16 SuccessorLow; UInt16 SuccessorLow;
UInt16 SuccessorHigh; UInt16 SuccessorHigh;
} CPpmd_State; } CPpmd_State;
#pragma pack(pop) #pragma pack(pop)
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
CPpmd_State * CPpmd_State *
#else #else
UInt32 UInt32
#endif #endif
CPpmd_State_Ref; CPpmd_State_Ref;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
void * void *
#else #else
UInt32 UInt32
#endif #endif
CPpmd_Void_Ref; CPpmd_Void_Ref;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
Byte * Byte *
#else #else
UInt32 UInt32
#endif #endif
CPpmd_Byte_Ref; CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \ #define PPMD_SetAllBitsIn256Bytes(p) \
{ size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \ { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }} p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END EXTERN_C_END
#endif #endif

1424
C/Ppmd7.c
View File

File diff suppressed because it is too large Load Diff

284
C/Ppmd7.h
View File

@@ -1,142 +1,142 @@
/* Ppmd7.h -- PPMdH compression codec /* Ppmd7.h -- PPMdH compression codec
2018-07-04 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation /* This code supports virtual RangeDecoder and includes the implementation
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef __PPMD7_H #ifndef __PPMD7_H
#define __PPMD7_H #define __PPMD7_H
#include "Ppmd.h" #include "Ppmd.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define PPMD7_MIN_ORDER 2 #define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64 #define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11) #define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) #define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_; struct CPpmd7_Context_;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
struct CPpmd7_Context_ * struct CPpmd7_Context_ *
#else #else
UInt32 UInt32
#endif #endif
CPpmd7_Context_Ref; CPpmd7_Context_Ref;
typedef struct CPpmd7_Context_ typedef struct CPpmd7_Context_
{ {
UInt16 NumStats; UInt16 NumStats;
UInt16 SummFreq; UInt16 SummFreq;
CPpmd_State_Ref Stats; CPpmd_State_Ref Stats;
CPpmd7_Context_Ref Suffix; CPpmd7_Context_Ref Suffix;
} CPpmd7_Context; } CPpmd7_Context;
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) #define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
typedef struct typedef struct
{ {
CPpmd7_Context *MinContext, *MaxContext; CPpmd7_Context *MinContext, *MaxContext;
CPpmd_State *FoundState; CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
Int32 RunLength, InitRL; /* must be 32-bit at least */ Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size; UInt32 Size;
UInt32 GlueCount; UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 AlignOffset; UInt32 AlignOffset;
Byte Indx2Units[PPMD_NUM_INDEXES]; Byte Indx2Units[PPMD_NUM_INDEXES];
Byte Units2Indx[128]; Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
CPpmd_See DummySee, See[25][16]; CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64]; UInt16 BinSumm[128][64];
} CPpmd7; } CPpmd7;
void Ppmd7_Construct(CPpmd7 *p); void Ppmd7_Construct(CPpmd7 *p);
BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc); BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc); void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
/* ---------- Internal Functions ---------- */ /* ---------- Internal Functions ---------- */
extern const Byte PPMD7_kExpEscape[16]; extern const Byte PPMD7_kExpEscape[16];
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
#define Ppmd7_GetPtr(p, ptr) (ptr) #define Ppmd7_GetPtr(p, ptr) (ptr)
#define Ppmd7_GetContext(p, ptr) (ptr) #define Ppmd7_GetContext(p, ptr) (ptr)
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
#else #else
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
#endif #endif
void Ppmd7_Update1(CPpmd7 *p); void Ppmd7_Update1(CPpmd7 *p);
void Ppmd7_Update1_0(CPpmd7 *p); void Ppmd7_Update1_0(CPpmd7 *p);
void Ppmd7_Update2(CPpmd7 *p); void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p); void Ppmd7_UpdateBin(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \ #define Ppmd7_GetBinSumm(p) \
&p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \ 2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
((p->RunLength >> 26) & 0x20)] ((p->RunLength >> 26) & 0x20)]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */ /* ---------- Decode ---------- */
typedef struct IPpmd7_RangeDec IPpmd7_RangeDec; typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
struct IPpmd7_RangeDec struct IPpmd7_RangeDec
{ {
UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total); UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size); void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0); UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
}; };
typedef struct typedef struct
{ {
IPpmd7_RangeDec vt; IPpmd7_RangeDec vt;
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
IByteIn *Stream; IByteIn *Stream;
} CPpmd7z_RangeDec; } CPpmd7z_RangeDec;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc); int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
/* ---------- Encode ---------- */ /* ---------- Encode ---------- */
typedef struct typedef struct
{ {
UInt64 Low; UInt64 Low;
UInt32 Range; UInt32 Range;
Byte Cache; Byte Cache;
UInt64 CacheSize; UInt64 CacheSize;
IByteOut *Stream; IByteOut *Stream;
} CPpmd7z_RangeEnc; } CPpmd7z_RangeEnc;
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,191 +1,191 @@
/* Ppmd7Dec.c -- PPMdH Decoder /* Ppmd7Dec.c -- PPMdH Decoder
2018-07-04 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Ppmd7.h" #include "Ppmd7.h"
#define kTopValue (1 << 24) #define kTopValue (1 << 24)
BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
{ {
unsigned i; unsigned i;
p->Code = 0; p->Code = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
if (IByteIn_Read(p->Stream) != 0) if (IByteIn_Read(p->Stream) != 0)
return False; return False;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
return (p->Code < 0xFFFFFFFF); return (p->Code < 0xFFFFFFFF);
} }
#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt); #define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total) static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
{ {
GET_Ppmd7z_RangeDec GET_Ppmd7z_RangeDec
return p->Code / (p->Range /= total); return p->Code / (p->Range /= total);
} }
static void Range_Normalize(CPpmd7z_RangeDec *p) static void Range_Normalize(CPpmd7z_RangeDec *p)
{ {
if (p->Range < kTopValue) if (p->Range < kTopValue)
{ {
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8; p->Range <<= 8;
if (p->Range < kTopValue) if (p->Range < kTopValue)
{ {
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8; p->Range <<= 8;
} }
} }
} }
static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size) static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
{ {
GET_Ppmd7z_RangeDec GET_Ppmd7z_RangeDec
p->Code -= start * p->Range; p->Code -= start * p->Range;
p->Range *= size; p->Range *= size;
Range_Normalize(p); Range_Normalize(p);
} }
static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0) static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
{ {
GET_Ppmd7z_RangeDec GET_Ppmd7z_RangeDec
UInt32 newBound = (p->Range >> 14) * size0; UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol; UInt32 symbol;
if (p->Code < newBound) if (p->Code < newBound)
{ {
symbol = 0; symbol = 0;
p->Range = newBound; p->Range = newBound;
} }
else else
{ {
symbol = 1; symbol = 1;
p->Code -= newBound; p->Code -= newBound;
p->Range -= newBound; p->Range -= newBound;
} }
Range_Normalize(p); Range_Normalize(p);
return symbol; return symbol;
} }
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{ {
p->vt.GetThreshold = Range_GetThreshold; p->vt.GetThreshold = Range_GetThreshold;
p->vt.Decode = Range_Decode; p->vt.Decode = Range_Decode;
p->vt.DecodeBit = Range_DecodeBit; p->vt.DecodeBit = Range_DecodeBit;
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc) int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1) if (p->MinContext->NumStats != 1)
{ {
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
unsigned i; unsigned i;
UInt32 count, hiCnt; UInt32 count, hiCnt;
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
{ {
Byte symbol; Byte symbol;
rc->Decode(rc, 0, s->Freq); rc->Decode(rc, 0, s->Freq);
p->FoundState = s; p->FoundState = s;
symbol = s->Symbol; symbol = s->Symbol;
Ppmd7_Update1_0(p); Ppmd7_Update1_0(p);
return symbol; return symbol;
} }
p->PrevSuccess = 0; p->PrevSuccess = 0;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do do
{ {
if ((hiCnt += (++s)->Freq) > count) if ((hiCnt += (++s)->Freq) > count)
{ {
Byte symbol; Byte symbol;
rc->Decode(rc, hiCnt - s->Freq, s->Freq); rc->Decode(rc, hiCnt - s->Freq, s->Freq);
p->FoundState = s; p->FoundState = s;
symbol = s->Symbol; symbol = s->Symbol;
Ppmd7_Update1(p); Ppmd7_Update1(p);
return symbol; return symbol;
} }
} }
while (--i); while (--i);
if (count >= p->MinContext->SummFreq) if (count >= p->MinContext->SummFreq)
return -2; return -2;
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do { MASK((--s)->Symbol) = 0; } while (--i); do { MASK((--s)->Symbol) = 0; } while (--i);
} }
else else
{ {
UInt16 *prob = Ppmd7_GetBinSumm(p); UInt16 *prob = Ppmd7_GetBinSumm(p);
if (rc->DecodeBit(rc, *prob) == 0) if (rc->DecodeBit(rc, *prob) == 0)
{ {
Byte symbol; Byte symbol;
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
Ppmd7_UpdateBin(p); Ppmd7_UpdateBin(p);
return symbol; return symbol;
} }
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
p->PrevSuccess = 0; p->PrevSuccess = 0;
} }
for (;;) for (;;)
{ {
CPpmd_State *ps[256], *s; CPpmd_State *ps[256], *s;
UInt32 freqSum, count, hiCnt; UInt32 freqSum, count, hiCnt;
CPpmd_See *see; CPpmd_See *see;
unsigned i, num, numMasked = p->MinContext->NumStats; unsigned i, num, numMasked = p->MinContext->NumStats;
do do
{ {
p->OrderFall++; p->OrderFall++;
if (!p->MinContext->Suffix) if (!p->MinContext->Suffix)
return -1; return -1;
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
} }
while (p->MinContext->NumStats == numMasked); while (p->MinContext->NumStats == numMasked);
hiCnt = 0; hiCnt = 0;
s = Ppmd7_GetStats(p, p->MinContext); s = Ppmd7_GetStats(p, p->MinContext);
i = 0; i = 0;
num = p->MinContext->NumStats - numMasked; num = p->MinContext->NumStats - numMasked;
do do
{ {
int k = (int)(MASK(s->Symbol)); int k = (int)(MASK(s->Symbol));
hiCnt += (s->Freq & k); hiCnt += (s->Freq & k);
ps[i] = s++; ps[i] = s++;
i -= k; i -= k;
} }
while (i != num); while (i != num);
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
freqSum += hiCnt; freqSum += hiCnt;
count = rc->GetThreshold(rc, freqSum); count = rc->GetThreshold(rc, freqSum);
if (count < hiCnt) if (count < hiCnt)
{ {
Byte symbol; Byte symbol;
CPpmd_State **pps = ps; CPpmd_State **pps = ps;
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
s = *pps; s = *pps;
rc->Decode(rc, hiCnt - s->Freq, s->Freq); rc->Decode(rc, hiCnt - s->Freq, s->Freq);
Ppmd_See_Update(see); Ppmd_See_Update(see);
p->FoundState = s; p->FoundState = s;
symbol = s->Symbol; symbol = s->Symbol;
Ppmd7_Update2(p); Ppmd7_Update2(p);
return symbol; return symbol;
} }
if (count >= freqSum) if (count >= freqSum)
return -2; return -2;
rc->Decode(rc, hiCnt, freqSum - hiCnt); rc->Decode(rc, hiCnt, freqSum - hiCnt);
see->Summ = (UInt16)(see->Summ + freqSum); see->Summ = (UInt16)(see->Summ + freqSum);
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
} }
} }

View File

@@ -1,187 +1,187 @@
/* Ppmd7Enc.c -- PPMdH Encoder /* Ppmd7Enc.c -- PPMdH Encoder
2017-04-03 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Ppmd7.h" #include "Ppmd7.h"
#define kTopValue (1 << 24) #define kTopValue (1 << 24)
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p) void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
{ {
p->Low = 0; p->Low = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
p->Cache = 0; p->Cache = 0;
p->CacheSize = 1; p->CacheSize = 1;
} }
static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
{ {
if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0) if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
{ {
Byte temp = p->Cache; Byte temp = p->Cache;
do do
{ {
IByteOut_Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); IByteOut_Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF; temp = 0xFF;
} }
while (--p->CacheSize != 0); while (--p->CacheSize != 0);
p->Cache = (Byte)((UInt32)p->Low >> 24); p->Cache = (Byte)((UInt32)p->Low >> 24);
} }
p->CacheSize++; p->CacheSize++;
p->Low = (UInt32)p->Low << 8; p->Low = (UInt32)p->Low << 8;
} }
static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total) static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
{ {
p->Low += start * (p->Range /= total); p->Low += start * (p->Range /= total);
p->Range *= size; p->Range *= size;
while (p->Range < kTopValue) while (p->Range < kTopValue)
{ {
p->Range <<= 8; p->Range <<= 8;
RangeEnc_ShiftLow(p); RangeEnc_ShiftLow(p);
} }
} }
static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0) static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
{ {
p->Range = (p->Range >> 14) * size0; p->Range = (p->Range >> 14) * size0;
while (p->Range < kTopValue) while (p->Range < kTopValue)
{ {
p->Range <<= 8; p->Range <<= 8;
RangeEnc_ShiftLow(p); RangeEnc_ShiftLow(p);
} }
} }
static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0) static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
{ {
UInt32 newBound = (p->Range >> 14) * size0; UInt32 newBound = (p->Range >> 14) * size0;
p->Low += newBound; p->Low += newBound;
p->Range -= newBound; p->Range -= newBound;
while (p->Range < kTopValue) while (p->Range < kTopValue)
{ {
p->Range <<= 8; p->Range <<= 8;
RangeEnc_ShiftLow(p); RangeEnc_ShiftLow(p);
} }
} }
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p) void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
RangeEnc_ShiftLow(p); RangeEnc_ShiftLow(p);
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol) void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1) if (p->MinContext->NumStats != 1)
{ {
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
UInt32 sum; UInt32 sum;
unsigned i; unsigned i;
if (s->Symbol == symbol) if (s->Symbol == symbol)
{ {
RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq); RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
p->FoundState = s; p->FoundState = s;
Ppmd7_Update1_0(p); Ppmd7_Update1_0(p);
return; return;
} }
p->PrevSuccess = 0; p->PrevSuccess = 0;
sum = s->Freq; sum = s->Freq;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do do
{ {
if ((++s)->Symbol == symbol) if ((++s)->Symbol == symbol)
{ {
RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq); RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
p->FoundState = s; p->FoundState = s;
Ppmd7_Update1(p); Ppmd7_Update1(p);
return; return;
} }
sum += s->Freq; sum += s->Freq;
} }
while (--i); while (--i);
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do { MASK((--s)->Symbol) = 0; } while (--i); do { MASK((--s)->Symbol) = 0; } while (--i);
RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
} }
else else
{ {
UInt16 *prob = Ppmd7_GetBinSumm(p); UInt16 *prob = Ppmd7_GetBinSumm(p);
CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
if (s->Symbol == symbol) if (s->Symbol == symbol)
{ {
RangeEnc_EncodeBit_0(rc, *prob); RangeEnc_EncodeBit_0(rc, *prob);
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
p->FoundState = s; p->FoundState = s;
Ppmd7_UpdateBin(p); Ppmd7_UpdateBin(p);
return; return;
} }
else else
{ {
RangeEnc_EncodeBit_1(rc, *prob); RangeEnc_EncodeBit_1(rc, *prob);
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
p->PrevSuccess = 0; p->PrevSuccess = 0;
} }
} }
for (;;) for (;;)
{ {
UInt32 escFreq; UInt32 escFreq;
CPpmd_See *see; CPpmd_See *see;
CPpmd_State *s; CPpmd_State *s;
UInt32 sum; UInt32 sum;
unsigned i, numMasked = p->MinContext->NumStats; unsigned i, numMasked = p->MinContext->NumStats;
do do
{ {
p->OrderFall++; p->OrderFall++;
if (!p->MinContext->Suffix) if (!p->MinContext->Suffix)
return; /* EndMarker (symbol = -1) */ return; /* EndMarker (symbol = -1) */
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
} }
while (p->MinContext->NumStats == numMasked); while (p->MinContext->NumStats == numMasked);
see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
s = Ppmd7_GetStats(p, p->MinContext); s = Ppmd7_GetStats(p, p->MinContext);
sum = 0; sum = 0;
i = p->MinContext->NumStats; i = p->MinContext->NumStats;
do do
{ {
int cur = s->Symbol; int cur = s->Symbol;
if (cur == symbol) if (cur == symbol)
{ {
UInt32 low = sum; UInt32 low = sum;
CPpmd_State *s1 = s; CPpmd_State *s1 = s;
do do
{ {
sum += (s->Freq & (int)(MASK(s->Symbol))); sum += (s->Freq & (int)(MASK(s->Symbol)));
s++; s++;
} }
while (--i); while (--i);
RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq); RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
Ppmd_See_Update(see); Ppmd_See_Update(see);
p->FoundState = s1; p->FoundState = s1;
Ppmd7_Update2(p); Ppmd7_Update2(p);
return; return;
} }
sum += (s->Freq & (int)(MASK(cur))); sum += (s->Freq & (int)(MASK(cur)));
MASK(cur) = 0; MASK(cur) = 0;
s++; s++;
} }
while (--i); while (--i);
RangeEnc_Encode(rc, sum, escFreq, sum + escFreq); RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
see->Summ = (UInt16)(see->Summ + sum + escFreq); see->Summ = (UInt16)(see->Summ + sum + escFreq);
} }
} }

2246
C/Ppmd8.c
View File

File diff suppressed because it is too large Load Diff

274
C/Ppmd8.h
View File

@@ -1,137 +1,137 @@
/* Ppmd8.h -- PPMdI codec /* Ppmd8.h -- PPMdI codec
2018-07-04 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#ifndef __PPMD8_H #ifndef __PPMD8_H
#define __PPMD8_H #define __PPMD8_H
#include "Ppmd.h" #include "Ppmd.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define PPMD8_MIN_ORDER 2 #define PPMD8_MIN_ORDER 2
#define PPMD8_MAX_ORDER 16 #define PPMD8_MAX_ORDER 16
struct CPpmd8_Context_; struct CPpmd8_Context_;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
struct CPpmd8_Context_ * struct CPpmd8_Context_ *
#else #else
UInt32 UInt32
#endif #endif
CPpmd8_Context_Ref; CPpmd8_Context_Ref;
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct CPpmd8_Context_ typedef struct CPpmd8_Context_
{ {
Byte NumStats; Byte NumStats;
Byte Flags; Byte Flags;
UInt16 SummFreq; UInt16 SummFreq;
CPpmd_State_Ref Stats; CPpmd_State_Ref Stats;
CPpmd8_Context_Ref Suffix; CPpmd8_Context_Ref Suffix;
} CPpmd8_Context; } CPpmd8_Context;
#pragma pack(pop) #pragma pack(pop)
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) #define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed /* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
code is not compatible with original code for some files compressed code is not compatible with original code for some files compressed
in FREEZE mode. So we disable FREEZE mode support. */ in FREEZE mode. So we disable FREEZE mode support. */
enum enum
{ {
PPMD8_RESTORE_METHOD_RESTART, PPMD8_RESTORE_METHOD_RESTART,
PPMD8_RESTORE_METHOD_CUT_OFF PPMD8_RESTORE_METHOD_CUT_OFF
#ifdef PPMD8_FREEZE_SUPPORT #ifdef PPMD8_FREEZE_SUPPORT
, PPMD8_RESTORE_METHOD_FREEZE , PPMD8_RESTORE_METHOD_FREEZE
#endif #endif
}; };
typedef struct typedef struct
{ {
CPpmd8_Context *MinContext, *MaxContext; CPpmd8_Context *MinContext, *MaxContext;
CPpmd_State *FoundState; CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder; unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder;
Int32 RunLength, InitRL; /* must be 32-bit at least */ Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size; UInt32 Size;
UInt32 GlueCount; UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 AlignOffset; UInt32 AlignOffset;
unsigned RestoreMethod; unsigned RestoreMethod;
/* Range Coder */ /* Range Coder */
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
UInt32 Low; UInt32 Low;
union union
{ {
IByteIn *In; IByteIn *In;
IByteOut *Out; IByteOut *Out;
} Stream; } Stream;
Byte Indx2Units[PPMD_NUM_INDEXES]; Byte Indx2Units[PPMD_NUM_INDEXES];
Byte Units2Indx[128]; Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
UInt32 Stamps[PPMD_NUM_INDEXES]; UInt32 Stamps[PPMD_NUM_INDEXES];
Byte NS2BSIndx[256], NS2Indx[260]; Byte NS2BSIndx[256], NS2Indx[260];
CPpmd_See DummySee, See[24][32]; CPpmd_See DummySee, See[24][32];
UInt16 BinSumm[25][64]; UInt16 BinSumm[25][64];
} CPpmd8; } CPpmd8;
void Ppmd8_Construct(CPpmd8 *p); void Ppmd8_Construct(CPpmd8 *p);
BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc); BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc); void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL) #define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
/* ---------- Internal Functions ---------- */ /* ---------- Internal Functions ---------- */
extern const Byte PPMD8_kExpEscape[16]; extern const Byte PPMD8_kExpEscape[16];
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
#define Ppmd8_GetPtr(p, ptr) (ptr) #define Ppmd8_GetPtr(p, ptr) (ptr)
#define Ppmd8_GetContext(p, ptr) (ptr) #define Ppmd8_GetContext(p, ptr) (ptr)
#define Ppmd8_GetStats(p, ctx) ((ctx)->Stats) #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats)
#else #else
#define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs))) #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
#define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs))) #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs)))
#define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats))) #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats)))
#endif #endif
void Ppmd8_Update1(CPpmd8 *p); void Ppmd8_Update1(CPpmd8 *p);
void Ppmd8_Update1_0(CPpmd8 *p); void Ppmd8_Update1_0(CPpmd8 *p);
void Ppmd8_Update2(CPpmd8 *p); void Ppmd8_Update2(CPpmd8 *p);
void Ppmd8_UpdateBin(CPpmd8 *p); void Ppmd8_UpdateBin(CPpmd8 *p);
#define Ppmd8_GetBinSumm(p) \ #define Ppmd8_GetBinSumm(p) \
&p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \ &p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)] p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale); CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */ /* ---------- Decode ---------- */
BoolInt Ppmd8_RangeDec_Init(CPpmd8 *p); BoolInt Ppmd8_RangeDec_Init(CPpmd8 *p);
#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) #define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */ int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */
/* ---------- Encode ---------- */ /* ---------- Encode ---------- */
#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; } #define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
void Ppmd8_RangeEnc_FlushData(CPpmd8 *p); void Ppmd8_RangeEnc_FlushData(CPpmd8 *p);
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */ void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,157 +1,157 @@
/* Ppmd8Dec.c -- PPMdI Decoder /* Ppmd8Dec.c -- PPMdI Decoder
2018-07-04 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Ppmd8.h" #include "Ppmd8.h"
#define kTop (1 << 24) #define kTop (1 << 24)
#define kBot (1 << 15) #define kBot (1 << 15)
BoolInt Ppmd8_RangeDec_Init(CPpmd8 *p) BoolInt Ppmd8_RangeDec_Init(CPpmd8 *p)
{ {
unsigned i; unsigned i;
p->Low = 0; p->Low = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
p->Code = 0; p->Code = 0;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
return (p->Code < 0xFFFFFFFF); return (p->Code < 0xFFFFFFFF);
} }
static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total) static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total)
{ {
return p->Code / (p->Range /= total); return p->Code / (p->Range /= total);
} }
static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size) static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
{ {
start *= p->Range; start *= p->Range;
p->Low += start; p->Low += start;
p->Code -= start; p->Code -= start;
p->Range *= size; p->Range *= size;
while ((p->Low ^ (p->Low + p->Range)) < kTop || while ((p->Low ^ (p->Low + p->Range)) < kTop ||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{ {
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
p->Range <<= 8; p->Range <<= 8;
p->Low <<= 8; p->Low <<= 8;
} }
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd8_DecodeSymbol(CPpmd8 *p) int Ppmd8_DecodeSymbol(CPpmd8 *p)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 0) if (p->MinContext->NumStats != 0)
{ {
CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
unsigned i; unsigned i;
UInt32 count, hiCnt; UInt32 count, hiCnt;
if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
{ {
Byte symbol; Byte symbol;
RangeDec_Decode(p, 0, s->Freq); RangeDec_Decode(p, 0, s->Freq);
p->FoundState = s; p->FoundState = s;
symbol = s->Symbol; symbol = s->Symbol;
Ppmd8_Update1_0(p); Ppmd8_Update1_0(p);
return symbol; return symbol;
} }
p->PrevSuccess = 0; p->PrevSuccess = 0;
i = p->MinContext->NumStats; i = p->MinContext->NumStats;
do do
{ {
if ((hiCnt += (++s)->Freq) > count) if ((hiCnt += (++s)->Freq) > count)
{ {
Byte symbol; Byte symbol;
RangeDec_Decode(p, hiCnt - s->Freq, s->Freq); RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
p->FoundState = s; p->FoundState = s;
symbol = s->Symbol; symbol = s->Symbol;
Ppmd8_Update1(p); Ppmd8_Update1(p);
return symbol; return symbol;
} }
} }
while (--i); while (--i);
if (count >= p->MinContext->SummFreq) if (count >= p->MinContext->SummFreq)
return -2; return -2;
RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt); RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt);
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
i = p->MinContext->NumStats; i = p->MinContext->NumStats;
do { MASK((--s)->Symbol) = 0; } while (--i); do { MASK((--s)->Symbol) = 0; } while (--i);
} }
else else
{ {
UInt16 *prob = Ppmd8_GetBinSumm(p); UInt16 *prob = Ppmd8_GetBinSumm(p);
if (((p->Code / (p->Range >>= 14)) < *prob)) if (((p->Code / (p->Range >>= 14)) < *prob))
{ {
Byte symbol; Byte symbol;
RangeDec_Decode(p, 0, *prob); RangeDec_Decode(p, 0, *prob);
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol; symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol;
Ppmd8_UpdateBin(p); Ppmd8_UpdateBin(p);
return symbol; return symbol;
} }
RangeDec_Decode(p, *prob, (1 << 14) - *prob); RangeDec_Decode(p, *prob, (1 << 14) - *prob);
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
p->InitEsc = PPMD8_kExpEscape[*prob >> 10]; p->InitEsc = PPMD8_kExpEscape[*prob >> 10];
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0; MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0;
p->PrevSuccess = 0; p->PrevSuccess = 0;
} }
for (;;) for (;;)
{ {
CPpmd_State *ps[256], *s; CPpmd_State *ps[256], *s;
UInt32 freqSum, count, hiCnt; UInt32 freqSum, count, hiCnt;
CPpmd_See *see; CPpmd_See *see;
unsigned i, num, numMasked = p->MinContext->NumStats; unsigned i, num, numMasked = p->MinContext->NumStats;
do do
{ {
p->OrderFall++; p->OrderFall++;
if (!p->MinContext->Suffix) if (!p->MinContext->Suffix)
return -1; return -1;
p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix); p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix);
} }
while (p->MinContext->NumStats == numMasked); while (p->MinContext->NumStats == numMasked);
hiCnt = 0; hiCnt = 0;
s = Ppmd8_GetStats(p, p->MinContext); s = Ppmd8_GetStats(p, p->MinContext);
i = 0; i = 0;
num = p->MinContext->NumStats - numMasked; num = p->MinContext->NumStats - numMasked;
do do
{ {
int k = (int)(MASK(s->Symbol)); int k = (int)(MASK(s->Symbol));
hiCnt += (s->Freq & k); hiCnt += (s->Freq & k);
ps[i] = s++; ps[i] = s++;
i -= k; i -= k;
} }
while (i != num); while (i != num);
see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum); see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum);
freqSum += hiCnt; freqSum += hiCnt;
count = RangeDec_GetThreshold(p, freqSum); count = RangeDec_GetThreshold(p, freqSum);
if (count < hiCnt) if (count < hiCnt)
{ {
Byte symbol; Byte symbol;
CPpmd_State **pps = ps; CPpmd_State **pps = ps;
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
s = *pps; s = *pps;
RangeDec_Decode(p, hiCnt - s->Freq, s->Freq); RangeDec_Decode(p, hiCnt - s->Freq, s->Freq);
Ppmd_See_Update(see); Ppmd_See_Update(see);
p->FoundState = s; p->FoundState = s;
symbol = s->Symbol; symbol = s->Symbol;
Ppmd8_Update2(p); Ppmd8_Update2(p);
return symbol; return symbol;
} }
if (count >= freqSum) if (count >= freqSum)
return -2; return -2;
RangeDec_Decode(p, hiCnt, freqSum - hiCnt); RangeDec_Decode(p, hiCnt, freqSum - hiCnt);
see->Summ = (UInt16)(see->Summ + freqSum); see->Summ = (UInt16)(see->Summ + freqSum);
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
} }
} }

View File

@@ -1,163 +1,163 @@
/* Ppmd8Enc.c -- PPMdI Encoder /* Ppmd8Enc.c -- PPMdI Encoder
2017-04-03 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Ppmd8.h" #include "Ppmd8.h"
#define kTop (1 << 24) #define kTop (1 << 24)
#define kBot (1 << 15) #define kBot (1 << 15)
void Ppmd8_RangeEnc_FlushData(CPpmd8 *p) void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < 4; i++, p->Low <<= 8 ) for (i = 0; i < 4; i++, p->Low <<= 8 )
IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24)); IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
} }
static void RangeEnc_Normalize(CPpmd8 *p) static void RangeEnc_Normalize(CPpmd8 *p)
{ {
while ((p->Low ^ (p->Low + p->Range)) < kTop || while ((p->Low ^ (p->Low + p->Range)) < kTop ||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{ {
IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24)); IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
p->Range <<= 8; p->Range <<= 8;
p->Low <<= 8; p->Low <<= 8;
} }
} }
static void RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total) static void RangeEnc_Encode(CPpmd8 *p, UInt32 start, UInt32 size, UInt32 total)
{ {
p->Low += start * (p->Range /= total); p->Low += start * (p->Range /= total);
p->Range *= size; p->Range *= size;
RangeEnc_Normalize(p); RangeEnc_Normalize(p);
} }
static void RangeEnc_EncodeBit_0(CPpmd8 *p, UInt32 size0) static void RangeEnc_EncodeBit_0(CPpmd8 *p, UInt32 size0)
{ {
p->Range >>= 14; p->Range >>= 14;
p->Range *= size0; p->Range *= size0;
RangeEnc_Normalize(p); RangeEnc_Normalize(p);
} }
static void RangeEnc_EncodeBit_1(CPpmd8 *p, UInt32 size0) static void RangeEnc_EncodeBit_1(CPpmd8 *p, UInt32 size0)
{ {
p->Low += size0 * (p->Range >>= 14); p->Low += size0 * (p->Range >>= 14);
p->Range *= ((1 << 14) - size0); p->Range *= ((1 << 14) - size0);
RangeEnc_Normalize(p); RangeEnc_Normalize(p);
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol) void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 0) if (p->MinContext->NumStats != 0)
{ {
CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext);
UInt32 sum; UInt32 sum;
unsigned i; unsigned i;
if (s->Symbol == symbol) if (s->Symbol == symbol)
{ {
RangeEnc_Encode(p, 0, s->Freq, p->MinContext->SummFreq); RangeEnc_Encode(p, 0, s->Freq, p->MinContext->SummFreq);
p->FoundState = s; p->FoundState = s;
Ppmd8_Update1_0(p); Ppmd8_Update1_0(p);
return; return;
} }
p->PrevSuccess = 0; p->PrevSuccess = 0;
sum = s->Freq; sum = s->Freq;
i = p->MinContext->NumStats; i = p->MinContext->NumStats;
do do
{ {
if ((++s)->Symbol == symbol) if ((++s)->Symbol == symbol)
{ {
RangeEnc_Encode(p, sum, s->Freq, p->MinContext->SummFreq); RangeEnc_Encode(p, sum, s->Freq, p->MinContext->SummFreq);
p->FoundState = s; p->FoundState = s;
Ppmd8_Update1(p); Ppmd8_Update1(p);
return; return;
} }
sum += s->Freq; sum += s->Freq;
} }
while (--i); while (--i);
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
i = p->MinContext->NumStats; i = p->MinContext->NumStats;
do { MASK((--s)->Symbol) = 0; } while (--i); do { MASK((--s)->Symbol) = 0; } while (--i);
RangeEnc_Encode(p, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); RangeEnc_Encode(p, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
} }
else else
{ {
UInt16 *prob = Ppmd8_GetBinSumm(p); UInt16 *prob = Ppmd8_GetBinSumm(p);
CPpmd_State *s = Ppmd8Context_OneState(p->MinContext); CPpmd_State *s = Ppmd8Context_OneState(p->MinContext);
if (s->Symbol == symbol) if (s->Symbol == symbol)
{ {
RangeEnc_EncodeBit_0(p, *prob); RangeEnc_EncodeBit_0(p, *prob);
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
p->FoundState = s; p->FoundState = s;
Ppmd8_UpdateBin(p); Ppmd8_UpdateBin(p);
return; return;
} }
else else
{ {
RangeEnc_EncodeBit_1(p, *prob); RangeEnc_EncodeBit_1(p, *prob);
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
p->InitEsc = PPMD8_kExpEscape[*prob >> 10]; p->InitEsc = PPMD8_kExpEscape[*prob >> 10];
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
p->PrevSuccess = 0; p->PrevSuccess = 0;
} }
} }
for (;;) for (;;)
{ {
UInt32 escFreq; UInt32 escFreq;
CPpmd_See *see; CPpmd_See *see;
CPpmd_State *s; CPpmd_State *s;
UInt32 sum; UInt32 sum;
unsigned i, numMasked = p->MinContext->NumStats; unsigned i, numMasked = p->MinContext->NumStats;
do do
{ {
p->OrderFall++; p->OrderFall++;
if (!p->MinContext->Suffix) if (!p->MinContext->Suffix)
return; /* EndMarker (symbol = -1) */ return; /* EndMarker (symbol = -1) */
p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix); p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix);
} }
while (p->MinContext->NumStats == numMasked); while (p->MinContext->NumStats == numMasked);
see = Ppmd8_MakeEscFreq(p, numMasked, &escFreq); see = Ppmd8_MakeEscFreq(p, numMasked, &escFreq);
s = Ppmd8_GetStats(p, p->MinContext); s = Ppmd8_GetStats(p, p->MinContext);
sum = 0; sum = 0;
i = p->MinContext->NumStats + 1; i = p->MinContext->NumStats + 1;
do do
{ {
int cur = s->Symbol; int cur = s->Symbol;
if (cur == symbol) if (cur == symbol)
{ {
UInt32 low = sum; UInt32 low = sum;
CPpmd_State *s1 = s; CPpmd_State *s1 = s;
do do
{ {
sum += (s->Freq & (int)(MASK(s->Symbol))); sum += (s->Freq & (int)(MASK(s->Symbol)));
s++; s++;
} }
while (--i); while (--i);
RangeEnc_Encode(p, low, s1->Freq, sum + escFreq); RangeEnc_Encode(p, low, s1->Freq, sum + escFreq);
Ppmd_See_Update(see); Ppmd_See_Update(see);
p->FoundState = s1; p->FoundState = s1;
Ppmd8_Update2(p); Ppmd8_Update2(p);
return; return;
} }
sum += (s->Freq & (int)(MASK(cur))); sum += (s->Freq & (int)(MASK(cur)));
MASK(cur) = 0; MASK(cur) = 0;
s++; s++;
} }
while (--i); while (--i);
RangeEnc_Encode(p, sum, escFreq, sum + escFreq); RangeEnc_Encode(p, sum, escFreq, sum + escFreq);
see->Summ = (UInt16)(see->Summ + sum + escFreq); see->Summ = (UInt16)(see->Summ + sum + escFreq);
} }
} }

View File

@@ -1,10 +1,10 @@
/* Precomp.h -- StdAfx /* Precomp.h -- StdAfx
2013-11-12 : Igor Pavlov : Public domain */ 2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H #ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H #define __7Z_PRECOMP_H
#include "Compiler.h" #include "Compiler.h"
/* #include "7zTypes.h" */ /* #include "7zTypes.h" */
#endif #endif

View File

@@ -1,30 +1,30 @@
/* RotateDefs.h -- Rotate functions /* RotateDefs.h -- Rotate functions
2015-03-25 : Igor Pavlov : Public domain */ 2015-03-25 : Igor Pavlov : Public domain */
#ifndef __ROTATE_DEFS_H #ifndef __ROTATE_DEFS_H
#define __ROTATE_DEFS_H #define __ROTATE_DEFS_H
#ifdef _MSC_VER #ifdef _MSC_VER
#include <stdlib.h> #include <stdlib.h>
/* don't use _rotl with MINGW. It can insert slow call to function. */ /* don't use _rotl with MINGW. It can insert slow call to function. */
/* #if (_MSC_VER >= 1200) */ /* #if (_MSC_VER >= 1200) */
#pragma intrinsic(_rotl) #pragma intrinsic(_rotl)
#pragma intrinsic(_rotr) #pragma intrinsic(_rotr)
/* #endif */ /* #endif */
#define rotlFixed(x, n) _rotl((x), (n)) #define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n)) #define rotrFixed(x, n) _rotr((x), (n))
#else #else
/* new compilers can translate these macros to fast commands. */ /* new compilers can translate these macros to fast commands. */
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) #define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) #define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
#endif #endif
#endif #endif

680
C/Sha1.c
View File

@@ -1,340 +1,340 @@
/* Sha1.c -- SHA-1 Hash /* Sha1.c -- SHA-1 Hash
2017-04-03 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
#include <string.h> #include <string.h>
#include "CpuArch.h" #include "CpuArch.h"
#include "RotateDefs.h" #include "RotateDefs.h"
#include "Sha1.h" #include "Sha1.h"
// define it for speed optimization // define it for speed optimization
// #define _SHA1_UNROLL // #define _SHA1_UNROLL
#ifdef _SHA1_UNROLL #ifdef _SHA1_UNROLL
#define kNumW 16 #define kNumW 16
#define WW(i) W[(i)&15] #define WW(i) W[(i)&15]
#else #else
#define kNumW 80 #define kNumW 80
#define WW(i) W[i] #define WW(i) W[i]
#endif #endif
#define w0(i) (W[i] = data[i]) #define w0(i) (W[i] = data[i])
#define w1(i) (WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1)) #define w1(i) (WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1))
#define f1(x,y,z) (z^(x&(y^z))) #define f1(x,y,z) (z^(x&(y^z)))
#define f2(x,y,z) (x^y^z) #define f2(x,y,z) (x^y^z)
#define f3(x,y,z) ((x&y)|(z&(x|y))) #define f3(x,y,z) ((x&y)|(z&(x|y)))
#define f4(x,y,z) (x^y^z) #define f4(x,y,z) (x^y^z)
#define RK(a,b,c,d,e, fx, w, k) e += fx(b,c,d) + w + k + rotlFixed(a,5); b = rotlFixed(b,30); #define RK(a,b,c,d,e, fx, w, k) e += fx(b,c,d) + w + k + rotlFixed(a,5); b = rotlFixed(b,30);
#define R0(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w0(i), 0x5A827999) #define R0(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w0(i), 0x5A827999)
#define R1(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w1(i), 0x5A827999) #define R1(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w1(i), 0x5A827999)
#define R2(a,b,c,d,e, i) RK(a,b,c,d,e, f2, w1(i), 0x6ED9EBA1) #define R2(a,b,c,d,e, i) RK(a,b,c,d,e, f2, w1(i), 0x6ED9EBA1)
#define R3(a,b,c,d,e, i) RK(a,b,c,d,e, f3, w1(i), 0x8F1BBCDC) #define R3(a,b,c,d,e, i) RK(a,b,c,d,e, f3, w1(i), 0x8F1BBCDC)
#define R4(a,b,c,d,e, i) RK(a,b,c,d,e, f4, w1(i), 0xCA62C1D6) #define R4(a,b,c,d,e, i) RK(a,b,c,d,e, f4, w1(i), 0xCA62C1D6)
#define RX_1_4(rx1, rx4, i) \ #define RX_1_4(rx1, rx4, i) \
rx1(a,b,c,d,e, i); \ rx1(a,b,c,d,e, i); \
rx4(e,a,b,c,d, i+1); \ rx4(e,a,b,c,d, i+1); \
rx4(d,e,a,b,c, i+2); \ rx4(d,e,a,b,c, i+2); \
rx4(c,d,e,a,b, i+3); \ rx4(c,d,e,a,b, i+3); \
rx4(b,c,d,e,a, i+4); \ rx4(b,c,d,e,a, i+4); \
#define RX_5(rx, i) RX_1_4(rx, rx, i); #define RX_5(rx, i) RX_1_4(rx, rx, i);
#ifdef _SHA1_UNROLL #ifdef _SHA1_UNROLL
#define RX_15 \ #define RX_15 \
RX_5(R0, 0); \ RX_5(R0, 0); \
RX_5(R0, 5); \ RX_5(R0, 5); \
RX_5(R0, 10); RX_5(R0, 10);
#define RX_20(rx, i) \ #define RX_20(rx, i) \
RX_5(rx, i); \ RX_5(rx, i); \
RX_5(rx, i + 5); \ RX_5(rx, i + 5); \
RX_5(rx, i + 10); \ RX_5(rx, i + 10); \
RX_5(rx, i + 15); RX_5(rx, i + 15);
#else #else
#define RX_15 { size_t i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } } #define RX_15 { size_t i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
#define RX_20(rx, ii) { size_t i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } } #define RX_20(rx, ii) { size_t i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
#endif #endif
void Sha1_Init(CSha1 *p) void Sha1_Init(CSha1 *p)
{ {
p->state[0] = 0x67452301; p->state[0] = 0x67452301;
p->state[1] = 0xEFCDAB89; p->state[1] = 0xEFCDAB89;
p->state[2] = 0x98BADCFE; p->state[2] = 0x98BADCFE;
p->state[3] = 0x10325476; p->state[3] = 0x10325476;
p->state[4] = 0xC3D2E1F0; p->state[4] = 0xC3D2E1F0;
p->count = 0; p->count = 0;
} }
void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest) void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest)
{ {
UInt32 a, b, c, d, e; UInt32 a, b, c, d, e;
UInt32 W[kNumW]; UInt32 W[kNumW];
a = p->state[0]; a = p->state[0];
b = p->state[1]; b = p->state[1];
c = p->state[2]; c = p->state[2];
d = p->state[3]; d = p->state[3];
e = p->state[4]; e = p->state[4];
RX_15 RX_15
RX_1_4(R0, R1, 15); RX_1_4(R0, R1, 15);
RX_20(R2, 20); RX_20(R2, 20);
RX_20(R3, 40); RX_20(R3, 40);
RX_20(R4, 60); RX_20(R4, 60);
destDigest[0] = p->state[0] + a; destDigest[0] = p->state[0] + a;
destDigest[1] = p->state[1] + b; destDigest[1] = p->state[1] + b;
destDigest[2] = p->state[2] + c; destDigest[2] = p->state[2] + c;
destDigest[3] = p->state[3] + d; destDigest[3] = p->state[3] + d;
destDigest[4] = p->state[4] + e; destDigest[4] = p->state[4] + e;
} }
void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes) void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes)
{ {
UInt32 a, b, c, d, e; UInt32 a, b, c, d, e;
UInt32 W[kNumW]; UInt32 W[kNumW];
a = p->state[0]; a = p->state[0];
b = p->state[1]; b = p->state[1];
c = p->state[2]; c = p->state[2];
d = p->state[3]; d = p->state[3];
e = p->state[4]; e = p->state[4];
RX_15 RX_15
RX_1_4(R0, R1, 15); RX_1_4(R0, R1, 15);
RX_20(R2, 20); RX_20(R2, 20);
RX_20(R3, 40); RX_20(R3, 40);
RX_20(R4, 60); RX_20(R4, 60);
p->state[0] += a; p->state[0] += a;
p->state[1] += b; p->state[1] += b;
p->state[2] += c; p->state[2] += c;
p->state[3] += d; p->state[3] += d;
p->state[4] += e; p->state[4] += e;
if (returnRes) if (returnRes)
{ {
size_t i; size_t i;
for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++) for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++)
data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i]; data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i];
} }
} }
#define Sha1_UpdateBlock(p) Sha1_GetBlockDigest(p, p->buffer, p->state) #define Sha1_UpdateBlock(p) Sha1_GetBlockDigest(p, p->buffer, p->state)
void Sha1_Update(CSha1 *p, const Byte *data, size_t size) void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
{ {
unsigned pos, pos2; unsigned pos, pos2;
if (size == 0) if (size == 0)
return; return;
pos = (unsigned)p->count & 0x3F; pos = (unsigned)p->count & 0x3F;
p->count += size; p->count += size;
pos2 = pos & 3; pos2 = pos & 3;
pos >>= 2; pos >>= 2;
if (pos2 != 0) if (pos2 != 0)
{ {
UInt32 w; UInt32 w;
pos2 = (3 - pos2) * 8; pos2 = (3 - pos2) * 8;
w = ((UInt32)*data++) << pos2; w = ((UInt32)*data++) << pos2;
if (--size && pos2) if (--size && pos2)
{ {
pos2 -= 8; pos2 -= 8;
w |= ((UInt32)*data++) << pos2; w |= ((UInt32)*data++) << pos2;
if (--size && pos2) if (--size && pos2)
{ {
pos2 -= 8; pos2 -= 8;
w |= ((UInt32)*data++) << pos2; w |= ((UInt32)*data++) << pos2;
size--; size--;
} }
} }
p->buffer[pos] |= w; p->buffer[pos] |= w;
if (pos2 == 0) if (pos2 == 0)
pos++; pos++;
} }
for (;;) for (;;)
{ {
if (pos == SHA1_NUM_BLOCK_WORDS) if (pos == SHA1_NUM_BLOCK_WORDS)
{ {
for (;;) for (;;)
{ {
size_t i; size_t i;
Sha1_UpdateBlock(p); Sha1_UpdateBlock(p);
if (size < SHA1_BLOCK_SIZE) if (size < SHA1_BLOCK_SIZE)
break; break;
size -= SHA1_BLOCK_SIZE; size -= SHA1_BLOCK_SIZE;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i += 2) for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i += 2)
{ {
p->buffer[i ] = GetBe32(data); p->buffer[i ] = GetBe32(data);
p->buffer[i + 1] = GetBe32(data + 4); p->buffer[i + 1] = GetBe32(data + 4);
data += 8; data += 8;
} }
} }
pos = 0; pos = 0;
} }
if (size < 4) if (size < 4)
break; break;
p->buffer[pos] = GetBe32(data); p->buffer[pos] = GetBe32(data);
data += 4; data += 4;
size -= 4; size -= 4;
pos++; pos++;
} }
if (size != 0) if (size != 0)
{ {
UInt32 w = ((UInt32)data[0]) << 24; UInt32 w = ((UInt32)data[0]) << 24;
if (size > 1) if (size > 1)
{ {
w |= ((UInt32)data[1]) << 16; w |= ((UInt32)data[1]) << 16;
if (size > 2) if (size > 2)
w |= ((UInt32)data[2]) << 8; w |= ((UInt32)data[2]) << 8;
} }
p->buffer[pos] = w; p->buffer[pos] = w;
} }
} }
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */) void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */)
{ {
int returnRes = False; int returnRes = False;
unsigned pos = (unsigned)p->count & 0x3F; unsigned pos = (unsigned)p->count & 0x3F;
p->count += size; p->count += size;
while (size--) while (size--)
{ {
unsigned pos2 = (pos & 3); unsigned pos2 = (pos & 3);
UInt32 v = ((UInt32)*data++) << (8 * (3 - pos2)); UInt32 v = ((UInt32)*data++) << (8 * (3 - pos2));
UInt32 *ref = &(p->buffer[pos >> 2]); UInt32 *ref = &(p->buffer[pos >> 2]);
pos++; pos++;
if (pos2 == 0) if (pos2 == 0)
{ {
*ref = v; *ref = v;
continue; continue;
} }
*ref |= v; *ref |= v;
if (pos == SHA1_BLOCK_SIZE) if (pos == SHA1_BLOCK_SIZE)
{ {
pos = 0; pos = 0;
Sha1_UpdateBlock_Rar(p, p->buffer, returnRes); Sha1_UpdateBlock_Rar(p, p->buffer, returnRes);
if (returnRes) if (returnRes)
{ {
size_t i; size_t i;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
{ {
UInt32 d = p->buffer[i]; UInt32 d = p->buffer[i];
Byte *prev = data + i * 4 - SHA1_BLOCK_SIZE; Byte *prev = data + i * 4 - SHA1_BLOCK_SIZE;
SetUi32(prev, d); SetUi32(prev, d);
} }
} }
// returnRes = rar350Mode; // returnRes = rar350Mode;
returnRes = True; returnRes = True;
} }
} }
} }
void Sha1_Final(CSha1 *p, Byte *digest) void Sha1_Final(CSha1 *p, Byte *digest)
{ {
unsigned pos = (unsigned)p->count & 0x3F; unsigned pos = (unsigned)p->count & 0x3F;
unsigned pos2 = (pos & 3); unsigned pos2 = (pos & 3);
UInt64 numBits; UInt64 numBits;
UInt32 w; UInt32 w;
unsigned i; unsigned i;
pos >>= 2; pos >>= 2;
w = 0; w = 0;
if (pos2 != 0) if (pos2 != 0)
w = p->buffer[pos]; w = p->buffer[pos];
p->buffer[pos++] = w | (((UInt32)0x80000000) >> (8 * pos2)); p->buffer[pos++] = w | (((UInt32)0x80000000) >> (8 * pos2));
while (pos != (SHA1_NUM_BLOCK_WORDS - 2)) while (pos != (SHA1_NUM_BLOCK_WORDS - 2))
{ {
pos &= 0xF; pos &= 0xF;
if (pos == 0) if (pos == 0)
Sha1_UpdateBlock(p); Sha1_UpdateBlock(p);
p->buffer[pos++] = 0; p->buffer[pos++] = 0;
} }
numBits = (p->count << 3); numBits = (p->count << 3);
p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32); p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits); p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
Sha1_UpdateBlock(p); Sha1_UpdateBlock(p);
for (i = 0; i < SHA1_NUM_DIGEST_WORDS; i++) for (i = 0; i < SHA1_NUM_DIGEST_WORDS; i++)
{ {
UInt32 v = p->state[i]; UInt32 v = p->state[i];
SetBe32(digest, v); SetBe32(digest, v);
digest += 4; digest += 4;
} }
Sha1_Init(p); Sha1_Init(p);
} }
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size) void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size)
{ {
const UInt64 numBits = (p->count + size) << 5; const UInt64 numBits = (p->count + size) << 5;
block[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32); block[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
block[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits); block[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
block[size++] = 0x80000000; block[size++] = 0x80000000;
while (size != (SHA1_NUM_BLOCK_WORDS - 2)) while (size != (SHA1_NUM_BLOCK_WORDS - 2))
block[size++] = 0; block[size++] = 0;
} }
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size) void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size)
{ {
unsigned pos = (unsigned)p->count & 0xF; unsigned pos = (unsigned)p->count & 0xF;
p->count += size; p->count += size;
while (size--) while (size--)
{ {
p->buffer[pos++] = *data++; p->buffer[pos++] = *data++;
if (pos == SHA1_NUM_BLOCK_WORDS) if (pos == SHA1_NUM_BLOCK_WORDS)
{ {
pos = 0; pos = 0;
Sha1_UpdateBlock(p); Sha1_UpdateBlock(p);
} }
} }
} }
void Sha1_32_Final(CSha1 *p, UInt32 *digest) void Sha1_32_Final(CSha1 *p, UInt32 *digest)
{ {
UInt64 numBits; UInt64 numBits;
unsigned pos = (unsigned)p->count & 0xF; unsigned pos = (unsigned)p->count & 0xF;
p->buffer[pos++] = 0x80000000; p->buffer[pos++] = 0x80000000;
while (pos != (SHA1_NUM_BLOCK_WORDS - 2)) while (pos != (SHA1_NUM_BLOCK_WORDS - 2))
{ {
pos &= 0xF; pos &= 0xF;
if (pos == 0) if (pos == 0)
Sha1_UpdateBlock(p); Sha1_UpdateBlock(p);
p->buffer[pos++] = 0; p->buffer[pos++] = 0;
} }
numBits = (p->count << 5); numBits = (p->count << 5);
p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32); p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits); p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
Sha1_GetBlockDigest(p, p->buffer, digest); Sha1_GetBlockDigest(p, p->buffer, digest);
Sha1_Init(p); Sha1_Init(p);
} }

View File

@@ -1,38 +1,38 @@
/* Sha1.h -- SHA-1 Hash /* Sha1.h -- SHA-1 Hash
2016-05-20 : Igor Pavlov : Public domain */ 2016-05-20 : Igor Pavlov : Public domain */
#ifndef __7Z_SHA1_H #ifndef __7Z_SHA1_H
#define __7Z_SHA1_H #define __7Z_SHA1_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define SHA1_NUM_BLOCK_WORDS 16 #define SHA1_NUM_BLOCK_WORDS 16
#define SHA1_NUM_DIGEST_WORDS 5 #define SHA1_NUM_DIGEST_WORDS 5
#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4) #define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4)
#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4) #define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4)
typedef struct typedef struct
{ {
UInt32 state[SHA1_NUM_DIGEST_WORDS]; UInt32 state[SHA1_NUM_DIGEST_WORDS];
UInt64 count; UInt64 count;
UInt32 buffer[SHA1_NUM_BLOCK_WORDS]; UInt32 buffer[SHA1_NUM_BLOCK_WORDS];
} CSha1; } CSha1;
void Sha1_Init(CSha1 *p); void Sha1_Init(CSha1 *p);
void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest); void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest);
void Sha1_Update(CSha1 *p, const Byte *data, size_t size); void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
void Sha1_Final(CSha1 *p, Byte *digest); void Sha1_Final(CSha1 *p, Byte *digest);
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */); void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */);
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size); void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size);
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size); void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size);
void Sha1_32_Final(CSha1 *p, UInt32 *digest); void Sha1_32_Final(CSha1 *p, UInt32 *digest);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,248 +1,248 @@
/* Crypto/Sha256.c -- SHA-256 Hash /* Crypto/Sha256.c -- SHA-256 Hash
2017-04-03 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */ This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
#include <string.h> #include <string.h>
#include "CpuArch.h" #include "CpuArch.h"
#include "RotateDefs.h" #include "RotateDefs.h"
#include "Sha256.h" #include "Sha256.h"
/* define it for speed optimization */ /* define it for speed optimization */
#ifndef _SFX #ifndef _SFX
#define _SHA256_UNROLL #define _SHA256_UNROLL
#define _SHA256_UNROLL2 #define _SHA256_UNROLL2
#endif #endif
/* #define _SHA256_UNROLL2 */ /* #define _SHA256_UNROLL2 */
void Sha256_Init(CSha256 *p) void Sha256_Init(CSha256 *p)
{ {
p->state[0] = 0x6a09e667; p->state[0] = 0x6a09e667;
p->state[1] = 0xbb67ae85; p->state[1] = 0xbb67ae85;
p->state[2] = 0x3c6ef372; p->state[2] = 0x3c6ef372;
p->state[3] = 0xa54ff53a; p->state[3] = 0xa54ff53a;
p->state[4] = 0x510e527f; p->state[4] = 0x510e527f;
p->state[5] = 0x9b05688c; p->state[5] = 0x9b05688c;
p->state[6] = 0x1f83d9ab; p->state[6] = 0x1f83d9ab;
p->state[7] = 0x5be0cd19; p->state[7] = 0x5be0cd19;
p->count = 0; p->count = 0;
} }
#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) #define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) #define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) #define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) #define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
#define blk0(i) (W[i]) #define blk0(i) (W[i])
#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15])) #define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z))) #define Ch(x,y,z) (z^(x&(y^z)))
#define Maj(x,y,z) ((x&y)|(z&(x|y))) #define Maj(x,y,z) ((x&y)|(z&(x|y)))
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
#define R(a,b,c,d,e,f,g,h, i) \ #define R(a,b,c,d,e,f,g,h, i) \
h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \ h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
d += h; \ d += h; \
h += S0(a) + Maj(a, b, c) h += S0(a) + Maj(a, b, c)
#define RX_8(i) \ #define RX_8(i) \
R(a,b,c,d,e,f,g,h, i); \ R(a,b,c,d,e,f,g,h, i); \
R(h,a,b,c,d,e,f,g, i+1); \ R(h,a,b,c,d,e,f,g, i+1); \
R(g,h,a,b,c,d,e,f, i+2); \ R(g,h,a,b,c,d,e,f, i+2); \
R(f,g,h,a,b,c,d,e, i+3); \ R(f,g,h,a,b,c,d,e, i+3); \
R(e,f,g,h,a,b,c,d, i+4); \ R(e,f,g,h,a,b,c,d, i+4); \
R(d,e,f,g,h,a,b,c, i+5); \ R(d,e,f,g,h,a,b,c, i+5); \
R(c,d,e,f,g,h,a,b, i+6); \ R(c,d,e,f,g,h,a,b, i+6); \
R(b,c,d,e,f,g,h,a, i+7) R(b,c,d,e,f,g,h,a, i+7)
#define RX_16 RX_8(0); RX_8(8); #define RX_16 RX_8(0); RX_8(8);
#else #else
#define a(i) T[(0-(i))&7] #define a(i) T[(0-(i))&7]
#define b(i) T[(1-(i))&7] #define b(i) T[(1-(i))&7]
#define c(i) T[(2-(i))&7] #define c(i) T[(2-(i))&7]
#define d(i) T[(3-(i))&7] #define d(i) T[(3-(i))&7]
#define e(i) T[(4-(i))&7] #define e(i) T[(4-(i))&7]
#define f(i) T[(5-(i))&7] #define f(i) T[(5-(i))&7]
#define g(i) T[(6-(i))&7] #define g(i) T[(6-(i))&7]
#define h(i) T[(7-(i))&7] #define h(i) T[(7-(i))&7]
#define R(i) \ #define R(i) \
h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \ h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
d(i) += h(i); \ d(i) += h(i); \
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \ h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
#ifdef _SHA256_UNROLL #ifdef _SHA256_UNROLL
#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); #define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
#define RX_16 RX_8(0); RX_8(8); #define RX_16 RX_8(0); RX_8(8);
#else #else
#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); } #define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); }
#endif #endif
#endif #endif
static const UInt32 K[64] = { static const UInt32 K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
}; };
static void Sha256_WriteByteBlock(CSha256 *p) static void Sha256_WriteByteBlock(CSha256 *p)
{ {
UInt32 W[16]; UInt32 W[16];
unsigned j; unsigned j;
UInt32 *state; UInt32 *state;
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
UInt32 a,b,c,d,e,f,g,h; UInt32 a,b,c,d,e,f,g,h;
#else #else
UInt32 T[8]; UInt32 T[8];
#endif #endif
for (j = 0; j < 16; j += 4) for (j = 0; j < 16; j += 4)
{ {
const Byte *ccc = p->buffer + j * 4; const Byte *ccc = p->buffer + j * 4;
W[j ] = GetBe32(ccc); W[j ] = GetBe32(ccc);
W[j + 1] = GetBe32(ccc + 4); W[j + 1] = GetBe32(ccc + 4);
W[j + 2] = GetBe32(ccc + 8); W[j + 2] = GetBe32(ccc + 8);
W[j + 3] = GetBe32(ccc + 12); W[j + 3] = GetBe32(ccc + 12);
} }
state = p->state; state = p->state;
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
a = state[0]; a = state[0];
b = state[1]; b = state[1];
c = state[2]; c = state[2];
d = state[3]; d = state[3];
e = state[4]; e = state[4];
f = state[5]; f = state[5];
g = state[6]; g = state[6];
h = state[7]; h = state[7];
#else #else
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
T[j] = state[j]; T[j] = state[j];
#endif #endif
for (j = 0; j < 64; j += 16) for (j = 0; j < 64; j += 16)
{ {
RX_16 RX_16
} }
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
state[0] += a; state[0] += a;
state[1] += b; state[1] += b;
state[2] += c; state[2] += c;
state[3] += d; state[3] += d;
state[4] += e; state[4] += e;
state[5] += f; state[5] += f;
state[6] += g; state[6] += g;
state[7] += h; state[7] += h;
#else #else
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
state[j] += T[j]; state[j] += T[j];
#endif #endif
/* Wipe variables */ /* Wipe variables */
/* memset(W, 0, sizeof(W)); */ /* memset(W, 0, sizeof(W)); */
/* memset(T, 0, sizeof(T)); */ /* memset(T, 0, sizeof(T)); */
} }
#undef S0 #undef S0
#undef S1 #undef S1
#undef s0 #undef s0
#undef s1 #undef s1
void Sha256_Update(CSha256 *p, const Byte *data, size_t size) void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
{ {
if (size == 0) if (size == 0)
return; return;
{ {
unsigned pos = (unsigned)p->count & 0x3F; unsigned pos = (unsigned)p->count & 0x3F;
unsigned num; unsigned num;
p->count += size; p->count += size;
num = 64 - pos; num = 64 - pos;
if (num > size) if (num > size)
{ {
memcpy(p->buffer + pos, data, size); memcpy(p->buffer + pos, data, size);
return; return;
} }
size -= num; size -= num;
memcpy(p->buffer + pos, data, num); memcpy(p->buffer + pos, data, num);
data += num; data += num;
} }
for (;;) for (;;)
{ {
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
if (size < 64) if (size < 64)
break; break;
size -= 64; size -= 64;
memcpy(p->buffer, data, 64); memcpy(p->buffer, data, 64);
data += 64; data += 64;
} }
if (size != 0) if (size != 0)
memcpy(p->buffer, data, size); memcpy(p->buffer, data, size);
} }
void Sha256_Final(CSha256 *p, Byte *digest) void Sha256_Final(CSha256 *p, Byte *digest)
{ {
unsigned pos = (unsigned)p->count & 0x3F; unsigned pos = (unsigned)p->count & 0x3F;
unsigned i; unsigned i;
p->buffer[pos++] = 0x80; p->buffer[pos++] = 0x80;
while (pos != (64 - 8)) while (pos != (64 - 8))
{ {
pos &= 0x3F; pos &= 0x3F;
if (pos == 0) if (pos == 0)
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
p->buffer[pos++] = 0; p->buffer[pos++] = 0;
} }
{ {
UInt64 numBits = (p->count << 3); UInt64 numBits = (p->count << 3);
SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)); SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)); SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
} }
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
for (i = 0; i < 8; i += 2) for (i = 0; i < 8; i += 2)
{ {
UInt32 v0 = p->state[i]; UInt32 v0 = p->state[i];
UInt32 v1 = p->state[i + 1]; UInt32 v1 = p->state[i + 1];
SetBe32(digest , v0); SetBe32(digest , v0);
SetBe32(digest + 4, v1); SetBe32(digest + 4, v1);
digest += 8; digest += 8;
} }
Sha256_Init(p); Sha256_Init(p);
} }

View File

@@ -1,26 +1,26 @@
/* Sha256.h -- SHA-256 Hash /* Sha256.h -- SHA-256 Hash
2013-01-18 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __CRYPTO_SHA256_H #ifndef __CRYPTO_SHA256_H
#define __CRYPTO_SHA256_H #define __CRYPTO_SHA256_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define SHA256_DIGEST_SIZE 32 #define SHA256_DIGEST_SIZE 32
typedef struct typedef struct
{ {
UInt32 state[8]; UInt32 state[8];
UInt64 count; UInt64 count;
Byte buffer[64]; Byte buffer[64];
} CSha256; } CSha256;
void Sha256_Init(CSha256 *p); void Sha256_Init(CSha256 *p);
void Sha256_Update(CSha256 *p, const Byte *data, size_t size); void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
void Sha256_Final(CSha256 *p, Byte *digest); void Sha256_Final(CSha256 *p, Byte *digest);
EXTERN_C_END EXTERN_C_END
#endif #endif

282
C/Sort.c
View File

@@ -1,141 +1,141 @@
/* Sort.c -- Sort functions /* Sort.c -- Sort functions
2014-04-05 : Igor Pavlov : Public domain */ 2014-04-05 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Sort.h" #include "Sort.h"
#define HeapSortDown(p, k, size, temp) \ #define HeapSortDown(p, k, size, temp) \
{ for (;;) { \ { for (;;) { \
size_t s = (k << 1); \ size_t s = (k << 1); \
if (s > size) break; \ if (s > size) break; \
if (s < size && p[s + 1] > p[s]) s++; \ if (s < size && p[s + 1] > p[s]) s++; \
if (temp >= p[s]) break; \ if (temp >= p[s]) break; \
p[k] = p[s]; k = s; \ p[k] = p[s]; k = s; \
} p[k] = temp; } } p[k] = temp; }
void HeapSort(UInt32 *p, size_t size) void HeapSort(UInt32 *p, size_t size)
{ {
if (size <= 1) if (size <= 1)
return; return;
p--; p--;
{ {
size_t i = size / 2; size_t i = size / 2;
do do
{ {
UInt32 temp = p[i]; UInt32 temp = p[i];
size_t k = i; size_t k = i;
HeapSortDown(p, k, size, temp) HeapSortDown(p, k, size, temp)
} }
while (--i != 0); while (--i != 0);
} }
/* /*
do do
{ {
size_t k = 1; size_t k = 1;
UInt32 temp = p[size]; UInt32 temp = p[size];
p[size--] = p[1]; p[size--] = p[1];
HeapSortDown(p, k, size, temp) HeapSortDown(p, k, size, temp)
} }
while (size > 1); while (size > 1);
*/ */
while (size > 3) while (size > 3)
{ {
UInt32 temp = p[size]; UInt32 temp = p[size];
size_t k = (p[3] > p[2]) ? 3 : 2; size_t k = (p[3] > p[2]) ? 3 : 2;
p[size--] = p[1]; p[size--] = p[1];
p[1] = p[k]; p[1] = p[k];
HeapSortDown(p, k, size, temp) HeapSortDown(p, k, size, temp)
} }
{ {
UInt32 temp = p[size]; UInt32 temp = p[size];
p[size] = p[1]; p[size] = p[1];
if (size > 2 && p[2] < temp) if (size > 2 && p[2] < temp)
{ {
p[1] = p[2]; p[1] = p[2];
p[2] = temp; p[2] = temp;
} }
else else
p[1] = temp; p[1] = temp;
} }
} }
void HeapSort64(UInt64 *p, size_t size) void HeapSort64(UInt64 *p, size_t size)
{ {
if (size <= 1) if (size <= 1)
return; return;
p--; p--;
{ {
size_t i = size / 2; size_t i = size / 2;
do do
{ {
UInt64 temp = p[i]; UInt64 temp = p[i];
size_t k = i; size_t k = i;
HeapSortDown(p, k, size, temp) HeapSortDown(p, k, size, temp)
} }
while (--i != 0); while (--i != 0);
} }
/* /*
do do
{ {
size_t k = 1; size_t k = 1;
UInt64 temp = p[size]; UInt64 temp = p[size];
p[size--] = p[1]; p[size--] = p[1];
HeapSortDown(p, k, size, temp) HeapSortDown(p, k, size, temp)
} }
while (size > 1); while (size > 1);
*/ */
while (size > 3) while (size > 3)
{ {
UInt64 temp = p[size]; UInt64 temp = p[size];
size_t k = (p[3] > p[2]) ? 3 : 2; size_t k = (p[3] > p[2]) ? 3 : 2;
p[size--] = p[1]; p[size--] = p[1];
p[1] = p[k]; p[1] = p[k];
HeapSortDown(p, k, size, temp) HeapSortDown(p, k, size, temp)
} }
{ {
UInt64 temp = p[size]; UInt64 temp = p[size];
p[size] = p[1]; p[size] = p[1];
if (size > 2 && p[2] < temp) if (size > 2 && p[2] < temp)
{ {
p[1] = p[2]; p[1] = p[2];
p[2] = temp; p[2] = temp;
} }
else else
p[1] = temp; p[1] = temp;
} }
} }
/* /*
#define HeapSortRefDown(p, vals, n, size, temp) \ #define HeapSortRefDown(p, vals, n, size, temp) \
{ size_t k = n; UInt32 val = vals[temp]; for (;;) { \ { size_t k = n; UInt32 val = vals[temp]; for (;;) { \
size_t s = (k << 1); \ size_t s = (k << 1); \
if (s > size) break; \ if (s > size) break; \
if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \
if (val >= vals[p[s]]) break; \ if (val >= vals[p[s]]) break; \
p[k] = p[s]; k = s; \ p[k] = p[s]; k = s; \
} p[k] = temp; } } p[k] = temp; }
void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size)
{ {
if (size <= 1) if (size <= 1)
return; return;
p--; p--;
{ {
size_t i = size / 2; size_t i = size / 2;
do do
{ {
UInt32 temp = p[i]; UInt32 temp = p[i];
HeapSortRefDown(p, vals, i, size, temp); HeapSortRefDown(p, vals, i, size, temp);
} }
while (--i != 0); while (--i != 0);
} }
do do
{ {
UInt32 temp = p[size]; UInt32 temp = p[size];
p[size--] = p[1]; p[size--] = p[1];
HeapSortRefDown(p, vals, 1, size, temp); HeapSortRefDown(p, vals, 1, size, temp);
} }
while (size > 1); while (size > 1);
} }
*/ */

View File

@@ -1,18 +1,18 @@
/* Sort.h -- Sort functions /* Sort.h -- Sort functions
2014-04-05 : Igor Pavlov : Public domain */ 2014-04-05 : Igor Pavlov : Public domain */
#ifndef __7Z_SORT_H #ifndef __7Z_SORT_H
#define __7Z_SORT_H #define __7Z_SORT_H
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
void HeapSort(UInt32 *p, size_t size); void HeapSort(UInt32 *p, size_t size);
void HeapSort64(UInt64 *p, size_t size); void HeapSort64(UInt64 *p, size_t size);
/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */ /* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,95 +1,95 @@
/* Threads.c -- multithreading library /* Threads.c -- multithreading library
2017-06-26 : Igor Pavlov : Public domain */ 2017-06-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#ifndef UNDER_CE #ifndef UNDER_CE
#include <process.h> #include <process.h>
#endif #endif
#include "Threads.h" #include "Threads.h"
static WRes GetError() static WRes GetError()
{ {
DWORD res = GetLastError(); DWORD res = GetLastError();
return res ? (WRes)res : 1; return res ? (WRes)res : 1;
} }
static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); } static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
WRes HandlePtr_Close(HANDLE *p) WRes HandlePtr_Close(HANDLE *p)
{ {
if (*p != NULL) if (*p != NULL)
{ {
if (!CloseHandle(*p)) if (!CloseHandle(*p))
return GetError(); return GetError();
*p = NULL; *p = NULL;
} }
return 0; return 0;
} }
WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); }
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
{ {
/* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
#ifdef UNDER_CE #ifdef UNDER_CE
DWORD threadId; DWORD threadId;
*p = CreateThread(0, 0, func, param, 0, &threadId); *p = CreateThread(0, 0, func, param, 0, &threadId);
#else #else
unsigned threadId; unsigned threadId;
*p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
#endif #endif
/* maybe we must use errno here, but probably GetLastError() is also OK. */ /* maybe we must use errno here, but probably GetLastError() is also OK. */
return HandleToWRes(*p); return HandleToWRes(*p);
} }
static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
{ {
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
return HandleToWRes(*p); return HandleToWRes(*p);
} }
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }
WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }
WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }
WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
{ {
*p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
return HandleToWRes(*p); return HandleToWRes(*p);
} }
static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
{ return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)
{ return Semaphore_Release(p, (LONG)num, NULL); } { return Semaphore_Release(p, (LONG)num, NULL); }
WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }
WRes CriticalSection_Init(CCriticalSection *p) WRes CriticalSection_Init(CCriticalSection *p)
{ {
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
#ifdef _MSC_VER #ifdef _MSC_VER
__try __try
#endif #endif
{ {
InitializeCriticalSection(p); InitializeCriticalSection(p);
/* InitializeCriticalSectionAndSpinCount(p, 0); */ /* InitializeCriticalSectionAndSpinCount(p, 0); */
} }
#ifdef _MSC_VER #ifdef _MSC_VER
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; } __except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
#endif #endif
return 0; return 0;
} }

View File

@@ -1,68 +1,68 @@
/* Threads.h -- multithreading library /* Threads.h -- multithreading library
2017-06-18 : Igor Pavlov : Public domain */ 2017-06-18 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H #ifndef __7Z_THREADS_H
#define __7Z_THREADS_H #define __7Z_THREADS_H
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
#include "7zTypes.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
WRes HandlePtr_Close(HANDLE *h); WRes HandlePtr_Close(HANDLE *h);
WRes Handle_WaitObject(HANDLE h); WRes Handle_WaitObject(HANDLE h);
typedef HANDLE CThread; typedef HANDLE CThread;
#define Thread_Construct(p) *(p) = NULL #define Thread_Construct(p) *(p) = NULL
#define Thread_WasCreated(p) (*(p) != NULL) #define Thread_WasCreated(p) (*(p) != NULL)
#define Thread_Close(p) HandlePtr_Close(p) #define Thread_Close(p) HandlePtr_Close(p)
#define Thread_Wait(p) Handle_WaitObject(*(p)) #define Thread_Wait(p) Handle_WaitObject(*(p))
typedef typedef
#ifdef UNDER_CE #ifdef UNDER_CE
DWORD DWORD
#else #else
unsigned unsigned
#endif #endif
THREAD_FUNC_RET_TYPE; THREAD_FUNC_RET_TYPE;
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL #define THREAD_FUNC_CALL_TYPE MY_STD_CALL
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
typedef HANDLE CEvent; typedef HANDLE CEvent;
typedef CEvent CAutoResetEvent; typedef CEvent CAutoResetEvent;
typedef CEvent CManualResetEvent; typedef CEvent CManualResetEvent;
#define Event_Construct(p) *(p) = NULL #define Event_Construct(p) *(p) = NULL
#define Event_IsCreated(p) (*(p) != NULL) #define Event_IsCreated(p) (*(p) != NULL)
#define Event_Close(p) HandlePtr_Close(p) #define Event_Close(p) HandlePtr_Close(p)
#define Event_Wait(p) Handle_WaitObject(*(p)) #define Event_Wait(p) Handle_WaitObject(*(p))
WRes Event_Set(CEvent *p); WRes Event_Set(CEvent *p);
WRes Event_Reset(CEvent *p); WRes Event_Reset(CEvent *p);
WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
typedef HANDLE CSemaphore; typedef HANDLE CSemaphore;
#define Semaphore_Construct(p) *(p) = NULL #define Semaphore_Construct(p) *(p) = NULL
#define Semaphore_IsCreated(p) (*(p) != NULL) #define Semaphore_IsCreated(p) (*(p) != NULL)
#define Semaphore_Close(p) HandlePtr_Close(p) #define Semaphore_Close(p) HandlePtr_Close(p)
#define Semaphore_Wait(p) Handle_WaitObject(*(p)) #define Semaphore_Wait(p) Handle_WaitObject(*(p))
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
WRes Semaphore_Release1(CSemaphore *p); WRes Semaphore_Release1(CSemaphore *p);
typedef CRITICAL_SECTION CCriticalSection; typedef CRITICAL_SECTION CCriticalSection;
WRes CriticalSection_Init(CCriticalSection *p); WRes CriticalSection_Init(CCriticalSection *p);
#define CriticalSection_Delete(p) DeleteCriticalSection(p) #define CriticalSection_Delete(p) DeleteCriticalSection(p)
#define CriticalSection_Enter(p) EnterCriticalSection(p) #define CriticalSection_Enter(p) EnterCriticalSection(p)
#define CriticalSection_Leave(p) LeaveCriticalSection(p) #define CriticalSection_Leave(p) LeaveCriticalSection(p)
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

@@ -1,241 +1,241 @@
# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103 # TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=7z - Win32 Debug CFG=7z - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "7z.mak". !MESSAGE NMAKE /f "7z.mak".
!MESSAGE !MESSAGE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug" !MESSAGE NMAKE /f "7z.mak" CFG="7z - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
# PROP AllowPerConfigDependencies 0 # PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "" # PROP Scc_ProjName ""
# PROP Scc_LocalPath "" # PROP Scc_LocalPath ""
CPP=cl.exe CPP=cl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "7z - Win32 Release" !IF "$(CFG)" == "7z - Win32 Release"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0 # PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release" # PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release" # PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release" # PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release" # PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c # ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 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 /out:"c:\util\7zDec.exe" /opt:NOWIN98 # ADD 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 /out:"c:\util\7zDec.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none # SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "7z - Win32 Debug" !ELSEIF "$(CFG)" == "7z - Win32 Debug"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1 # PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug" # PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug" # PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 1 # PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug" # PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug" # PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # 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 BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c # ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe 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 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 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 /out:"c:\util\7zDec.exe" /pdbtype:sept # ADD 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 /out:"c:\util\7zDec.exe" /pdbtype:sept
!ENDIF !ENDIF
# Begin Target # Begin Target
# Name "7z - Win32 Release" # Name "7z - Win32 Release"
# Name "7z - Win32 Debug" # Name "7z - Win32 Debug"
# Begin Group "Common" # Begin Group "Common"
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\7z.h SOURCE=..\..\7z.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zAlloc.c SOURCE=..\..\7zAlloc.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zAlloc.h SOURCE=..\..\7zAlloc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zArcIn.c SOURCE=..\..\7zArcIn.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zBuf.c SOURCE=..\..\7zBuf.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zBuf.h SOURCE=..\..\7zBuf.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zCrc.c SOURCE=..\..\7zCrc.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zCrc.h SOURCE=..\..\7zCrc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zCrcOpt.c SOURCE=..\..\7zCrcOpt.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zDec.c SOURCE=..\..\7zDec.c
# ADD CPP /D "_7ZIP_PPMD_SUPPPORT" # ADD CPP /D "_7ZIP_PPMD_SUPPPORT"
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zFile.c SOURCE=..\..\7zFile.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zFile.h SOURCE=..\..\7zFile.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zStream.c SOURCE=..\..\7zStream.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zTypes.h SOURCE=..\..\7zTypes.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Bcj2.c SOURCE=..\..\Bcj2.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Bcj2.h SOURCE=..\..\Bcj2.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Bra.c SOURCE=..\..\Bra.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Bra.h SOURCE=..\..\Bra.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Bra86.c SOURCE=..\..\Bra86.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\BraIA64.c SOURCE=..\..\BraIA64.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\CpuArch.c SOURCE=..\..\CpuArch.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\CpuArch.h SOURCE=..\..\CpuArch.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Delta.c SOURCE=..\..\Delta.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Delta.h SOURCE=..\..\Delta.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Lzma2Dec.c SOURCE=..\..\Lzma2Dec.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Lzma2Dec.h SOURCE=..\..\Lzma2Dec.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\LzmaDec.c SOURCE=..\..\LzmaDec.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\LzmaDec.h SOURCE=..\..\LzmaDec.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Ppmd.h SOURCE=..\..\Ppmd.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Ppmd7.c SOURCE=..\..\Ppmd7.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Ppmd7.h SOURCE=..\..\Ppmd7.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Ppmd7Dec.c SOURCE=..\..\Ppmd7Dec.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "Spec" # Begin Group "Spec"
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\Compiler.h SOURCE=..\..\Compiler.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\Precomp.c SOURCE=.\Precomp.c
# ADD CPP /Yc"Precomp.h" # ADD CPP /Yc"Precomp.h"
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\Precomp.h SOURCE=.\Precomp.h
# End Source File # End Source File
# End Group # End Group
# Begin Source File # Begin Source File
SOURCE=.\7zMain.c SOURCE=.\7zMain.c
# End Source File # End Source File
# End Target # End Target
# End Project # End Project

View File

@@ -1,29 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00 Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
############################################################################### ###############################################################################
Project: "7z"=.\7z.dsp - Package Owner=<4> Project: "7z"=.\7z.dsp - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{
}}} }}}
Package=<4> Package=<4>
{{{ {{{
}}} }}}
############################################################################### ###############################################################################
Global: Global:
Package=<5> Package=<5>
{{{ {{{
}}} }}}
Package=<3> Package=<3>
{{{ {{{
}}} }}}
############################################################################### ###############################################################################

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* Precomp.c -- StdAfx /* Precomp.c -- StdAfx
2013-01-21 : Igor Pavlov : Public domain */ 2013-01-21 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"

View File

@@ -1,10 +1,10 @@
/* Precomp.h -- StdAfx /* Precomp.h -- StdAfx
2013-06-16 : Igor Pavlov : Public domain */ 2013-06-16 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H #ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H #define __7Z_PRECOMP_H
#include "../../Compiler.h" #include "../../Compiler.h"
#include "../../7zTypes.h" #include "../../7zTypes.h"
#endif #endif

View File

@@ -1,40 +1,40 @@
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe PROG = 7zDec.exe
C_OBJS = \ C_OBJS = \
$O\7zAlloc.obj \ $O\7zAlloc.obj \
$O\7zBuf.obj \ $O\7zBuf.obj \
$O\7zCrc.obj \ $O\7zCrc.obj \
$O\7zCrcOpt.obj \ $O\7zCrcOpt.obj \
$O\7zFile.obj \ $O\7zFile.obj \
$O\7zDec.obj \ $O\7zDec.obj \
$O\7zArcIn.obj \ $O\7zArcIn.obj \
$O\7zStream.obj \ $O\7zStream.obj \
$O\Bcj2.obj \ $O\Bcj2.obj \
$O\Bra.obj \ $O\Bra.obj \
$O\Bra86.obj \ $O\Bra86.obj \
$O\BraIA64.obj \ $O\BraIA64.obj \
$O\CpuArch.obj \ $O\CpuArch.obj \
$O\Delta.obj \ $O\Delta.obj \
$O\Lzma2Dec.obj \ $O\Lzma2Dec.obj \
$O\LzmaDec.obj \ $O\LzmaDec.obj \
$O\Ppmd7.obj \ $O\Ppmd7.obj \
$O\Ppmd7Dec.obj \ $O\Ppmd7Dec.obj \
7Z_OBJS = \ 7Z_OBJS = \
$O\7zMain.obj \ $O\7zMain.obj \
OBJS = \ OBJS = \
$O\Precomp.obj \ $O\Precomp.obj \
$(7Z_OBJS) \ $(7Z_OBJS) \
$(C_OBJS) \ $(C_OBJS) \
!include "../../../CPP/Build.mak" !include "../../../CPP/Build.mak"
$(7Z_OBJS): $(*B).c $(7Z_OBJS): $(*B).c
$(CCOMPL_USE) $(CCOMPL_USE)
$(C_OBJS): ../../$(*B).c $(C_OBJS): ../../$(*B).c
$(CCOMPL_USE) $(CCOMPL_USE)
$O\Precomp.obj: Precomp.c $O\Precomp.obj: Precomp.c
$(CCOMPL_PCH) $(CCOMPL_PCH)

View File

@@ -1,75 +1,75 @@
PROG = 7zDec PROG = 7zDec
CXX = gcc CXX = gcc
LIB = LIB =
RM = rm -f RM = rm -f
CFLAGS = -c -O2 -Wall CFLAGS = -c -O2 -Wall
OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o Delta.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o BraIA64.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o Delta.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o BraIA64.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
all: $(PROG) all: $(PROG)
$(PROG): $(OBJS) $(PROG): $(OBJS)
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
7zMain.o: 7zMain.c 7zMain.o: 7zMain.c
$(CXX) $(CFLAGS) 7zMain.c $(CXX) $(CFLAGS) 7zMain.c
7zAlloc.o: ../../7zAlloc.c 7zAlloc.o: ../../7zAlloc.c
$(CXX) $(CFLAGS) ../../7zAlloc.c $(CXX) $(CFLAGS) ../../7zAlloc.c
7zArcIn.o: ../../7zArcIn.c 7zArcIn.o: ../../7zArcIn.c
$(CXX) $(CFLAGS) ../../7zArcIn.c $(CXX) $(CFLAGS) ../../7zArcIn.c
7zBuf.o: ../../7zBuf.c 7zBuf.o: ../../7zBuf.c
$(CXX) $(CFLAGS) ../../7zBuf.c $(CXX) $(CFLAGS) ../../7zBuf.c
7zBuf2.o: ../../7zBuf2.c 7zBuf2.o: ../../7zBuf2.c
$(CXX) $(CFLAGS) ../../7zBuf2.c $(CXX) $(CFLAGS) ../../7zBuf2.c
7zCrc.o: ../../7zCrc.c 7zCrc.o: ../../7zCrc.c
$(CXX) $(CFLAGS) ../../7zCrc.c $(CXX) $(CFLAGS) ../../7zCrc.c
7zCrcOpt.o: ../../7zCrc.c 7zCrcOpt.o: ../../7zCrc.c
$(CXX) $(CFLAGS) ../../7zCrcOpt.c $(CXX) $(CFLAGS) ../../7zCrcOpt.c
7zDec.o: ../../7zDec.c 7zDec.o: ../../7zDec.c
$(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c $(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c
CpuArch.o: ../../CpuArch.c CpuArch.o: ../../CpuArch.c
$(CXX) $(CFLAGS) ../../CpuArch.c $(CXX) $(CFLAGS) ../../CpuArch.c
Delta.o: ../../Delta.c Delta.o: ../../Delta.c
$(CXX) $(CFLAGS) ../../Delta.c $(CXX) $(CFLAGS) ../../Delta.c
LzmaDec.o: ../../LzmaDec.c LzmaDec.o: ../../LzmaDec.c
$(CXX) $(CFLAGS) ../../LzmaDec.c $(CXX) $(CFLAGS) ../../LzmaDec.c
Lzma2Dec.o: ../../Lzma2Dec.c Lzma2Dec.o: ../../Lzma2Dec.c
$(CXX) $(CFLAGS) ../../Lzma2Dec.c $(CXX) $(CFLAGS) ../../Lzma2Dec.c
Bra.o: ../../Bra.c Bra.o: ../../Bra.c
$(CXX) $(CFLAGS) ../../Bra.c $(CXX) $(CFLAGS) ../../Bra.c
Bra86.o: ../../Bra86.c Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c $(CXX) $(CFLAGS) ../../Bra86.c
BraIA64.o: ../../BraIA64.c BraIA64.o: ../../BraIA64.c
$(CXX) $(CFLAGS) ../../BraIA64.c $(CXX) $(CFLAGS) ../../BraIA64.c
Bcj2.o: ../../Bcj2.c Bcj2.o: ../../Bcj2.c
$(CXX) $(CFLAGS) ../../Bcj2.c $(CXX) $(CFLAGS) ../../Bcj2.c
Ppmd7.o: ../../Ppmd7.c Ppmd7.o: ../../Ppmd7.c
$(CXX) $(CFLAGS) ../../Ppmd7.c $(CXX) $(CFLAGS) ../../Ppmd7.c
Ppmd7Dec.o: ../../Ppmd7Dec.c Ppmd7Dec.o: ../../Ppmd7Dec.c
$(CXX) $(CFLAGS) ../../Ppmd7Dec.c $(CXX) $(CFLAGS) ../../Ppmd7Dec.c
7zFile.o: ../../7zFile.c 7zFile.o: ../../7zFile.c
$(CXX) $(CFLAGS) ../../7zFile.c $(CXX) $(CFLAGS) ../../7zFile.c
7zStream.o: ../../7zStream.c 7zStream.o: ../../7zStream.c
$(CXX) $(CFLAGS) ../../7zStream.c $(CXX) $(CFLAGS) ../../7zStream.c
clean: clean:
-$(RM) $(PROG) $(OBJS) -$(RM) $(PROG) $(OBJS)

View File

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More