Merge pull request #4 from FnControlOption/2106

This commit is contained in:
Kornel
2021-12-18 11:01:24 +00:00
committed by GitHub
224 changed files with 13267 additions and 2922 deletions

View File

@@ -1,5 +1,5 @@
; 7zAsm.asm -- ASM macros ; 7zAsm.asm -- ASM macros
; 2021-02-07 : Igor Pavlov : Public domain ; 2021-08-29 : Igor Pavlov : Public domain
ifdef RAX ifdef RAX
x64 equ 1 x64 equ 1
@@ -27,6 +27,8 @@ else
endif endif
endif endif
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
MY_ASM_START macro MY_ASM_START macro
ifdef x64 ifdef x64
@@ -171,6 +173,7 @@ endm
; for fastcall and for WIN-x64 ; for fastcall and for WIN-x64
REG_PARAM_0_x equ x1 REG_PARAM_0_x equ x1
REG_PARAM_0 equ r1 REG_PARAM_0 equ r1
REG_PARAM_1_x equ x2
REG_PARAM_1 equ r2 REG_PARAM_1 equ r2
ifndef x64 ifndef x64
@@ -178,6 +181,7 @@ ifndef x64
REG_ABI_PARAM_0_x equ REG_PARAM_0_x REG_ABI_PARAM_0_x equ REG_PARAM_0_x
REG_ABI_PARAM_0 equ REG_PARAM_0 REG_ABI_PARAM_0 equ REG_PARAM_0
REG_ABI_PARAM_1_x equ REG_PARAM_1_x
REG_ABI_PARAM_1 equ REG_PARAM_1 REG_ABI_PARAM_1 equ REG_PARAM_1
else else
@@ -186,28 +190,39 @@ else
if (IS_LINUX eq 0) if (IS_LINUX eq 0)
; for WIN-x64: ; for WIN-x64:
REG_PARAM_2 equ r8 REG_PARAM_2_x equ x8
REG_PARAM_3 equ r9 REG_PARAM_2 equ r8
REG_PARAM_3 equ r9
REG_ABI_PARAM_0_x equ REG_PARAM_0_x REG_ABI_PARAM_0_x equ REG_PARAM_0_x
REG_ABI_PARAM_0 equ REG_PARAM_0 REG_ABI_PARAM_0 equ REG_PARAM_0
REG_ABI_PARAM_1_x equ REG_PARAM_1_x
REG_ABI_PARAM_1 equ REG_PARAM_1 REG_ABI_PARAM_1 equ REG_PARAM_1
REG_ABI_PARAM_2_x equ REG_PARAM_2_x
REG_ABI_PARAM_2 equ REG_PARAM_2 REG_ABI_PARAM_2 equ REG_PARAM_2
REG_ABI_PARAM_3 equ REG_PARAM_3 REG_ABI_PARAM_3 equ REG_PARAM_3
else else
; for LINUX-x64: ; for LINUX-x64:
REG_LINUX_PARAM_0_x equ x7 REG_LINUX_PARAM_0_x equ x7
REG_LINUX_PARAM_0 equ r7 REG_LINUX_PARAM_0 equ r7
REG_LINUX_PARAM_1 equ r6 REG_LINUX_PARAM_1_x equ x6
REG_LINUX_PARAM_2 equ r2 REG_LINUX_PARAM_1 equ r6
REG_LINUX_PARAM_3 equ r1 REG_LINUX_PARAM_2 equ r2
REG_LINUX_PARAM_3 equ r1
REG_LINUX_PARAM_4_x equ x8
REG_LINUX_PARAM_4 equ r8
REG_LINUX_PARAM_5 equ r9
REG_ABI_PARAM_0_x equ REG_LINUX_PARAM_0_x REG_ABI_PARAM_0_x equ REG_LINUX_PARAM_0_x
REG_ABI_PARAM_0 equ REG_LINUX_PARAM_0 REG_ABI_PARAM_0 equ REG_LINUX_PARAM_0
REG_ABI_PARAM_1_x equ REG_LINUX_PARAM_1_x
REG_ABI_PARAM_1 equ REG_LINUX_PARAM_1 REG_ABI_PARAM_1 equ REG_LINUX_PARAM_1
REG_ABI_PARAM_2 equ REG_LINUX_PARAM_2 REG_ABI_PARAM_2 equ REG_LINUX_PARAM_2
REG_ABI_PARAM_3 equ REG_LINUX_PARAM_3 REG_ABI_PARAM_3 equ REG_LINUX_PARAM_3
REG_ABI_PARAM_4_x equ REG_LINUX_PARAM_4_x
REG_ABI_PARAM_4 equ REG_LINUX_PARAM_4
REG_ABI_PARAM_5 equ REG_LINUX_PARAM_5
MY_ABI_LINUX_TO_WIN_2 macro MY_ABI_LINUX_TO_WIN_2 macro
mov r2, r6 mov r2, r6

513
Asm/x86/LzFindOpt.asm Normal file
View File

@@ -0,0 +1,513 @@
; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function
; 2021-07-21: Igor Pavlov : Public domain
;
ifndef x64
; x64=1
; .err <x64_IS_REQUIRED>
endif
include 7zAsm.asm
MY_ASM_START
_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE'
MY_ALIGN macro num:req
align num
endm
MY_ALIGN_32 macro
MY_ALIGN 32
endm
MY_ALIGN_64 macro
MY_ALIGN 64
endm
t0_L equ x0_L
t0_x equ x0
t0 equ r0
t1_x equ x3
t1 equ r3
cp_x equ t1_x
cp_r equ t1
m equ x5
m_r equ r5
len_x equ x6
len equ r6
diff_x equ x7
diff equ r7
len0 equ r10
len1_x equ x11
len1 equ r11
maxLen_x equ x12
maxLen equ r12
d equ r13
ptr0 equ r14
ptr1 equ r15
d_lim equ m_r
cycSize equ len_x
hash_lim equ len0
delta1_x equ len1_x
delta1_r equ len1
delta_x equ maxLen_x
delta_r equ maxLen
hash equ ptr0
src equ ptr1
if (IS_LINUX gt 0)
; r1 r2 r8 r9 : win32
; r7 r6 r2 r1 r8 r9 : linux
lenLimit equ r8
lenLimit_x equ x8
; pos_r equ r2
pos equ x2
cur equ r1
son equ r9
else
lenLimit equ REG_ABI_PARAM_2
lenLimit_x equ REG_ABI_PARAM_2_x
pos equ REG_ABI_PARAM_1_x
cur equ REG_ABI_PARAM_0
son equ REG_ABI_PARAM_3
endif
if (IS_LINUX gt 0)
maxLen_OFFS equ (REG_SIZE * (6 + 1))
else
cutValue_OFFS equ (REG_SIZE * (8 + 1 + 4))
d_OFFS equ (REG_SIZE + cutValue_OFFS)
maxLen_OFFS equ (REG_SIZE + d_OFFS)
endif
hash_OFFS equ (REG_SIZE + maxLen_OFFS)
limit_OFFS equ (REG_SIZE + hash_OFFS)
size_OFFS equ (REG_SIZE + limit_OFFS)
cycPos_OFFS equ (REG_SIZE + size_OFFS)
cycSize_OFFS equ (REG_SIZE + cycPos_OFFS)
posRes_OFFS equ (REG_SIZE + cycSize_OFFS)
if (IS_LINUX gt 0)
else
cutValue_PAR equ [r0 + cutValue_OFFS]
d_PAR equ [r0 + d_OFFS]
endif
maxLen_PAR equ [r0 + maxLen_OFFS]
hash_PAR equ [r0 + hash_OFFS]
limit_PAR equ [r0 + limit_OFFS]
size_PAR equ [r0 + size_OFFS]
cycPos_PAR equ [r0 + cycPos_OFFS]
cycSize_PAR equ [r0 + cycSize_OFFS]
posRes_PAR equ [r0 + posRes_OFFS]
cutValue_VAR equ DWORD PTR [r4 + 8 * 0]
cutValueCur_VAR equ DWORD PTR [r4 + 8 * 0 + 4]
cycPos_VAR equ DWORD PTR [r4 + 8 * 1 + 0]
cycSize_VAR equ DWORD PTR [r4 + 8 * 1 + 4]
hash_VAR equ QWORD PTR [r4 + 8 * 2]
limit_VAR equ QWORD PTR [r4 + 8 * 3]
size_VAR equ QWORD PTR [r4 + 8 * 4]
distances equ QWORD PTR [r4 + 8 * 5]
maxLen_VAR equ QWORD PTR [r4 + 8 * 6]
Old_RSP equ QWORD PTR [r4 + 8 * 7]
LOCAL_SIZE equ 8 * 8
COPY_VAR_32 macro dest_var, src_var
mov x3, src_var
mov dest_var, x3
endm
COPY_VAR_64 macro dest_var, src_var
mov r3, src_var
mov dest_var, r3
endm
; MY_ALIGN_64
MY_PROC GetMatchesSpecN_2, 13
MY_PUSH_PRESERVED_ABI_REGS
mov r0, RSP
lea r3, [r0 - LOCAL_SIZE]
and r3, -64
mov RSP, r3
mov Old_RSP, r0
if (IS_LINUX gt 0)
mov d, REG_ABI_PARAM_5 ; r13 = r9
mov cutValue_VAR, REG_ABI_PARAM_4_x ; = r8
mov son, REG_ABI_PARAM_3 ; r9 = r1
mov r8, REG_ABI_PARAM_2 ; r8 = r2
mov pos, REG_ABI_PARAM_1_x ; r2 = x6
mov r1, REG_ABI_PARAM_0 ; r1 = r7
else
COPY_VAR_32 cutValue_VAR, cutValue_PAR
mov d, d_PAR
endif
COPY_VAR_64 limit_VAR, limit_PAR
mov hash_lim, size_PAR
mov size_VAR, hash_lim
mov cp_x, cycPos_PAR
mov hash, hash_PAR
mov cycSize, cycSize_PAR
mov cycSize_VAR, cycSize
; we want cur in (rcx). So we change the cur and lenLimit variables
sub lenLimit, cur
neg lenLimit_x
inc lenLimit_x
mov t0_x, maxLen_PAR
sub t0, lenLimit
mov maxLen_VAR, t0
jmp main_loop
MY_ALIGN_64
fill_empty:
; ptr0 = *ptr1 = kEmptyHashValue;
mov QWORD PTR [ptr1], 0
inc pos
inc cp_x
mov DWORD PTR [d - 4], 0
cmp d, limit_VAR
jae fin
cmp hash, hash_lim
je fin
; MY_ALIGN_64
main_loop:
; UInt32 delta = *hash++;
mov diff_x, [hash] ; delta
add hash, 4
; mov cycPos_VAR, cp_x
inc cur
add d, 4
mov m, pos
sub m, diff_x; ; matchPos
; CLzRef *ptr1 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2;
lea ptr1, [son + 8 * cp_r]
; mov cycSize, cycSize_VAR
cmp pos, cycSize
jb directMode ; if (pos < cycSize_VAR)
; CYC MODE
cmp diff_x, cycSize
jae fill_empty ; if (delta >= cycSize_VAR)
xor t0_x, t0_x
mov cycPos_VAR, cp_x
sub cp_x, diff_x
; jae prepare_for_tree_loop
; add cp_x, cycSize
cmovb t0_x, cycSize
add cp_x, t0_x ; cp_x += (cycPos < delta ? cycSize : 0)
jmp prepare_for_tree_loop
directMode:
cmp diff_x, pos
je fill_empty ; if (delta == pos)
jae fin_error ; if (delta >= pos)
mov cycPos_VAR, cp_x
mov cp_x, m
prepare_for_tree_loop:
mov len0, lenLimit
mov hash_VAR, hash
; CLzRef *ptr0 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2 + 1;
lea ptr0, [ptr1 + 4]
; UInt32 *_distances = ++d;
mov distances, d
neg len0
mov len1, len0
mov t0_x, cutValue_VAR
mov maxLen, maxLen_VAR
mov cutValueCur_VAR, t0_x
MY_ALIGN_32
tree_loop:
neg diff
mov len, len0
cmp len1, len0
cmovb len, len1 ; len = (len1 < len0 ? len1 : len0);
add diff, cur
mov t0_x, [son + cp_r * 8] ; prefetch
movzx t0_x, BYTE PTR [diff + 1 * len]
lea cp_r, [son + cp_r * 8]
cmp [cur + 1 * len], t0_L
je matched_1
jb left_0
mov [ptr1], m
mov m, [cp_r + 4]
lea ptr1, [cp_r + 4]
sub diff, cur ; FIX32
jmp next_node
MY_ALIGN_32
left_0:
mov [ptr0], m
mov m, [cp_r]
mov ptr0, cp_r
sub diff, cur ; FIX32
; jmp next_node
; ------------ NEXT NODE ------------
; MY_ALIGN_32
next_node:
mov cycSize, cycSize_VAR
dec cutValueCur_VAR
je finish_tree
add diff_x, pos ; prev_match = pos + diff
cmp m, diff_x
jae fin_error ; if (new_match >= prev_match)
mov diff_x, pos
sub diff_x, m ; delta = pos - new_match
cmp pos, cycSize
jae cyc_mode_2 ; if (pos >= cycSize)
mov cp_x, m
test m, m
jne tree_loop ; if (m != 0)
finish_tree:
; ptr0 = *ptr1 = kEmptyHashValue;
mov DWORD PTR [ptr0], 0
mov DWORD PTR [ptr1], 0
inc pos
; _distances[-1] = (UInt32)(d - _distances);
mov t0, distances
mov t1, d
sub t1, t0
shr t1_x, 2
mov [t0 - 4], t1_x
cmp d, limit_VAR
jae fin ; if (d >= limit)
mov cp_x, cycPos_VAR
mov hash, hash_VAR
mov hash_lim, size_VAR
inc cp_x
cmp hash, hash_lim
jne main_loop ; if (hash != size)
jmp fin
MY_ALIGN_32
cyc_mode_2:
cmp diff_x, cycSize
jae finish_tree ; if (delta >= cycSize)
mov cp_x, cycPos_VAR
xor t0_x, t0_x
sub cp_x, diff_x ; cp_x = cycPos - delta
cmovb t0_x, cycSize
add cp_x, t0_x ; cp_x += (cycPos < delta ? cycSize : 0)
jmp tree_loop
MY_ALIGN_32
matched_1:
inc len
; cmp len_x, lenLimit_x
je short lenLimit_reach
movzx t0_x, BYTE PTR [diff + 1 * len]
cmp [cur + 1 * len], t0_L
jne mismatch
MY_ALIGN_32
match_loop:
; while (++len != lenLimit) (len[diff] != len[0]) ;
inc len
; cmp len_x, lenLimit_x
je short lenLimit_reach
movzx t0_x, BYTE PTR [diff + 1 * len]
cmp BYTE PTR [cur + 1 * len], t0_L
je match_loop
mismatch:
jb left_2
mov [ptr1], m
mov m, [cp_r + 4]
lea ptr1, [cp_r + 4]
mov len1, len
jmp max_update
MY_ALIGN_32
left_2:
mov [ptr0], m
mov m, [cp_r]
mov ptr0, cp_r
mov len0, len
max_update:
sub diff, cur ; restore diff
cmp maxLen, len
jae next_node
mov maxLen, len
add len, lenLimit
mov [d], len_x
mov t0_x, diff_x
not t0_x
mov [d + 4], t0_x
add d, 8
jmp next_node
MY_ALIGN_32
lenLimit_reach:
mov delta_r, cur
sub delta_r, diff
lea delta1_r, [delta_r - 1]
mov t0_x, [cp_r]
mov [ptr1], t0_x
mov t0_x, [cp_r + 4]
mov [ptr0], t0_x
mov [d], lenLimit_x
mov [d + 4], delta1_x
add d, 8
; _distances[-1] = (UInt32)(d - _distances);
mov t0, distances
mov t1, d
sub t1, t0
shr t1_x, 2
mov [t0 - 4], t1_x
mov hash, hash_VAR
mov hash_lim, size_VAR
inc pos
mov cp_x, cycPos_VAR
inc cp_x
mov d_lim, limit_VAR
mov cycSize, cycSize_VAR
; if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit)
; break;
cmp hash, hash_lim
je fin
cmp d, d_lim
jae fin
cmp delta_x, [hash]
jne main_loop
movzx t0_x, BYTE PTR [diff]
cmp [cur], t0_L
jne main_loop
; jmp main_loop ; bypass for debug
mov cycPos_VAR, cp_x
shl len, 3 ; cycSize * 8
sub diff, cur ; restore diff
xor t0_x, t0_x
cmp cp_x, delta_x ; cmp (cycPos_VAR, delta)
lea cp_r, [son + 8 * cp_r] ; dest
lea src, [cp_r + 8 * diff]
cmovb t0, len ; t0 = (cycPos_VAR < delta ? cycSize * 8 : 0)
add src, t0
add len, son ; len = son + cycSize * 8
MY_ALIGN_32
long_loop:
add hash, 4
; *(UInt64 *)(void *)ptr = ((const UInt64 *)(const void *)ptr)[diff];
mov t0, [src]
add src, 8
mov [cp_r], t0
add cp_r, 8
cmp src, len
cmove src, son ; if end of (son) buffer is reached, we wrap to begin
mov DWORD PTR [d], 2
mov [d + 4], lenLimit_x
mov [d + 8], delta1_x
add d, 12
inc cur
cmp hash, hash_lim
je long_footer
cmp delta_x, [hash]
jne long_footer
movzx t0_x, BYTE PTR [diff + 1 * cur]
cmp [cur], t0_L
jne long_footer
cmp d, d_lim
jb long_loop
long_footer:
sub cp_r, son
shr cp_r, 3
add pos, cp_x
sub pos, cycPos_VAR
mov cycSize, cycSize_VAR
cmp d, d_lim
jae fin
cmp hash, hash_lim
jne main_loop
jmp fin
fin_error:
xor d, d
fin:
mov RSP, Old_RSP
mov t0, [r4 + posRes_OFFS]
mov [t0], pos
mov r0, d
MY_POP_PRESERVED_ABI_REGS
MY_ENDP
_TEXT$LZFINDOPT ENDS
end

View File

@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types /* 7zTypes.h -- Basic types
2021-04-25 : Igor Pavlov : Public domain */ 2021-07-13 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
@@ -62,6 +62,8 @@ typedef int SRes;
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)
// #define MY_HRES_ERROR__INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR)
#else // _WIN32 #else // _WIN32
// #define ENV_HAVE_LSTAT // #define ENV_HAVE_LSTAT
@@ -95,6 +97,7 @@ typedef int WRes;
#define ERROR_DIRECTORY 267L #define ERROR_DIRECTORY 267L
#define ERROR_TOO_MANY_POSTS 298L #define ERROR_TOO_MANY_POSTS 298L
#define ERROR_INTERNAL_ERROR 1359L
#define ERROR_INVALID_REPARSE_DATA 4392L #define ERROR_INVALID_REPARSE_DATA 4392L
#define ERROR_REPARSE_TAG_INVALID 4393L #define ERROR_REPARSE_TAG_INVALID 4393L
#define ERROR_REPARSE_TAG_MISMATCH 4394L #define ERROR_REPARSE_TAG_MISMATCH 4394L
@@ -206,6 +209,8 @@ typedef size_t SIZE_T;
#endif // _WIN32 #endif // _WIN32
#define MY_HRES_ERROR__INTERNAL_ERROR ((HRESULT)0x8007054FL)
#ifdef _SZ_NO_INT_64 #ifdef _SZ_NO_INT_64

View File

@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 21 #define MY_VER_MAJOR 21
#define MY_VER_MINOR 02 #define MY_VER_MINOR 06
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "21.02 alpha" #define MY_VERSION_NUMBERS "21.06"
#define MY_VERSION MY_VERSION_NUMBERS #define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME #ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION #define MY_VERSION_CPU MY_VERSION
#endif #endif
#define MY_DATE "2021-05-06" #define MY_DATE "2021-11-24"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"

View File

@@ -5,6 +5,7 @@ MY_ASM = jwasm
MY_ASM = asmc MY_ASM = asmc
PROGPATH = $(O)/$(PROG) PROGPATH = $(O)/$(PROG)
PROGPATH_STATIC = $(O)/$(PROG)s
# for object file # for object file
@@ -53,7 +54,7 @@ endif
PROGPATH = $(O)/$(PROG)$(SHARED_EXT) PROGPATH = $(O)/$(PROG)$(SHARED_EXT)
PROGPATH_STATIC = $(O)/$(PROG)s$(SHARED_EXT)
ifndef O ifndef O
O=_o O=_o
@@ -82,7 +83,7 @@ MY_MKDIR=mkdir -p
# LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl # LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl
LIB2 = -lpthread -ldl LIB2 = -lpthread -ldl
DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(OBJS) DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS)
endif endif
@@ -108,14 +109,23 @@ CXX_WARN_FLAGS =
CXXFLAGS = $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(CXXFLAGS_EXTRA) $(CC_SHARED) -o $@ $(CXX_WARN_FLAGS) CXXFLAGS = $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(CXXFLAGS_EXTRA) $(CC_SHARED) -o $@ $(CXX_WARN_FLAGS)
all: $(O) $(PROGPATH) STATIC_TARGET=
ifdef COMPL_STATIC
STATIC_TARGET=$(PROGPATH_STATIC)
endif
all: $(O) $(PROGPATH) $(STATIC_TARGET)
$(O): $(O):
$(MY_MKDIR) $(O) $(MY_MKDIR) $(O)
LFLAGS_ALL = -s $(MY_ARCH_2) $(LDFLAGS) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2)
$(PROGPATH): $(OBJS) $(PROGPATH): $(OBJS)
$(CXX) -s -o $(PROGPATH) $(MY_ARCH_2) $(LDFLAGS) $(OBJS) $(MY_LIBS) $(LIB2) $(CXX) -o $(PROGPATH) $(LFLAGS_ALL)
$(PROGPATH_STATIC): $(OBJS)
$(CXX) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL)
ifndef NO_DEFAULT_RES ifndef NO_DEFAULT_RES
@@ -174,6 +184,8 @@ $O/LzFind.o: ../../../C/LzFind.c
# ifdef MT_FILES # ifdef MT_FILES
$O/LzFindMt.o: ../../../C/LzFindMt.c $O/LzFindMt.o: ../../../C/LzFindMt.c
$(CC) $(CFLAGS) $< $(CC) $(CFLAGS) $<
$O/LzFindOpt.o: ../../../C/LzFindOpt.c
$(CC) $(CFLAGS) $<
$O/Threads.o: ../../../C/Threads.c $O/Threads.o: ../../../C/Threads.c
$(CC) $(CFLAGS) $< $(CC) $(CFLAGS) $<

10
C/Aes.c
View File

@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption /* Aes.c -- AES encryption / decryption
2021-04-01 : Igor Pavlov : Public domain */ 2021-05-13 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -365,10 +365,10 @@ void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
*((UInt32 *)(void *)data) ^= t; *((UInt32 *)(void *)data) ^= t;
#else #else
data[0] ^= (t & 0xFF); data[0] = (Byte)(data[0] ^ (t & 0xFF));
data[1] ^= ((t >> 8) & 0xFF); data[1] = (Byte)(data[1] ^ ((t >> 8) & 0xFF));
data[2] ^= ((t >> 16) & 0xFF); data[2] = (Byte)(data[2] ^ ((t >> 16) & 0xFF));
data[3] ^= ((t >> 24)); data[3] = (Byte)(data[3] ^ ((t >> 24)));
#endif #endif
} }
} }

View File

@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions /* Alloc.c -- Memory allocation functions
2020-10-29 : Igor Pavlov : Public domain */ 2021-07-13 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -247,14 +247,14 @@ static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc
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 };
#ifdef _WIN32
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 };
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_MidAlloc = { SzMidAlloc, SzMidFree };
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#endif
/* /*
uintptr_t : <stdint.h> C99 (optional) uintptr_t : <stdint.h> C99 (optional)

View File

@@ -1,5 +1,5 @@
/* Alloc.h -- Memory allocation functions /* Alloc.h -- Memory allocation functions
2021-02-08 : Igor Pavlov : Public domain */ 2021-07-13 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H #ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H #define __COMMON_ALLOC_H
@@ -30,8 +30,15 @@ void BigFree(void *address);
#endif #endif
extern const ISzAlloc g_Alloc; extern const ISzAlloc g_Alloc;
#ifdef _WIN32
extern const ISzAlloc g_BigAlloc; extern const ISzAlloc g_BigAlloc;
extern const ISzAlloc g_MidAlloc; extern const ISzAlloc g_MidAlloc;
#else
#define g_BigAlloc g_AlignedAlloc
#define g_MidAlloc g_AlignedAlloc
#endif
extern const ISzAlloc g_AlignedAlloc; extern const ISzAlloc g_AlignedAlloc;

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2021-04-28 : Igor Pavlov : Public domain */ 2021-07-13 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -278,6 +278,30 @@ BoolInt CPU_IsSupported_SHA()
#include <Windows.h> #include <Windows.h>
#endif #endif
BoolInt CPU_IsSupported_AVX2()
{
Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT
#ifdef _WIN32
#define MY__PF_XSAVE_ENABLED 17
if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED))
return False;
#endif
if (!x86cpuid_CheckAndRead(&p))
return False;
if (p.maxFunc < 7)
return False;
{
UInt32 d[4] = { 0 };
MyCPUID(7, &d[0], &d[1], &d[2], &d[3]);
// printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]);
return 1
& (d[1] >> 5); // avx2
}
}
BoolInt CPU_IsSupported_VAES_AVX2() BoolInt CPU_IsSupported_VAES_AVX2()
{ {
Cx86cpuid p; Cx86cpuid p;
@@ -329,10 +353,9 @@ BoolInt CPU_IsSupported_PageGB()
#include <Windows.h> #include <Windows.h>
BoolInt CPU_IsSupported_CRC32() BoolInt CPU_IsSupported_CRC32() { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
{ return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } BoolInt CPU_IsSupported_CRYPTO() { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
BoolInt CPU_IsSupported_CRYPTO() BoolInt CPU_IsSupported_NEON() { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
{ return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
#else #else
@@ -356,17 +379,27 @@ static void Print_sysctlbyname(const char *name)
} }
*/ */
BoolInt CPU_IsSupported_CRC32(void) static BoolInt My_sysctlbyname_Get_BoolInt(const char *name)
{ {
UInt32 val = 0;
if (My_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1)
return 1;
return 0;
}
/* /*
Print_sysctlbyname("hw.pagesize"); Print_sysctlbyname("hw.pagesize");
Print_sysctlbyname("machdep.cpu.brand_string"); Print_sysctlbyname("machdep.cpu.brand_string");
*/ */
UInt32 val = 0; BoolInt CPU_IsSupported_CRC32(void)
if (My_sysctlbyname_Get_UInt32("hw.optional.armv8_crc32", &val) == 0 && val == 1) {
return 1; return My_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32");
return 0; }
BoolInt CPU_IsSupported_NEON(void)
{
return My_sysctlbyname_Get_BoolInt("hw.optional.neon");
} }
#ifdef MY_CPU_ARM64 #ifdef MY_CPU_ARM64
@@ -390,18 +423,25 @@ BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
#include <asm/hwcap.h> #include <asm/hwcap.h>
#define MY_HWCAP_CHECK_FUNC_2(name1, name2) \
BoolInt CPU_IsSupported_ ## name1() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name2)) ? 1 : 0; }
#ifdef MY_CPU_ARM64 #ifdef MY_CPU_ARM64
#define MY_HWCAP_CHECK_FUNC(name) \ #define MY_HWCAP_CHECK_FUNC(name) \
BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP) & (HWCAP_ ## name)) ? 1 : 0; } MY_HWCAP_CHECK_FUNC_2(name, name)
MY_HWCAP_CHECK_FUNC_2(NEON, ASIMD)
// MY_HWCAP_CHECK_FUNC (ASIMD)
#elif defined(MY_CPU_ARM) #elif defined(MY_CPU_ARM)
#define MY_HWCAP_CHECK_FUNC(name) \ #define MY_HWCAP_CHECK_FUNC(name) \
BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; } BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; }
MY_HWCAP_CHECK_FUNC_2(NEON, NEON)
#endif #endif
#else // USE_HWCAP #else // USE_HWCAP
#define MY_HWCAP_CHECK_FUNC(name) \ #define MY_HWCAP_CHECK_FUNC(name) \
BoolInt CPU_IsSupported_ ## name() { return 0; } BoolInt CPU_IsSupported_ ## name() { return 0; }
MY_HWCAP_CHECK_FUNC(NEON)
#endif // USE_HWCAP #endif // USE_HWCAP

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2021-04-25 : Igor Pavlov : Public domain */ 2021-07-13 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@@ -225,7 +225,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif #endif
#else #else
#ifdef __xlC__ #ifdef __xlC__
// for XLC compiler:
#define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)") #define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)")
#define MY_CPU_pragma_pop _Pragma("pack()") #define MY_CPU_pragma_pop _Pragma("pack()")
#else #else
@@ -253,8 +252,12 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#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) #define MY_CPU_LE_UNALIGN
#define MY_CPU_LE_UNALIGN_64
#elif defined(__ARM_FEATURE_UNALIGNED)
/* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.
So we can't use unaligned 64-bit operations. */
#define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN
#endif #endif
#endif #endif
@@ -264,11 +267,15 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#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))
#ifdef MY_CPU_LE_UNALIGN_64
#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) #define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#endif
#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); } #define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); } #define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
#ifdef MY_CPU_LE_UNALIGN_64
#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } #define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
#endif
#else #else
@@ -282,8 +289,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
((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 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); }
@@ -294,12 +299,22 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
_ppp_[2] = (Byte)(_vvv_ >> 16); \ _ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); } _ppp_[3] = (Byte)(_vvv_ >> 24); }
#endif
#ifndef MY_CPU_LE_UNALIGN_64
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#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
@@ -392,6 +407,7 @@ int x86cpuid_GetFirm(const Cx86cpuid *p);
BoolInt CPU_Is_InOrder(void); BoolInt CPU_Is_InOrder(void);
BoolInt CPU_IsSupported_AES(void); BoolInt CPU_IsSupported_AES(void);
BoolInt CPU_IsSupported_AVX2(void);
BoolInt CPU_IsSupported_VAES_AVX2(void); BoolInt CPU_IsSupported_VAES_AVX2(void);
BoolInt CPU_IsSupported_SSSE3(void); BoolInt CPU_IsSupported_SSSE3(void);
BoolInt CPU_IsSupported_SSE41(void); BoolInt CPU_IsSupported_SSE41(void);
@@ -401,6 +417,7 @@ BoolInt CPU_IsSupported_PageGB(void);
#elif defined(MY_CPU_ARM_OR_ARM64) #elif defined(MY_CPU_ARM_OR_ARM64)
BoolInt CPU_IsSupported_CRC32(void); BoolInt CPU_IsSupported_CRC32(void);
BoolInt CPU_IsSupported_NEON(void);
#if defined(_WIN32) #if defined(_WIN32)
BoolInt CPU_IsSupported_CRYPTO(void); BoolInt CPU_IsSupported_CRYPTO(void);

View File

@@ -1,5 +1,5 @@
/* DllSecur.c -- DLL loading security /* DllSecur.c -- DLL loading security
2018-02-21 : Igor Pavlov : Public domain */ 2021-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -43,7 +43,7 @@ void My_SetDefaultDllDirectories()
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"); (void(*)())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;
@@ -66,7 +66,7 @@ void LoadSecurityDlls()
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"); (void(*)())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;

1000
C/LzFind.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2021-02-09 : Igor Pavlov : Public domain */ 2021-07-13 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
@@ -15,7 +15,7 @@ typedef struct _CMatchFinder
Byte *buffer; Byte *buffer;
UInt32 pos; UInt32 pos;
UInt32 posLimit; UInt32 posLimit;
UInt32 streamPos; UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */
UInt32 lenLimit; UInt32 lenLimit;
UInt32 cyclicBufferPos; UInt32 cyclicBufferPos;
@@ -51,17 +51,19 @@ typedef struct _CMatchFinder
UInt64 expectedDataSize; UInt64 expectedDataSize;
} CMatchFinder; } CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((const Byte *)(p)->buffer)
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) #define Inline_MatchFinder_GetNumAvailableBytes(p) ((UInt32)((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);
@@ -76,10 +78,21 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
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);
/*
#define Inline_MatchFinder_InitPos(p, val) \
(p)->pos = (val); \
(p)->streamPos = (val);
*/
#define Inline_MatchFinder_ReduceOffsets(p, subValue) \
(p)->pos -= (subValue); \
(p)->streamPos -= (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, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 maxLen); UInt32 *distances, UInt32 maxLen);
/* /*
@@ -91,7 +104,7 @@ Conditions:
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
@@ -101,21 +114,23 @@ typedef struct _IMatchFinder
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; } IMatchFinder2;
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *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_4(CMatchFinder *p);
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);
void LzFindPrepare(void);
EXTERN_C_END EXTERN_C_END
#endif #endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2019-11-05 : Igor Pavlov : Public domain */ 2021-07-12 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H #ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H #define __LZ_FIND_MT_H
@@ -11,22 +11,24 @@ EXTERN_C_BEGIN
typedef struct _CMtSync typedef struct _CMtSync
{ {
UInt32 numProcessedBlocks;
CThread thread;
UInt64 affinity;
BoolInt wasCreated; BoolInt wasCreated;
BoolInt needStart; BoolInt needStart;
BoolInt csWasInitialized;
BoolInt csWasEntered;
BoolInt exit; BoolInt exit;
BoolInt stopWriting; BoolInt stopWriting;
CThread thread;
CAutoResetEvent canStart; CAutoResetEvent canStart;
CAutoResetEvent wasStarted;
CAutoResetEvent wasStopped; CAutoResetEvent wasStopped;
CSemaphore freeSemaphore; CSemaphore freeSemaphore;
CSemaphore filledSemaphore; CSemaphore filledSemaphore;
BoolInt csWasInitialized;
BoolInt csWasEntered;
CCriticalSection cs; CCriticalSection cs;
UInt32 numProcessedBlocks; // UInt32 numBlocks_Sent;
UInt64 affinity;
} CMtSync; } CMtSync;
typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances); typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
@@ -42,8 +44,8 @@ typedef struct _CMatchFinderMt
/* LZ */ /* LZ */
const Byte *pointerToCurPos; const Byte *pointerToCurPos;
UInt32 *btBuf; UInt32 *btBuf;
UInt32 btBufPos; const UInt32 *btBufPos;
UInt32 btBufPosLimit; const UInt32 *btBufPosLimit;
UInt32 lzPos; UInt32 lzPos;
UInt32 btNumAvailBytes; UInt32 btNumAvailBytes;
@@ -54,6 +56,10 @@ typedef struct _CMatchFinderMt
const UInt32 *crc; const UInt32 *crc;
Mf_Mix_Matches MixMatchesFunc; Mf_Mix_Matches MixMatchesFunc;
UInt32 failure_LZ_BT; // failure in BT transfered to LZ
// UInt32 failure_LZ_LZ; // failure in LZ tables
UInt32 failureBuf[1];
// UInt32 crc[256];
/* LZ + BT */ /* LZ + BT */
CMtSync btSync; CMtSync btSync;
@@ -64,6 +70,8 @@ typedef struct _CMatchFinderMt
UInt32 hashBufPos; UInt32 hashBufPos;
UInt32 hashBufPosLimit; UInt32 hashBufPosLimit;
UInt32 hashNumAvail; UInt32 hashNumAvail;
UInt32 failure_BT;
CLzRef *son; CLzRef *son;
UInt32 matchMaxLen; UInt32 matchMaxLen;
@@ -71,7 +79,7 @@ typedef struct _CMatchFinderMt
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 */
@@ -81,13 +89,19 @@ typedef struct _CMatchFinderMt
/* Hash */ /* Hash */
Mf_GetHeads GetHeadsFunc; Mf_GetHeads GetHeadsFunc;
CMatchFinder *MatchFinder; CMatchFinder *MatchFinder;
// CMatchFinder MatchFinder;
} CMatchFinderMt; } CMatchFinderMt;
// only for Mt part
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, IMatchFinder2 *vTable);
/* call MatchFinderMt_InitMt() before IMatchFinder::Init() */
SRes MatchFinderMt_InitMt(CMatchFinderMt *p);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
EXTERN_C_END EXTERN_C_END

578
C/LzFindOpt.c Normal file
View File

@@ -0,0 +1,578 @@
/* LzFindOpt.c -- multithreaded Match finder for LZ algorithms
2021-07-13 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#include "LzFind.h"
// #include "LzFindMt.h"
// #define LOG_ITERS
// #define LOG_THREAD
#ifdef LOG_THREAD
#include <stdio.h>
#define PRF(x) x
#else
// #define PRF(x)
#endif
#ifdef LOG_ITERS
#include <stdio.h>
UInt64 g_NumIters_Tree;
UInt64 g_NumIters_Loop;
UInt64 g_NumIters_Bytes;
#define LOG_ITER(x) x
#else
#define LOG_ITER(x)
#endif
// ---------- BT THREAD ----------
#define USE_SON_PREFETCH
#define USE_LONG_MATCH_OPT
#define kEmptyHashValue 0
// #define CYC_TO_POS_OFFSET 0
// #define CYC_TO_POS_OFFSET 1 // for debug
/*
MY_NO_INLINE
UInt32 * MY_FAST_CALL GetMatchesSpecN_1(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son,
UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, UInt32 *posRes)
{
do
{
UInt32 delta;
if (hash == size)
break;
delta = *hash++;
if (delta == 0 || delta > (UInt32)pos)
return NULL;
lenLimit++;
if (delta == (UInt32)pos)
{
CLzRef *ptr1 = son + ((size_t)pos << 1) - CYC_TO_POS_OFFSET * 2;
*d++ = 0;
ptr1[0] = kEmptyHashValue;
ptr1[1] = kEmptyHashValue;
}
else
{
UInt32 *_distances = ++d;
CLzRef *ptr0 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2 + 1;
CLzRef *ptr1 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2;
const Byte *len0 = cur, *len1 = cur;
UInt32 cutValue = _cutValue;
const Byte *maxLen = cur + _maxLen;
for (LOG_ITER(g_NumIters_Tree++);;)
{
LOG_ITER(g_NumIters_Loop++);
{
const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta;
CLzRef *pair = son + ((size_t)(((ptrdiff_t)pos - CYC_TO_POS_OFFSET) + diff) << 1);
const Byte *len = (len0 < len1 ? len0 : len1);
#ifdef USE_SON_PREFETCH
const UInt32 pair0 = *pair;
#endif
if (len[diff] == len[0])
{
if (++len != lenLimit && len[diff] == len[0])
while (++len != lenLimit)
{
LOG_ITER(g_NumIters_Bytes++);
if (len[diff] != len[0])
break;
}
if (maxLen < len)
{
maxLen = len;
*d++ = (UInt32)(len - cur);
*d++ = delta - 1;
if (len == lenLimit)
{
const UInt32 pair1 = pair[1];
*ptr1 =
#ifdef USE_SON_PREFETCH
pair0;
#else
pair[0];
#endif
*ptr0 = pair1;
_distances[-1] = (UInt32)(d - _distances);
#ifdef USE_LONG_MATCH_OPT
if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit)
break;
{
for (;;)
{
hash++;
pos++;
cur++;
lenLimit++;
{
CLzRef *ptr = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2;
#if 0
*(UInt64 *)(void *)ptr = ((const UInt64 *)(const void *)ptr)[diff];
#else
const UInt32 p0 = ptr[0 + (diff * 2)];
const UInt32 p1 = ptr[1 + (diff * 2)];
ptr[0] = p0;
ptr[1] = p1;
// ptr[0] = ptr[0 + (diff * 2)];
// ptr[1] = ptr[1 + (diff * 2)];
#endif
}
// PrintSon(son + 2, pos - 1);
// printf("\npos = %x delta = %x\n", pos, delta);
len++;
*d++ = 2;
*d++ = (UInt32)(len - cur);
*d++ = delta - 1;
if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit)
break;
}
}
#endif
break;
}
}
}
{
const UInt32 curMatch = (UInt32)pos - delta; // (UInt32)(pos + diff);
if (len[diff] < len[0])
{
delta = pair[1];
if (delta >= curMatch)
return NULL;
*ptr1 = curMatch;
ptr1 = pair + 1;
len1 = len;
}
else
{
delta = *pair;
if (delta >= curMatch)
return NULL;
*ptr0 = curMatch;
ptr0 = pair;
len0 = len;
}
delta = (UInt32)pos - delta;
if (--cutValue == 0 || delta >= pos)
{
*ptr0 = *ptr1 = kEmptyHashValue;
_distances[-1] = (UInt32)(d - _distances);
break;
}
}
}
} // for (tree iterations)
}
pos++;
cur++;
}
while (d < limit);
*posRes = (UInt32)pos;
return d;
}
*/
/* define cbs if you use 2 functions.
GetMatchesSpecN_1() : (pos < _cyclicBufferSize)
GetMatchesSpecN_2() : (pos >= _cyclicBufferSize)
do not define cbs if you use 1 function:
GetMatchesSpecN_2()
*/
// #define cbs _cyclicBufferSize
/*
we use size_t for (pos) and (_cyclicBufferPos_ instead of UInt32
to eliminate "movsx" BUG in old MSVC x64 compiler.
*/
UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son,
UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size,
size_t _cyclicBufferPos, UInt32 _cyclicBufferSize,
UInt32 *posRes);
MY_NO_INLINE
UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son,
UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size,
size_t _cyclicBufferPos, UInt32 _cyclicBufferSize,
UInt32 *posRes)
{
do // while (hash != size)
{
UInt32 delta;
#ifndef cbs
UInt32 cbs;
#endif
if (hash == size)
break;
delta = *hash++;
if (delta == 0)
return NULL;
lenLimit++;
#ifndef cbs
cbs = _cyclicBufferSize;
if ((UInt32)pos < cbs)
{
if (delta > (UInt32)pos)
return NULL;
cbs = (UInt32)pos;
}
#endif
if (delta >= cbs)
{
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
*d++ = 0;
ptr1[0] = kEmptyHashValue;
ptr1[1] = kEmptyHashValue;
}
else
{
UInt32 *_distances = ++d;
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
UInt32 cutValue = _cutValue;
const Byte *len0 = cur, *len1 = cur;
const Byte *maxLen = cur + _maxLen;
// if (cutValue == 0) { *ptr0 = *ptr1 = kEmptyHashValue; } else
for (LOG_ITER(g_NumIters_Tree++);;)
{
LOG_ITER(g_NumIters_Loop++);
{
// SPEC code
CLzRef *pair = son + ((size_t)((ptrdiff_t)_cyclicBufferPos - (ptrdiff_t)delta
+ (ptrdiff_t)(UInt32)(_cyclicBufferPos < delta ? cbs : 0)
) << 1);
const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta;
const Byte *len = (len0 < len1 ? len0 : len1);
#ifdef USE_SON_PREFETCH
const UInt32 pair0 = *pair;
#endif
if (len[diff] == len[0])
{
if (++len != lenLimit && len[diff] == len[0])
while (++len != lenLimit)
{
LOG_ITER(g_NumIters_Bytes++);
if (len[diff] != len[0])
break;
}
if (maxLen < len)
{
maxLen = len;
*d++ = (UInt32)(len - cur);
*d++ = delta - 1;
if (len == lenLimit)
{
const UInt32 pair1 = pair[1];
*ptr1 =
#ifdef USE_SON_PREFETCH
pair0;
#else
pair[0];
#endif
*ptr0 = pair1;
_distances[-1] = (UInt32)(d - _distances);
#ifdef USE_LONG_MATCH_OPT
if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit)
break;
{
for (;;)
{
*d++ = 2;
*d++ = (UInt32)(lenLimit - cur);
*d++ = delta - 1;
cur++;
lenLimit++;
// SPEC
_cyclicBufferPos++;
{
// SPEC code
CLzRef *dest = son + ((size_t)(_cyclicBufferPos) << 1);
const CLzRef *src = dest + ((diff
+ (ptrdiff_t)(UInt32)((_cyclicBufferPos < delta) ? cbs : 0)) << 1);
// CLzRef *ptr = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2;
#if 0
*(UInt64 *)(void *)dest = *((const UInt64 *)(const void *)src);
#else
const UInt32 p0 = src[0];
const UInt32 p1 = src[1];
dest[0] = p0;
dest[1] = p1;
#endif
}
pos++;
hash++;
if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit)
break;
} // for() end for long matches
}
#endif
break; // break from TREE iterations
}
}
}
{
const UInt32 curMatch = (UInt32)pos - delta; // (UInt32)(pos + diff);
if (len[diff] < len[0])
{
delta = pair[1];
*ptr1 = curMatch;
ptr1 = pair + 1;
len1 = len;
if (delta >= curMatch)
return NULL;
}
else
{
delta = *pair;
*ptr0 = curMatch;
ptr0 = pair;
len0 = len;
if (delta >= curMatch)
return NULL;
}
delta = (UInt32)pos - delta;
if (--cutValue == 0 || delta >= cbs)
{
*ptr0 = *ptr1 = kEmptyHashValue;
_distances[-1] = (UInt32)(d - _distances);
break;
}
}
}
} // for (tree iterations)
}
pos++;
_cyclicBufferPos++;
cur++;
}
while (d < limit);
*posRes = (UInt32)pos;
return d;
}
/*
typedef UInt32 uint32plus; // size_t
UInt32 * MY_FAST_CALL GetMatchesSpecN_3(uint32plus lenLimit, size_t pos, const Byte *cur, CLzRef *son,
UInt32 _cutValue, UInt32 *d, uint32plus _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size,
size_t _cyclicBufferPos, UInt32 _cyclicBufferSize,
UInt32 *posRes)
{
do // while (hash != size)
{
UInt32 delta;
#ifndef cbs
UInt32 cbs;
#endif
if (hash == size)
break;
delta = *hash++;
if (delta == 0)
return NULL;
#ifndef cbs
cbs = _cyclicBufferSize;
if ((UInt32)pos < cbs)
{
if (delta > (UInt32)pos)
return NULL;
cbs = (UInt32)pos;
}
#endif
if (delta >= cbs)
{
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
*d++ = 0;
ptr1[0] = kEmptyHashValue;
ptr1[1] = kEmptyHashValue;
}
else
{
CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
UInt32 *_distances = ++d;
uint32plus len0 = 0, len1 = 0;
UInt32 cutValue = _cutValue;
uint32plus maxLen = _maxLen;
// lenLimit++; // const Byte *lenLimit = cur + _lenLimit;
for (LOG_ITER(g_NumIters_Tree++);;)
{
LOG_ITER(g_NumIters_Loop++);
{
// const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta;
CLzRef *pair = son + ((size_t)((ptrdiff_t)_cyclicBufferPos - delta
+ (ptrdiff_t)(UInt32)(_cyclicBufferPos < delta ? cbs : 0)
) << 1);
const Byte *pb = cur - delta;
uint32plus len = (len0 < len1 ? len0 : len1);
#ifdef USE_SON_PREFETCH
const UInt32 pair0 = *pair;
#endif
if (pb[len] == cur[len])
{
if (++len != lenLimit && pb[len] == cur[len])
while (++len != lenLimit)
if (pb[len] != cur[len])
break;
if (maxLen < len)
{
maxLen = len;
*d++ = (UInt32)len;
*d++ = delta - 1;
if (len == lenLimit)
{
{
const UInt32 pair1 = pair[1];
*ptr0 = pair1;
*ptr1 =
#ifdef USE_SON_PREFETCH
pair0;
#else
pair[0];
#endif
}
_distances[-1] = (UInt32)(d - _distances);
#ifdef USE_LONG_MATCH_OPT
if (hash == size || *hash != delta || pb[lenLimit] != cur[lenLimit] || d >= limit)
break;
{
const ptrdiff_t diff = (ptrdiff_t)0 - (ptrdiff_t)delta;
for (;;)
{
*d++ = 2;
*d++ = (UInt32)lenLimit;
*d++ = delta - 1;
_cyclicBufferPos++;
{
CLzRef *dest = son + ((size_t)_cyclicBufferPos << 1);
const CLzRef *src = dest + ((diff +
(ptrdiff_t)(UInt32)(_cyclicBufferPos < delta ? cbs : 0)) << 1);
#if 0
*(UInt64 *)(void *)dest = *((const UInt64 *)(const void *)src);
#else
const UInt32 p0 = src[0];
const UInt32 p1 = src[1];
dest[0] = p0;
dest[1] = p1;
#endif
}
hash++;
pos++;
cur++;
pb++;
if (hash == size || *hash != delta || pb[lenLimit] != cur[lenLimit] || d >= limit)
break;
}
}
#endif
break;
}
}
}
{
const UInt32 curMatch = (UInt32)pos - delta;
if (pb[len] < cur[len])
{
delta = pair[1];
*ptr1 = curMatch;
ptr1 = pair + 1;
len1 = len;
}
else
{
delta = *pair;
*ptr0 = curMatch;
ptr0 = pair;
len0 = len;
}
{
if (delta >= curMatch)
return NULL;
delta = (UInt32)pos - delta;
if (delta >= cbs
// delta >= _cyclicBufferSize || delta >= pos
|| --cutValue == 0)
{
*ptr0 = *ptr1 = kEmptyHashValue;
_distances[-1] = (UInt32)(d - _distances);
break;
}
}
}
}
} // for (tree iterations)
}
pos++;
_cyclicBufferPos++;
cur++;
}
while (d < limit);
*posRes = (UInt32)pos;
return d;
}
*/

View File

@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder /* LzmaEnc.c -- LZMA Encoder
2021-04-01: Igor Pavlov : Public domain */ 2021-11-18: Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -12,6 +12,7 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
#include "CpuArch.h"
#include "LzmaEnc.h" #include "LzmaEnc.h"
#include "LzFind.h" #include "LzFind.h"
@@ -36,8 +37,8 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp);
static unsigned g_STAT_OFFSET = 0; static unsigned g_STAT_OFFSET = 0;
#endif #endif
#define kLzmaMaxHistorySize ((UInt32)3 << 29) /* for good normalization speed we still reserve 256 MB before 4 GB range */
/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */ #define kLzmaMaxHistorySize ((UInt32)15 << 28)
#define kNumTopBits 24 #define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits) #define kTopValue ((UInt32)1 << kNumTopBits)
@@ -78,13 +79,12 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (p->dictSize > p->reduceSize) if (p->dictSize > p->reduceSize)
{ {
unsigned i; UInt32 v = (UInt32)p->reduceSize;
UInt32 reduceSize = (UInt32)p->reduceSize; const UInt32 kReduceMin = ((UInt32)1 << 12);
for (i = 11; i <= 30; i++) if (v < kReduceMin)
{ v = kReduceMin;
if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } if (p->dictSize > v)
if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } p->dictSize = v;
}
} }
if (p->lc < 0) p->lc = 3; if (p->lc < 0) p->lc = 3;
@@ -113,18 +113,85 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
return props.dictSize; return props.dictSize;
} }
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
/* BSR code is fast for some new CPUs */ /*
/* #define LZMA_LOG_BSR */ x86/x64:
BSR:
IF (SRC == 0) ZF = 1, DEST is undefined;
AMD : DEST is unchanged;
IF (SRC != 0) ZF = 0; DEST is index of top non-zero bit
BSR is slow in some processors
LZCNT:
IF (SRC == 0) CF = 1, DEST is size_in_bits_of_register(src) (32 or 64)
IF (SRC != 0) CF = 0, DEST = num_lead_zero_bits
IF (DEST == 0) ZF = 1;
LZCNT works only in new processors starting from Haswell.
if LZCNT is not supported by processor, then it's executed as BSR.
LZCNT can be faster than BSR, if supported.
*/
// #define LZMA_LOG_BSR
#if defined(MY_CPU_ARM_OR_ARM64) /* || defined(MY_CPU_X86_OR_AMD64) */
#if (defined(__clang__) && (__clang_major__ >= 6)) \
|| (defined(__GNUC__) && (__GNUC__ >= 6))
#define LZMA_LOG_BSR
#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
// #if defined(MY_CPU_ARM_OR_ARM64)
#define LZMA_LOG_BSR
// #endif
#endif
#endif #endif
// #include <intrin.h>
#ifdef LZMA_LOG_BSR #ifdef LZMA_LOG_BSR
#define kDicLogSizeMaxCompress 32 #if defined(__clang__) \
|| defined(__GNUC__)
#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); } /*
C code: : (30 - __builtin_clz(x))
gcc9/gcc10 for x64 /x86 : 30 - (bsr(x) xor 31)
clang10 for x64 : 31 + (bsr(x) xor -32)
*/
static unsigned GetPosSlot1(UInt32 pos) #define MY_clz(x) ((unsigned)__builtin_clz(x))
// __lzcnt32
// __builtin_ia32_lzcnt_u32
#else // #if defined(_MSC_VER)
#ifdef MY_CPU_ARM_OR_ARM64
#define MY_clz _CountLeadingZeros
#else // if defined(MY_CPU_X86_OR_AMD64)
// #define MY_clz __lzcnt // we can use lzcnt (unsupported by old CPU)
// _BitScanReverse code is not optimal for some MSVC compilers
#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); zz--; \
res = (zz + zz) + (pos >> zz); }
#endif // MY_CPU_X86_OR_AMD64
#endif // _MSC_VER
#ifndef BSR2_RET
#define BSR2_RET(pos, res) { unsigned zz = 30 - MY_clz(pos); \
res = (zz + zz) + (pos >> zz); }
#endif
unsigned GetPosSlot1(UInt32 pos);
unsigned GetPosSlot1(UInt32 pos)
{ {
unsigned res; unsigned res;
BSR2_RET(pos, res); BSR2_RET(pos, res);
@@ -133,10 +200,10 @@ static unsigned GetPosSlot1(UInt32 pos)
#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } #define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
#else
#define kNumLogBits (9 + sizeof(size_t) / 2) #else // ! LZMA_LOG_BSR
/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
#define kNumLogBits (11 + sizeof(size_t) / 8 * 3)
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
@@ -183,7 +250,7 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); } #define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }
#endif #endif // LZMA_LOG_BSR
#define LZMA_NUM_REPS 4 #define LZMA_NUM_REPS 4
@@ -319,7 +386,7 @@ typedef UInt32 CProbPrice;
typedef struct typedef struct
{ {
void *matchFinderObj; void *matchFinderObj;
IMatchFinder matchFinder; IMatchFinder2 matchFinder;
unsigned optCur; unsigned optCur;
unsigned optEnd; unsigned optEnd;
@@ -364,10 +431,14 @@ typedef struct
// begin of CMatchFinderMt is used in LZ thread // begin of CMatchFinderMt is used in LZ thread
CMatchFinderMt matchFinderMt; CMatchFinderMt matchFinderMt;
// end of CMatchFinderMt is used in BT and HASH threads // end of CMatchFinderMt is used in BT and HASH threads
// #else
// CMatchFinder matchFinderBase;
#endif #endif
CMatchFinder matchFinderBase; CMatchFinder matchFinderBase;
// we suppose that we have 8-bytes alignment after CMatchFinder
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
Byte pad[128]; Byte pad[128];
#endif #endif
@@ -375,8 +446,10 @@ typedef struct
// LZ thread // LZ thread
CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; // we want {len , dist} pairs to be 8-bytes aligned in matches array
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2];
// we want 8-bytes alignment here
UInt32 alignPrices[kAlignTableSize]; UInt32 alignPrices[kAlignTableSize];
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
@@ -405,12 +478,19 @@ typedef struct
CSaveState saveState; CSaveState saveState;
// BoolInt mf_Failure;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
Byte pad2[128]; Byte pad2[128];
#endif #endif
} CLzmaEnc; } CLzmaEnc;
#define MFB (p->matchFinderBase)
/*
#ifndef _7ZIP_ST
#define MFB (p->matchFinderMt.MatchFinder)
#endif
*/
#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr)); #define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr));
@@ -475,11 +555,21 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
if (props.lc > LZMA_LC_MAX if (props.lc > LZMA_LC_MAX
|| props.lp > LZMA_LP_MAX || props.lp > LZMA_LP_MAX
|| props.pb > LZMA_PB_MAX || props.pb > LZMA_PB_MAX)
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|| props.dictSize > kLzmaMaxHistorySize)
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
if (props.dictSize > kLzmaMaxHistorySize)
props.dictSize = kLzmaMaxHistorySize;
#ifndef LZMA_LOG_BSR
{
const UInt64 dict64 = props.dictSize;
if (dict64 > ((UInt64)1 << kDicLogSizeMaxCompress))
return SZ_ERROR_PARAM;
}
#endif
p->dictSize = props.dictSize; p->dictSize = props.dictSize;
{ {
unsigned fb = (unsigned)props.fb; unsigned fb = (unsigned)props.fb;
@@ -494,7 +584,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->pb = (unsigned)props.pb; p->pb = (unsigned)props.pb;
p->fastMode = (props.algo == 0); p->fastMode = (props.algo == 0);
// p->_maxMode = True; // p->_maxMode = True;
p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0); MFB.btMode = (Byte)(props.btMode ? 1 : 0);
{ {
unsigned numHashBytes = 4; unsigned numHashBytes = 4;
if (props.btMode) if (props.btMode)
@@ -504,10 +594,10 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
} }
if (props.numHashBytes >= 5) numHashBytes = 5; if (props.numHashBytes >= 5) numHashBytes = 5;
p->matchFinderBase.numHashBytes = numHashBytes; MFB.numHashBytes = numHashBytes;
} }
p->matchFinderBase.cutValue = props.mc; MFB.cutValue = props.mc;
p->writeEndMark = (BoolInt)props.writeEndMark; p->writeEndMark = (BoolInt)props.writeEndMark;
@@ -531,7 +621,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.expectedDataSize = expectedDataSiize; MFB.expectedDataSize = expectedDataSiize;
} }
@@ -578,12 +668,11 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc) static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
{ {
ISzAlloc_Free(alloc, p->bufBase); ISzAlloc_Free(alloc, p->bufBase);
p->bufBase = 0; p->bufBase = NULL;
} }
static void RangeEnc_Init(CRangeEnc *p) static void RangeEnc_Init(CRangeEnc *p)
{ {
/* Stream.Init(); */
p->range = 0xFFFFFFFF; p->range = 0xFFFFFFFF;
p->cache = 0; p->cache = 0;
p->low = 0; p->low = 0;
@@ -597,12 +686,12 @@ static void RangeEnc_Init(CRangeEnc *p)
MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)
{ {
size_t num; const size_t num = (size_t)(p->buf - p->bufBase);
if (p->res != SZ_OK) if (p->res == SZ_OK)
return; {
num = (size_t)(p->buf - p->bufBase); if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num)) p->res = SZ_ERROR_WRITE;
p->res = SZ_ERROR_WRITE; }
p->processed += num; p->processed += num;
p->buf = p->bufBase; p->buf = p->bufBase;
} }
@@ -1007,7 +1096,11 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
p->additionalOffset++; p->additionalOffset++;
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); {
const UInt32 *d = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
// if (!d) { p->mf_Failure = True; *numPairsRes = 0; return 0; }
numPairs = (unsigned)(d - p->matches);
}
*numPairsRes = numPairs; *numPairsRes = numPairs;
#ifdef SHOW_STAT #ifdef SHOW_STAT
@@ -1023,7 +1116,7 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
if (numPairs == 0) if (numPairs == 0)
return 0; return 0;
{ {
unsigned len = p->matches[(size_t)numPairs - 2]; const unsigned len = p->matches[(size_t)numPairs - 2];
if (len != p->numFastBytes) if (len != p->numFastBytes)
return len; return len;
{ {
@@ -1033,7 +1126,7 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
{ {
const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
const Byte *p2 = p1 + len; const Byte *p2 = p1 + len;
ptrdiff_t dif = (ptrdiff_t)-1 - (ptrdiff_t)p->matches[(size_t)numPairs - 1]; const ptrdiff_t dif = (ptrdiff_t)-1 - (ptrdiff_t)p->matches[(size_t)numPairs - 1];
const Byte *lim = p1 + numAvail; const Byte *lim = p1 + numAvail;
for (; p2 != lim && *p2 == p2[dif]; p2++) for (; p2 != lim && *p2 == p2[dif]; p2++)
{} {}
@@ -1189,6 +1282,8 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
repLens[i] = len; repLens[i] = len;
if (len > repLens[repMaxIndex]) if (len > repLens[repMaxIndex])
repMaxIndex = i; repMaxIndex = i;
if (len == LZMA_MATCH_LEN_MAX) // 21.03 : optimization
break;
} }
if (repLens[repMaxIndex] >= p->numFastBytes) if (repLens[repMaxIndex] >= p->numFastBytes)
@@ -1201,10 +1296,12 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
} }
matches = p->matches; matches = p->matches;
#define MATCHES matches
// #define MATCHES p->matches
if (mainLen >= p->numFastBytes) if (mainLen >= p->numFastBytes)
{ {
p->backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS; p->backRes = MATCHES[(size_t)numPairs - 1] + LZMA_NUM_REPS;
MOVE_POS(p, mainLen - 1) MOVE_POS(p, mainLen - 1)
return mainLen; return mainLen;
} }
@@ -1298,13 +1395,13 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
if (len < 2) if (len < 2)
len = 2; len = 2;
else else
while (len > matches[offs]) while (len > MATCHES[offs])
offs += 2; offs += 2;
for (; ; len++) for (; ; len++)
{ {
COptimal *opt; COptimal *opt;
UInt32 dist = matches[(size_t)offs + 1]; UInt32 dist = MATCHES[(size_t)offs + 1];
UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len); UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
unsigned lenToPosState = GetLenToPosState(len); unsigned lenToPosState = GetLenToPosState(len);
@@ -1328,7 +1425,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
opt->extra = 0; opt->extra = 0;
} }
if (len == matches[offs]) if (len == MATCHES[offs])
{ {
offs += 2; offs += 2;
if (offs == numPairs) if (offs == numPairs)
@@ -1749,8 +1846,8 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
if (newLen > numAvail) if (newLen > numAvail)
{ {
newLen = numAvail; newLen = numAvail;
for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); for (numPairs = 0; newLen > MATCHES[numPairs]; numPairs += 2);
matches[numPairs] = (UInt32)newLen; MATCHES[numPairs] = (UInt32)newLen;
numPairs += 2; numPairs += 2;
} }
@@ -1769,9 +1866,9 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
} }
offs = 0; offs = 0;
while (startLen > matches[offs]) while (startLen > MATCHES[offs])
offs += 2; offs += 2;
dist = matches[(size_t)offs + 1]; dist = MATCHES[(size_t)offs + 1];
// if (dist >= kNumFullDistances) // if (dist >= kNumFullDistances)
GetPosSlot2(dist, posSlot); GetPosSlot2(dist, posSlot);
@@ -1798,7 +1895,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
} }
} }
if (len == matches[offs]) if (len == MATCHES[offs])
{ {
// if (p->_maxMode) { // if (p->_maxMode) {
// MATCH : LIT : REP_0 // MATCH : LIT : REP_0
@@ -1863,7 +1960,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
offs += 2; offs += 2;
if (offs == numPairs) if (offs == numPairs)
break; break;
dist = matches[(size_t)offs + 1]; dist = MATCHES[(size_t)offs + 1];
// if (dist >= kNumFullDistances) // if (dist >= kNumFullDistances)
GetPosSlot2(dist, posSlot); GetPosSlot2(dist, posSlot);
} }
@@ -2081,8 +2178,23 @@ static SRes CheckErrors(CLzmaEnc *p)
return p->result; return p->result;
if (p->rc.res != SZ_OK) if (p->rc.res != SZ_OK)
p->result = SZ_ERROR_WRITE; p->result = SZ_ERROR_WRITE;
if (p->matchFinderBase.result != SZ_OK)
#ifndef _7ZIP_ST
if (
// p->mf_Failure ||
(p->mtMode &&
( // p->matchFinderMt.failure_LZ_LZ ||
p->matchFinderMt.failure_LZ_BT))
)
{
p->result = MY_HRES_ERROR__INTERNAL_ERROR;
// printf("\nCheckErrors p->matchFinderMt.failureLZ\n");
}
#endif
if (MFB.result != SZ_OK)
p->result = SZ_ERROR_READ; p->result = SZ_ERROR_READ;
if (p->result != SZ_OK) if (p->result != SZ_OK)
p->finished = True; p->finished = True;
return p->result; return p->result;
@@ -2223,11 +2335,11 @@ MY_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p)
static void LzmaEnc_Construct(CLzmaEnc *p) static void LzmaEnc_Construct(CLzmaEnc *p)
{ {
RangeEnc_Construct(&p->rc); RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase); MatchFinder_Construct(&MFB);
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
p->matchFinderMt.MatchFinder = &MFB;
MatchFinderMt_Construct(&p->matchFinderMt); MatchFinderMt_Construct(&p->matchFinderMt);
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
#endif #endif
{ {
@@ -2243,7 +2355,6 @@ static void LzmaEnc_Construct(CLzmaEnc *p)
LzmaEnc_InitPriceTables(p->ProbPrices); LzmaEnc_InitPriceTables(p->ProbPrices);
p->litProbs = NULL; p->litProbs = NULL;
p->saveState.litProbs = NULL; p->saveState.litProbs = NULL;
} }
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc) CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
@@ -2269,7 +2380,7 @@ static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBi
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
#endif #endif
MatchFinder_Free(&p->matchFinderBase, allocBig); MatchFinder_Free(&MFB, allocBig);
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
RangeEnc_Free(&p->rc, alloc); RangeEnc_Free(&p->rc, alloc);
} }
@@ -2287,6 +2398,12 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa
UInt32 nowPos32, startPos32; UInt32 nowPos32, startPos32;
if (p->needInit) if (p->needInit)
{ {
#ifndef _7ZIP_ST
if (p->mtMode)
{
RINOK(MatchFinderMt_InitMt(&p->matchFinderMt));
}
#endif
p->matchFinder.Init(p->matchFinderObj); p->matchFinder.Init(p->matchFinderObj);
p->needInit = 0; p->needInit = 0;
} }
@@ -2582,11 +2699,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
UInt32 beforeSize = kNumOpts; UInt32 beforeSize = kNumOpts;
UInt32 dictSize;
if (!RangeEnc_Alloc(&p->rc, alloc)) if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0)); p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0));
#endif #endif
{ {
@@ -2605,30 +2724,50 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc,
} }
} }
p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0); MFB.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
if (beforeSize + p->dictSize < keepWindowSize)
beforeSize = keepWindowSize - p->dictSize; dictSize = p->dictSize;
if (dictSize == ((UInt32)2 << 30) ||
dictSize == ((UInt32)3 << 30))
{
/* 21.03 : here we reduce the dictionary for 2 reasons:
1) we don't want 32-bit back_distance matches in decoder for 2 GB dictionary.
2) we want to elimate useless last MatchFinder_Normalize3() for corner cases,
where data size is aligned for 1 GB: 5/6/8 GB.
That reducing must be >= 1 for such corner cases. */
dictSize -= 1;
}
if (beforeSize + dictSize < keepWindowSize)
beforeSize = keepWindowSize - dictSize;
/* in worst case we can look ahead for
max(LZMA_MATCH_LEN_MAX, numFastBytes + 1 + numFastBytes) bytes.
we send larger value for (keepAfter) to MantchFinder_Create():
(numFastBytes + LZMA_MATCH_LEN_MAX + 1)
*/
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
if (p->mtMode) if (p->mtMode)
{ {
RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize,
LZMA_MATCH_LEN_MAX p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */
+ 1 /* 18.04 */
, allocBig)); , allocBig));
p->matchFinderObj = &p->matchFinderMt; p->matchFinderObj = &p->matchFinderMt;
p->matchFinderBase.bigHash = (Byte)( MFB.bigHash = (Byte)(
(p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0); (p->dictSize > kBigHashDicLimit && MFB.hashMask >= 0xFFFFFF) ? 1 : 0);
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
} }
else else
#endif #endif
{ {
if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) if (!MatchFinder_Create(&MFB, dictSize, beforeSize,
p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 21.03 */
, allocBig))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
p->matchFinderObj = &p->matchFinderBase; p->matchFinderObj = &MFB;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); MatchFinder_CreateVTable(&MFB, &p->matchFinder);
} }
return SZ_OK; return SZ_OK;
@@ -2700,6 +2839,8 @@ static void LzmaEnc_Init(CLzmaEnc *p)
p->pbMask = ((unsigned)1 << p->pb) - 1; p->pbMask = ((unsigned)1 << p->pb) - 1;
p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc); p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
// p->mf_Failure = False;
} }
@@ -2742,7 +2883,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS
ISzAllocPtr alloc, ISzAllocPtr allocBig) ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream; MFB.stream = inStream;
p->needInit = 1; p->needInit = 1;
p->rc.outStream = outStream; p->rc.outStream = outStream;
return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
@@ -2753,16 +2894,16 @@ SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
ISzAllocPtr alloc, ISzAllocPtr allocBig) ISzAllocPtr alloc, ISzAllocPtr allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream; MFB.stream = inStream;
p->needInit = 1; p->needInit = 1;
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
} }
static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
{ {
p->matchFinderBase.directInput = 1; MFB.directInput = 1;
p->matchFinderBase.bufferBase = (Byte *)src; MFB.bufferBase = (Byte *)src;
p->matchFinderBase.directInputRem = srcLen; MFB.directInputRem = srcLen;
} }
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
@@ -2804,9 +2945,12 @@ static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, s
size = p->rem; size = p->rem;
p->overflow = True; p->overflow = True;
} }
memcpy(p->data, data, size); if (size != 0)
p->rem -= size; {
p->data += size; memcpy(p->data, data, size);
p->rem -= size;
p->data += size;
}
return size; return size;
} }
@@ -2895,7 +3039,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
LzmaEnc_Finish(p); LzmaEnc_Finish(p);
/* /*
if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB))
res = SZ_ERROR_FAIL; res = SZ_ERROR_FAIL;
} }
*/ */
@@ -2914,29 +3058,37 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp;
unsigned i;
UInt32 dictSize = p->dictSize;
if (*size < LZMA_PROPS_SIZE) if (*size < LZMA_PROPS_SIZE)
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
*size = LZMA_PROPS_SIZE; *size = LZMA_PROPS_SIZE;
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
if (dictSize >= ((UInt32)1 << 22))
{ {
const UInt32 kDictMask = ((UInt32)1 << 20) - 1; const CLzmaEnc *p = (const CLzmaEnc *)pp;
if (dictSize < (UInt32)0xFFFFFFFF - kDictMask) const UInt32 dictSize = p->dictSize;
dictSize = (dictSize + kDictMask) & ~kDictMask; UInt32 v;
} props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
else for (i = 11; i <= 30; i++)
{ // we write aligned dictionary value to properties for lzma decoder
if (dictSize <= ((UInt32)2 << i)) { dictSize = ((UInt32)2 << i); break; } if (dictSize >= ((UInt32)1 << 21))
if (dictSize <= ((UInt32)3 << i)) { dictSize = ((UInt32)3 << i); break; } {
} const UInt32 kDictMask = ((UInt32)1 << 20) - 1;
v = (dictSize + kDictMask) & ~kDictMask;
if (v < dictSize)
v = dictSize;
}
else
{
unsigned i = 11 * 2;
do
{
v = (UInt32)(2 + (i & 1)) << (i >> 1);
i++;
}
while (v < dictSize);
}
for (i = 0; i < 4; i++) SetUi32(props + 1, v);
props[1 + i] = (Byte)(dictSize >> (8 * i)); return SZ_OK;
return SZ_OK; }
} }

View File

@@ -1,5 +1,5 @@
/* MtCoder.c -- Multi-thread Coder /* MtCoder.c -- Multi-thread Coder
2021-02-09 : Igor Pavlov : Public domain */ 2021-07-12 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -495,12 +495,7 @@ SRes MtCoder_Code(CMtCoder *p)
{ {
RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->readEvent)); RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->readEvent));
RINOK_THREAD(Semaphore_OptCreateInit(&p->blocksSemaphore, numBlocksMax, numBlocksMax));
if (Semaphore_IsCreated(&p->blocksSemaphore))
{
RINOK_THREAD(Semaphore_Close(&p->blocksSemaphore));
}
RINOK_THREAD(Semaphore_Create(&p->blocksSemaphore, numBlocksMax, numBlocksMax));
} }
for (i = 0; i < MTCODER__BLOCKS_MAX - 1; i++) for (i = 0; i < MTCODER__BLOCKS_MAX - 1; i++)

View File

@@ -1,5 +1,5 @@
/* Sha1.c -- SHA-1 Hash /* Sha1.c -- SHA-1 Hash
2021-04-01 : Igor Pavlov : Public domain 2021-07-13 : 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"
@@ -34,7 +34,7 @@ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ l
#endif #endif
#elif defined(MY_CPU_ARM_OR_ARM64) #elif defined(MY_CPU_ARM_OR_ARM64)
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER >= 1910 #if _MSC_VER >= 1910 && _MSC_VER >= 1929 && _MSC_FULL_VER >= 192930037
#define _SHA_SUPPORTED #define _SHA_SUPPORTED
#endif #endif
#elif defined(__clang__) #elif defined(__clang__)
@@ -435,7 +435,37 @@ void Sha1Prepare()
#endif #endif
{ {
// printf("\n========== HW SHA1 ======== \n"); // printf("\n========== HW SHA1 ======== \n");
f = f_hw = Sha1_UpdateBlocks_HW; #if defined(MY_CPU_ARM_OR_ARM64) && defined(_MSC_VER)
/* there was bug in MSVC compiler for ARM64 -O2 before version VS2019 16.10 (19.29.30037).
It generated incorrect SHA-1 code.
21.03 : we test sha1-hardware code at runtime initialization */
#pragma message("== SHA1 code: MSC compiler : failure-check code was inserted")
UInt32 state[5] = { 0, 1, 2, 3, 4 } ;
Byte data[64];
unsigned i;
for (i = 0; i < sizeof(data); i += 2)
{
data[i ] = (Byte)(i);
data[i + 1] = (Byte)(i + 1);
}
Sha1_UpdateBlocks_HW(state, data, sizeof(data) / 64);
if ( state[0] != 0x9acd7297
|| state[1] != 0x4624d898
|| state[2] != 0x0bf079f0
|| state[3] != 0x031e61b3
|| state[4] != 0x8323fe20)
{
// printf("\n========== SHA-1 hardware version failure ======== \n");
}
else
#endif
{
f = f_hw = Sha1_UpdateBlocks_HW;
}
} }
g_FUNC_UPDATE_BLOCKS = f; g_FUNC_UPDATE_BLOCKS = f;
g_FUNC_UPDATE_BLOCKS_HW = f_hw; g_FUNC_UPDATE_BLOCKS_HW = f_hw;

View File

@@ -1,5 +1,5 @@
/* Threads.c -- multithreading library /* Threads.c -- multithreading library
2021-04-25 : Igor Pavlov : Public domain */ 2021-07-12 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -150,6 +150,17 @@ WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
return HandleToWRes(*p); return HandleToWRes(*p);
} }
WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
{
// if (Semaphore_IsCreated(p))
{
WRes wres = Semaphore_Close(p);
if (wres != 0)
return wres;
}
return Semaphore_Create(p, initCount, maxCount);
}
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)
@@ -158,7 +169,9 @@ 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 exception:
Windows XP, 2003 : can raise a STATUS_NO_MEMORY exception
Windows Vista+ : no exceptions */
#ifdef _MSC_VER #ifdef _MSC_VER
__try __try
#endif #endif
@@ -167,7 +180,7 @@ WRes CriticalSection_Init(CCriticalSection *p)
/* InitializeCriticalSectionAndSpinCount(p, 0); */ /* InitializeCriticalSectionAndSpinCount(p, 0); */
} }
#ifdef _MSC_VER #ifdef _MSC_VER
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; } __except (EXCEPTION_EXECUTE_HANDLER) { return ERROR_NOT_ENOUGH_MEMORY; }
#endif #endif
return 0; return 0;
} }
@@ -406,6 +419,27 @@ WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
return 0; return 0;
} }
WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
{
if (Semaphore_IsCreated(p))
{
/*
WRes wres = Semaphore_Close(p);
if (wres != 0)
return wres;
*/
if (initCount > maxCount || maxCount < 1)
return EINVAL;
// return EINVAL; // for debug
p->_count = initCount;
p->_maxCount = maxCount;
return 0;
}
return Semaphore_Create(p, initCount, maxCount);
}
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
{ {
UInt32 newCount; UInt32 newCount;

View File

@@ -1,5 +1,5 @@
/* Threads.h -- multithreading library /* Threads.h -- multithreading library
2021-04-25 : Igor Pavlov : Public domain */ 2021-07-12 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H #ifndef __7Z_THREADS_H
#define __7Z_THREADS_H #define __7Z_THREADS_H
@@ -8,14 +8,18 @@
#include <Windows.h> #include <Windows.h>
#else #else
#if !defined(__APPLE__) && !defined(_AIX) #if defined(__linux__)
#if !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__)
#ifndef _7ZIP_AFFINITY_DISABLE #ifndef _7ZIP_AFFINITY_DISABLE
#define _7ZIP_AFFINITY_SUPPORTED #define _7ZIP_AFFINITY_SUPPORTED
// #pragma message(" ==== _7ZIP_AFFINITY_SUPPORTED")
// #define _GNU_SOURCE // #define _GNU_SOURCE
#endif #endif
#endif #endif
#endif
#include <pthread.h> #include <pthread.h>
#endif #endif
#include "7zTypes.h" #include "7zTypes.h"
@@ -122,6 +126,7 @@ typedef HANDLE CSemaphore;
#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_OptCreateInit(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);
@@ -172,6 +177,7 @@ typedef struct _CSemaphore
#define Semaphore_IsCreated(p) ((p)->_created) #define Semaphore_IsCreated(p) ((p)->_created)
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
#define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1) #define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1)
WRes Semaphore_Wait(CSemaphore *p); WRes Semaphore_Wait(CSemaphore *p);

View File

@@ -1,5 +1,5 @@
/* 7zipInstall.c - 7-Zip Installer /* 7zipInstall.c - 7-Zip Installer
2021-02-23 : Igor Pavlov : Public domain */ 2021-09-02 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -926,6 +926,9 @@ static void WriteShellEx()
wcscpy(destPath + 1, path); wcscpy(destPath + 1, path);
CatAscii(destPath, "Uninstall.exe\""); CatAscii(destPath, "Uninstall.exe\"");
MyRegistry_SetString(destKey, L"UninstallString", destPath); MyRegistry_SetString(destKey, L"UninstallString", destPath);
CatAscii(destPath, " /S");
MyRegistry_SetString(destKey, L"QuietUninstallString", destPath);
MyRegistry_SetDWORD(destKey, L"NoModify", 1); MyRegistry_SetDWORD(destKey, L"NoModify", 1);
MyRegistry_SetDWORD(destKey, L"NoRepair", 1); MyRegistry_SetDWORD(destKey, L"NoRepair", 1);

View File

@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller /* 7zipUninstall.c - 7-Zip Uninstaller
2021-02-23 : Igor Pavlov : Public domain */ 2021-11-24 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -51,7 +51,7 @@
#endif #endif
#endif #endif
#define k_7zip_with_Ver k_7zip_with_Ver_base k_Postfix #define k_7zip_with_Ver k_7zip_with_Ver_base k_Postfix
static LPCWSTR const k_7zip_with_Ver_Uninstall = k_7zip_with_Ver L" Uninstall"; static LPCWSTR const k_7zip_with_Ver_Uninstall = k_7zip_with_Ver L" Uninstall";
@@ -404,6 +404,17 @@ static LPCWSTR const k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVe
static LPCWSTR const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip"; static LPCWSTR const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip";
static void RemoveQuotes(wchar_t *s)
{
const size_t len = wcslen(s);
size_t i;
if (len == 0 || s[0] != '\"' || s[len - 1] != '\"')
return;
for (i = 0; i < len; i++)
s[i] = s[i + 1];
s[len - 2] = 0;
}
static BoolInt AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name) static BoolInt AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name)
{ {
if (!IsString1PrefixedByString2_NoCase(s, prefix)) if (!IsString1PrefixedByString2_NoCase(s, prefix))
@@ -490,12 +501,18 @@ static void WriteCLSID()
if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm, NULL, s)) if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm, NULL, s))
{
// RemoveQuotes(s);
if (AreEqual_Path_PrefixName(s, path, L"7zFM.exe")) if (AreEqual_Path_PrefixName(s, path, L"7zFM.exe"))
MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm); MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_AppPaths_7zFm);
}
if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_Uninstall_7zip, L"UninstallString", s)) if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_Uninstall_7zip, L"UninstallString", s))
{
RemoveQuotes(s);
if (AreEqual_Path_PrefixName(s, path, kUninstallExe)) if (AreEqual_Path_PrefixName(s, path, kUninstallExe))
MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_Uninstall_7zip); MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_Uninstall_7zip);
}
} }

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression /* LzmaUtil.c -- Test application for LZMA compression
2021-02-15 : Igor Pavlov : Public domain */ 2021-11-01 : Igor Pavlov : Public domain */
#include "../../Precomp.h" #include "../../Precomp.h"
@@ -12,6 +12,7 @@
#include "../../Alloc.h" #include "../../Alloc.h"
#include "../../7zFile.h" #include "../../7zFile.h"
#include "../../7zVersion.h" #include "../../7zVersion.h"
#include "../../LzFind.h"
#include "../../LzmaDec.h" #include "../../LzmaDec.h"
#include "../../LzmaEnc.h" #include "../../LzmaEnc.h"
@@ -195,6 +196,8 @@ static int main2(int numArgs, const char *args[], char *rs)
int encodeMode; int encodeMode;
BoolInt useOutFile = False; BoolInt useOutFile = False;
LzFindPrepare();
FileSeqInStream_CreateVTable(&inStream); FileSeqInStream_CreateVTable(&inStream);
File_Construct(&inStream.file); File_Construct(&inStream.file);
inStream.wres = 0; inStream.wres = 0;
@@ -276,7 +279,7 @@ static int main2(int numArgs, const char *args[], char *rs)
int MY_CDECL main(int numArgs, const char *args[]) int MY_CDECL main(int numArgs, const char *args[])
{ {
char rs[800] = { 0 }; char rs[1000] = { 0 };
int res = main2(numArgs, args, rs); int res = main2(numArgs, args, rs);
fputs(rs, stdout); fputs(rs, stdout);
return res; return res;

View File

@@ -134,6 +134,10 @@ SOURCE=..\..\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\LzFindOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\LzHash.h SOURCE=..\..\LzHash.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -8,8 +8,10 @@ LIB_OBJS = \
C_OBJS = \ C_OBJS = \
$O\Alloc.obj \ $O\Alloc.obj \
$O\CpuArch.obj \
$O\LzFind.obj \ $O\LzFind.obj \
$O\LzFindMt.obj \ $O\LzFindMt.obj \
$O\LzFindOpt.obj \
$O\LzmaDec.obj \ $O\LzmaDec.obj \
$O\LzmaEnc.obj \ $O\LzmaEnc.obj \
$O\7zFile.obj \ $O\7zFile.obj \

View File

@@ -8,8 +8,10 @@ OBJS = \
$O/7zFile.o \ $O/7zFile.o \
$O/7zStream.o \ $O/7zStream.o \
$O/Alloc.o \ $O/Alloc.o \
$O/CpuArch.o \
$O/LzFind.o \ $O/LzFind.o \
$O/LzFindMt.o \ $O/LzFindMt.o \
$O/LzFindOpt.o \
$O/LzmaDec.o \ $O/LzmaDec.o \
$O/LzmaEnc.o \ $O/LzmaEnc.o \
$O/LzmaUtil.o \ $O/LzmaUtil.o \

View File

@@ -136,6 +136,10 @@ SOURCE=..\..\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\LzFindOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\LzHash.h SOURCE=..\..\LzHash.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -11,8 +11,10 @@ LIB_OBJS = \
C_OBJS = \ C_OBJS = \
$O\Alloc.obj \ $O\Alloc.obj \
$O\CpuArch.obj \
$O\LzFind.obj \ $O\LzFind.obj \
$O\LzFindMt.obj \ $O\LzFindMt.obj \
$O\LzFindOpt.obj \
$O\LzmaDec.obj \ $O\LzmaDec.obj \
$O\LzmaEnc.obj \ $O\LzmaEnc.obj \
$O\LzmaLib.obj \ $O\LzmaLib.obj \

View File

@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode /* XzDec.c -- Xz Decode
2021-04-01 : Igor Pavlov : Public domain */ 2021-09-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -773,7 +773,8 @@ static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ #define READ_VARINT_AND_CHECK(buf, pos, size, res) \
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } if (s == 0) return SZ_ERROR_ARCHIVE; \
pos += s; }
static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p) static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p)

View File

@@ -1,5 +1,5 @@
/* XzIn.c - Xz input /* XzIn.c - Xz input
2021-04-01 : Igor Pavlov : Public domain */ 2021-09-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -26,7 +26,8 @@ SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ #define READ_VARINT_AND_CHECK(buf, pos, size, res) \
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } if (s == 0) return SZ_ERROR_ARCHIVE; \
pos += s; }
SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes) SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes)
{ {

View File

@@ -9,4 +9,3 @@ USE_ASM=1
CC=$(CROSS_COMPILE)clang CC=$(CROSS_COMPILE)clang
CXX=$(CROSS_COMPILE)clang++ CXX=$(CROSS_COMPILE)clang++
USE_CLANG=1 USE_CLANG=1

View File

@@ -9,4 +9,3 @@ USE_ASM=1
CC=$(CROSS_COMPILE)clang CC=$(CROSS_COMPILE)clang
CXX=$(CROSS_COMPILE)clang++ CXX=$(CROSS_COMPILE)clang++
USE_CLANG=1 USE_CLANG=1

View File

@@ -8,4 +8,3 @@ MY_ARCH=-m32
USE_ASM=1 USE_ASM=1
CC=$(CROSS_COMPILE)gcc CC=$(CROSS_COMPILE)gcc
CXX=$(CROSS_COMPILE)g++ CXX=$(CROSS_COMPILE)g++

View File

@@ -49,5 +49,3 @@ CFLAGS_WARN_GCC_PPMD_UNALIGNED = \
CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) \ CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) \
# $(CFLAGS_WARN_GCC_PPMD_UNALIGNED) # $(CFLAGS_WARN_GCC_PPMD_UNALIGNED)

View File

@@ -2,7 +2,7 @@
# USE_ASM = 1 # USE_ASM = 1
# IS_X64 = 1 # IS_X64 = 1
# MY_ARCH = # MY_ARCH =
# USE_ASM=
MY_ARCH_2 = $(MY_ARCH) MY_ARCH_2 = $(MY_ARCH)
@@ -10,6 +10,7 @@ MY_ASM = jwasm
MY_ASM = asmc MY_ASM = asmc
PROGPATH = $(O)/$(PROG) PROGPATH = $(O)/$(PROG)
PROGPATH_STATIC = $(O)/$(PROG)s
ifneq ($(CC), xlc) ifneq ($(CC), xlc)
@@ -23,6 +24,8 @@ CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \
-DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
-fPIC -fPIC
# -D_7ZIP_AFFINITY_DISABLE
ifdef SystemDrive ifdef SystemDrive
IS_MINGW = 1 IS_MINGW = 1
@@ -86,7 +89,7 @@ endif
PROGPATH = $(O)/$(PROG)$(SHARED_EXT) PROGPATH = $(O)/$(PROG)$(SHARED_EXT)
PROGPATH_STATIC = $(O)/$(PROG)s$(SHARED_EXT)
ifdef IS_MINGW ifdef IS_MINGW
@@ -112,7 +115,7 @@ LIB2 = -lpthread -ldl
DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(OBJS) DEL_OBJ_EXE = -$(RM) $(PROGPATH) $(PROGPATH_STATIC) $(OBJS)
endif endif
@@ -148,13 +151,23 @@ CXX_WARN_FLAGS =
CXXFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(CXXFLAGS_EXTRA) $(CC_SHARED) -o $@ $(CXX_WARN_FLAGS) CXXFLAGS = $(MY_ARCH_2) $(LOCAL_FLAGS) $(CXXFLAGS_BASE2) $(CFLAGS_BASE) $(CXXFLAGS_EXTRA) $(CC_SHARED) -o $@ $(CXX_WARN_FLAGS)
all: $(O) $(PROGPATH) STATIC_TARGET=
ifdef COMPL_STATIC
STATIC_TARGET=$(PROGPATH_STATIC)
endif
all: $(O) $(PROGPATH) $(STATIC_TARGET)
$(O): $(O):
$(MY_MKDIR) $(O) $(MY_MKDIR) $(O)
LFLAGS_ALL = -s $(MY_ARCH_2) $(LDFLAGS) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2)
$(PROGPATH): $(OBJS) $(PROGPATH): $(OBJS)
$(CXX) -o $(PROGPATH) -s $(MY_ARCH_2) $(LDFLAGS) $(LD_arch) $(OBJS) $(MY_LIBS) $(LIB2) $(CXX) -o $(PROGPATH) $(LFLAGS_ALL)
$(PROGPATH_STATIC): $(OBJS)
$(CXX) -static -o $(PROGPATH_STATIC) $(LFLAGS_ALL)
# -s strips debug sections from executable in GCC # -s strips debug sections from executable in GCC
@@ -186,6 +199,8 @@ $O/Lang.o: ../../../Common/Lang.cpp
$(CXX) $(CXXFLAGS) $< $(CXX) $(CXXFLAGS) $<
$O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp $O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp
$(CXX) $(CXXFLAGS) $< $(CXX) $(CXXFLAGS) $<
$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp
$(CXX) $(CXXFLAGS) $<
$O/MyMap.o: ../../../Common/MyMap.cpp $O/MyMap.o: ../../../Common/MyMap.cpp
$(CXX) $(CXXFLAGS) $< $(CXX) $(CXXFLAGS) $<
$O/MyString.o: ../../../Common/MyString.cpp $O/MyString.o: ../../../Common/MyString.cpp
@@ -1095,6 +1110,7 @@ $O/XzCrc64.o: ../../../../C/XzCrc64.c
ifdef USE_ASM ifdef USE_ASM
ifdef IS_X64 ifdef IS_X64
USE_X86_ASM=1 USE_X86_ASM=1
USE_X64_ASM=1
else else
ifdef IS_X86 ifdef IS_X86
USE_X86_ASM=1 USE_X86_ASM=1
@@ -1126,6 +1142,13 @@ $O/AesOpt.o: ../../../../C/AesOpt.c
$(CC) $(CFLAGS) $< $(CC) $(CFLAGS) $<
endif endif
ifdef USE_X64_ASM
$O/LzFindOpt.o: ../../../../Asm/x86/LzFindOpt.asm
$(MY_ASM) $(AFLAGS) $<
else
$O/LzFindOpt.o: ../../../../C/LzFindOpt.c
$(CC) $(CFLAGS) $<
endif
ifdef USE_LZMA_DEC_ASM ifdef USE_LZMA_DEC_ASM

View File

@@ -14,8 +14,10 @@ struct CMethodFull: public CMethodProps
CMethodId Id; CMethodId Id;
UInt32 NumStreams; UInt32 NumStreams;
int CodecIndex; int CodecIndex;
UInt32 NumThreads;
bool Set_NumThreads;
CMethodFull(): CodecIndex(-1) {} CMethodFull(): CodecIndex(-1), NumThreads(1), Set_NumThreads(false) {}
bool IsSimpleCoder() const { return NumStreams == 1; } bool IsSimpleCoder() const { return NumStreams == 1; }
}; };
@@ -53,8 +55,12 @@ struct CCompressionMethodMode
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
UInt32 NumThreads; UInt32 NumThreads;
bool NumThreads_WasForced;
bool MultiThreadMixer; bool MultiThreadMixer;
#endif #endif
UInt64 MemoryUsageLimit;
bool MemoryUsageLimit_WasSet;
bool PasswordIsDefined; bool PasswordIsDefined;
UString Password; // _Wipe UString Password; // _Wipe
@@ -65,8 +71,11 @@ struct CCompressionMethodMode
, Filter_was_Inserted(false) , Filter_was_Inserted(false)
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
, NumThreads(1) , NumThreads(1)
, NumThreads_WasForced(false)
, MultiThreadMixer(true) , MultiThreadMixer(true)
#endif #endif
, MemoryUsageLimit((UInt64)1 << 30)
, MemoryUsageLimit_WasSet(false)
, PasswordIsDefined(false) , PasswordIsDefined(false)
{} {}

View File

@@ -175,12 +175,16 @@ HRESULT CEncoder::CreateMixerCoder(
CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2; CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
if (methodFull.Set_NumThreads)
{ {
CMyComPtr<ICompressSetCoderMt> setCoderMt; CMyComPtr<ICompressSetCoderMt> setCoderMt;
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt) if (setCoderMt)
{ {
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads)); RINOK(setCoderMt->SetNumberOfThreads(
/* _options.NumThreads */
methodFull.NumThreads
));
} }
} }
#endif #endif

View File

@@ -374,7 +374,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
_7Z_DECODER_CRYPRO_VARS _7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) #if !defined(_7ZIP_ST)
, true, _numThreads, _memUsage , true, _numThreads, _memUsage_Decompress
#endif #endif
); );

View File

@@ -158,12 +158,7 @@ private:
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m); HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod); HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
HRESULT SetMainMethod(CCompressionMethodMode &method HRESULT SetMainMethod(CCompressionMethodMode &method);
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
#endif #endif

View File

@@ -69,15 +69,12 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
return PropsMethod_To_FullMethod(methodFull, m); return PropsMethod_To_FullMethod(methodFull, m);
} }
HRESULT CHandler::SetMainMethod(
CCompressionMethodMode &methodMode HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{ {
methodMode.Bonds = _bonds; methodMode.Bonds = _bonds;
// we create local copy of _methods. So we can modify it.
CObjectVector<COneMethodInfo> methods = _methods; CObjectVector<COneMethodInfo> methods = _methods;
{ {
@@ -120,20 +117,26 @@ HRESULT CHandler::SetMainMethod(
COneMethodInfo &oneMethodInfo = methods[i]; COneMethodInfo &oneMethodInfo = methods[i];
SetGlobalLevelTo(oneMethodInfo); SetGlobalLevelTo(oneMethodInfo);
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
CMultiMethodProps::SetMethodThreadsTo(oneMethodInfo, numThreads); const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
if (!numThreads_WasSpecifiedInMethod)
{
// here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, methodMode.NumThreads);
}
#endif #endif
CMethodFull &methodFull = methodMode.Methods.AddNew(); CMethodFull &methodFull = methodMode.Methods.AddNew();
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo)); RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
methodFull.Set_NumThreads = true;
methodFull.NumThreads = methodMode.NumThreads;
if (methodFull.Id != k_Copy) if (methodFull.Id != k_Copy)
needSolid = true; needSolid = true;
if (_numSolidBytesDefined) UInt64 dicSize;
continue;
UInt32 dicSize;
switch (methodFull.Id) switch (methodFull.Id)
{ {
case k_LZMA: case k_LZMA:
@@ -145,9 +148,13 @@ HRESULT CHandler::SetMainMethod(
default: continue; default: continue;
} }
UInt64 numSolidBytes;
if (methodFull.Id == k_LZMA2) if (methodFull.Id == k_LZMA2)
{ {
// he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
/* lzma2 code use dictionary upo to fake 4 GiB to calculate ChunkSize.
So we do same */
UInt64 cs = (UInt64)dicSize << 2; UInt64 cs = (UInt64)dicSize << 2;
const UInt32 kMinSize = (UInt32)1 << 20; const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28; const UInt32 kMaxSize = (UInt32)1 << 28;
@@ -157,20 +164,78 @@ HRESULT CHandler::SetMainMethod(
cs += (kMinSize - 1); cs += (kMinSize - 1);
cs &= ~(UInt64)(kMinSize - 1); cs &= ~(UInt64)(kMinSize - 1);
// we want to use at least 64 chunks (threads) per one solid block. // we want to use at least 64 chunks (threads) per one solid block.
_numSolidBytes = cs << 6;
// here we don't use chunckSize property
numSolidBytes = cs << 6;
// here we get real chunckSize
cs = oneMethodInfo.Get_Xz_BlockSize();
if (dicSize > cs)
dicSize = cs;
const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34); const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
if (_numSolidBytes > kSolidBytes_Lzma2_Max) if (numSolidBytes > kSolidBytes_Lzma2_Max)
_numSolidBytes = kSolidBytes_Lzma2_Max; numSolidBytes = kSolidBytes_Lzma2_Max;
methodFull.Set_NumThreads = false; // we don't use ICompressSetCoderMt::SetNumberOfThreads() for LZMA2 encoder
#ifndef _7ZIP_ST
if (!numThreads_WasSpecifiedInMethod
&& !methodMode.NumThreads_WasForced
&& methodMode.MemoryUsageLimit_WasSet
)
{
const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
const UInt32 numBlockThreads_Original = methodMode.NumThreads / lzmaThreads;
if (numBlockThreads_Original > 1)
{
/*
const UInt32 kNumThreads_Max = 1024;
if (numBlockThreads > kNumMaxThreads)
numBlockThreads = kNumMaxThreads;
*/
UInt32 numBlockThreads = numBlockThreads_Original;
const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false); // solid
for (; numBlockThreads > 1; numBlockThreads--)
{
UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
if (cs < ((UInt32)1 << 26)) numPackChunks++;
if (cs < ((UInt32)1 << 24)) numPackChunks++;
if (cs < ((UInt32)1 << 22)) numPackChunks++;
size += numPackChunks * cs;
// printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
if (size <= methodMode.MemoryUsageLimit)
break;
}
if (numBlockThreads == 0)
numBlockThreads = 1;
if (numBlockThreads != numBlockThreads_Original)
{
const UInt32 numThreads_New = numBlockThreads * lzmaThreads;
CMultiMethodProps::SetMethodThreadsTo_Replace(methodFull, numThreads_New);
}
}
}
#endif
} }
else else
{ {
_numSolidBytes = (UInt64)dicSize << 7; numSolidBytes = (UInt64)dicSize << 7;
if (_numSolidBytes > kSolidBytes_Max) if (numSolidBytes > kSolidBytes_Max)
_numSolidBytes = kSolidBytes_Max; numSolidBytes = kSolidBytes_Max;
} }
if (_numSolidBytes < kSolidBytes_Min) if (_numSolidBytesDefined)
_numSolidBytes = kSolidBytes_Min; continue;
if (numSolidBytes < kSolidBytes_Min)
numSolidBytes = kSolidBytes_Min;
_numSolidBytes = numSolidBytes;
_numSolidBytesDefined = true; _numSolidBytesDefined = true;
} }
@@ -182,9 +247,13 @@ HRESULT CHandler::SetMainMethod(
_numSolidBytes = 0; _numSolidBytes = 0;
} }
_numSolidBytesDefined = true; _numSolidBytesDefined = true;
return S_OK; return S_OK;
} }
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined) static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
{ {
// ft = 0; // ft = 0;
@@ -576,22 +645,28 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CCompressionMethodMode methodMode, headerMethod; CCompressionMethodMode methodMode, headerMethod;
HRESULT res = SetMainMethod(methodMode methodMode.MemoryUsageLimit = _memUsage_Compress;
#ifndef _7ZIP_ST methodMode.MemoryUsageLimit_WasSet = _memUsage_WasSet;
, _numThreads
#endif #ifndef _7ZIP_ST
); {
UInt32 numThreads = _numThreads;
const UInt32 kNumThreads_Max = 1024;
if (numThreads > kNumThreads_Max)
numThreads = kNumThreads_Max;
methodMode.NumThreads = numThreads;
methodMode.NumThreads_WasForced = _numThreads_WasForced;
methodMode.MultiThreadMixer = _useMultiThreadMixer;
// headerMethod.NumThreads = 1;
headerMethod.MultiThreadMixer = _useMultiThreadMixer;
}
#endif
HRESULT res = SetMainMethod(methodMode);
RINOK(res); RINOK(res);
RINOK(SetHeaderMethod(headerMethod)); RINOK(SetHeaderMethod(headerMethod));
#ifndef _7ZIP_ST
methodMode.NumThreads = _numThreads;
methodMode.MultiThreadMixer = _useMultiThreadMixer;
headerMethod.NumThreads = 1;
headerMethod.MultiThreadMixer = _useMultiThreadMixer;
#endif
CMyComPtr<ICryptoGetTextPassword2> getPassword2; CMyComPtr<ICryptoGetTextPassword2> getPassword2;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2); updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);

View File

@@ -27,11 +27,30 @@ bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsB
else if (prop.vt != VT_EMPTY) else if (prop.vt != VT_EMPTY)
return false; return false;
bool percentMode = false;
{
const wchar_t c = *s;
if (MyCharLower_Ascii(c) == 'p')
{
percentMode = true;
s++;
}
}
const wchar_t *end; const wchar_t *end;
UInt64 v = ConvertStringToUInt64(s, &end); const UInt64 v = ConvertStringToUInt64(s, &end);
if (s == end) if (s == end)
return false; return false;
wchar_t c = *end; const wchar_t c = *end;
if (percentMode)
{
if (c != 0)
return false;
res = Calc_From_Val_Percents(percentsBase, v);
return true;
}
if (c == 0) if (c == 0)
{ {
res = v; res = v;
@@ -42,7 +61,7 @@ bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsB
if (c == '%') if (c == '%')
{ {
res = percentsBase / 100 * v; res = Calc_From_Val_Percents(percentsBase, v);
return true; return true;
} }
@@ -56,7 +75,7 @@ bool ParseSizeString(const wchar_t *s, const PROPVARIANT &prop, UInt64 percentsB
case 't': numBits = 40; break; case 't': numBits = 40; break;
default: return false; default: return false;
} }
UInt64 val2 = v << numBits; const UInt64 val2 = v << numBits;
if ((val2 >> numBits) != v) if ((val2 >> numBits) != v)
return false; return false;
res = val2; res = val2;
@@ -70,15 +89,22 @@ bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIAN
if (name.IsPrefixedBy_Ascii_NoCase("mt")) if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{ {
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
hres = ParseMtProp(name.Ptr(2), value, _numProcessors, _numThreads); _numThreads = _numProcessors;
_numThreads_WasForced = false;
hres = ParseMtProp2(name.Ptr(2), value, _numThreads, _numThreads_WasForced);
// "mt" means "_numThreads_WasForced = false" here
#endif #endif
return true; return true;
} }
if (name.IsPrefixedBy_Ascii_NoCase("memuse")) if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{ {
if (!ParseSizeString(name.Ptr(6), value, _memAvail, _memUsage)) UInt64 v;
if (!ParseSizeString(name.Ptr(6), value, _memAvail, v))
hres = E_INVALIDARG; hres = E_INVALIDARG;
_memUsage_Decompress = v;
_memUsage_Compress = v;
_memUsage_WasSet = true;
return true; return true;
} }
@@ -88,12 +114,24 @@ bool CCommonMethodProps::SetCommonProperty(const UString &name, const PROPVARIAN
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value) static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
{ {
if (m.FindProp(propID) < 0) if (m.FindProp(propID) < 0)
m.AddProp32(propID, value); m.AddProp32(propID, value);
} }
static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
{
const int i = m.FindProp(propID);
if (i >= 0)
{
NWindows::NCOM::CPropVariant &val = m.Props[(unsigned)i].Value;
val = (UInt32)value;
return;
}
m.AddProp32(propID, value);
}
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
{ {
UInt32 level = _level; UInt32 level = _level;
@@ -102,10 +140,15 @@ void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
void CMultiMethodProps::SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads) void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
{ {
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads); SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
} }
void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo, UInt32 numThreads)
{
SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
}
#endif #endif
void CMultiMethodProps::InitMulti() void CMultiMethodProps::InitMulti()

View File

@@ -18,15 +18,29 @@ protected:
{ {
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors(); _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
_numThreads_WasForced = false;
#endif #endif
UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28; UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28;
_memAvail = memAvail; _memAvail = memAvail;
_memUsage = memAvail; _memUsage_Compress = memAvail;
if (NWindows::NSystem::GetRamSize(memAvail)) _memUsage_Decompress = memAvail;
_memUsage_WasSet = NWindows::NSystem::GetRamSize(memAvail);
if (_memUsage_WasSet)
{ {
_memAvail = memAvail; _memAvail = memAvail;
_memUsage = memAvail / 32 * 17; unsigned bits = sizeof(size_t) * 8;
if (bits == 32)
{
const UInt32 limit2 = (UInt32)7 << 28;
if (memAvail > limit2)
memAvail = limit2;
}
// 80% - is auto usage limit in handlers
// _memUsage_Compress = memAvail * 4 / 5;
// _memUsage_Compress = Calc_From_Val_Percents(memAvail, 80);
_memUsage_Compress = Calc_From_Val_Percents_Less100(memAvail, 80);
_memUsage_Decompress = memAvail / 32 * 17;
} }
} }
@@ -34,9 +48,12 @@ public:
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
UInt32 _numThreads; UInt32 _numThreads;
UInt32 _numProcessors; UInt32 _numProcessors;
bool _numThreads_WasForced;
#endif #endif
UInt64 _memUsage; bool _memUsage_WasSet;
UInt64 _memUsage_Compress;
UInt64 _memUsage_Decompress;
UInt64 _memAvail; UInt64 _memAvail;
bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres); bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
@@ -63,7 +80,8 @@ public:
void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const; void SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
static void SetMethodThreadsTo(COneMethodInfo &oneMethodInfo, UInt32 numThreads); static void SetMethodThreadsTo_IfNotFinded(CMethodProps &props, UInt32 numThreads);
static void SetMethodThreadsTo_Replace(CMethodProps &props, UInt32 numThreads);
#endif #endif

View File

@@ -1513,6 +1513,9 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
*propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE; *propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE;
return S_OK; return S_OK;
} }
#else
UNUSED_VAR(index);
UNUSED_VAR(propID);
#endif #endif
return S_OK; return S_OK;
} }

View File

@@ -59,6 +59,7 @@ namespace NArcInfoFlags
const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
const UInt32 kHardLinks = 1 << 11; // the handler supports hard links const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches
const UInt32 kHashHandler = 1 << 13; // the handler contains the hashes (checksums)
} }
namespace NArchive namespace NArchive
@@ -91,7 +92,8 @@ namespace NArchive
{ {
kExtract = 0, kExtract = 0,
kTest, kTest,
kSkip kSkip,
kReadExternal
}; };
} }
@@ -458,7 +460,8 @@ namespace NUpdateNotifyOp
kRepack, kRepack,
kSkip, kSkip,
kDelete, kDelete,
kHeader kHeader,
kHashRead
// kNumDefined // kNumDefined
}; };
@@ -481,6 +484,14 @@ ARCHIVE_INTERFACE(IArchiveUpdateCallbackFile, 0x83)
}; };
#define INTERFACE_IArchiveGetDiskProperty(x) \
STDMETHOD(GetDiskProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
ARCHIVE_INTERFACE(IArchiveGetDiskProperty, 0x84)
{
INTERFACE_IArchiveGetDiskProperty(PURE);
};
/* /*
UpdateItems() UpdateItems()
------------- -------------

View File

@@ -82,14 +82,14 @@ enum
EW_READENVSTR, // ReadEnvStr, ExpandEnvStrings EW_READENVSTR, // ReadEnvStr, ExpandEnvStrings
EW_INTCMP, // IntCmp, IntCmpU EW_INTCMP, // IntCmp, IntCmpU
EW_INTOP, // IntOp EW_INTOP, // IntOp
EW_INTFMT, // IntFmt EW_INTFMT, // IntFmt/Int64Fmt
EW_PUSHPOP, // Push/Pop/Exchange EW_PUSHPOP, // Push/Pop/Exchange
EW_FINDWINDOW, // FindWindow EW_FINDWINDOW, // FindWindow
EW_SENDMESSAGE, // SendMessage EW_SENDMESSAGE, // SendMessage
EW_ISWINDOW, // IsWindow EW_ISWINDOW, // IsWindow
EW_GETDLGITEM, // GetDlgItem EW_GETDLGITEM, // GetDlgItem
EW_SETCTLCOLORS, // SetCtlColors EW_SETCTLCOLORS, // SetCtlColors
EW_SETBRANDINGIMAGE, // SetBrandingImage EW_SETBRANDINGIMAGE, // SetBrandingImage / LoadAndSetImage
EW_CREATEFONT, // CreateFont EW_CREATEFONT, // CreateFont
EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow
EW_SHELLEXEC, // ExecShell EW_SHELLEXEC, // ExecShell
@@ -131,9 +131,16 @@ enum
EW_SECTIONSET, // Get*, Set* EW_SECTIONSET, // Get*, Set*
EW_INSTTYPESET, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType EW_INSTTYPESET, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType
/*
// before v3.06 nsis it was so:
// instructions not actually implemented in exehead, but used in compiler. // instructions not actually implemented in exehead, but used in compiler.
EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR
EW_GETFUNCTIONADDR, EW_GETFUNCTIONADDR,
*/
// v3.06 and later it was changed to:
EW_GETOSINFO,
EW_RESERVEDOPCODE,
EW_LOCKWINDOW, // LockWindow EW_LOCKWINDOW, // LockWindow
@@ -141,6 +148,13 @@ enum
EW_FPUTWS, // FileWriteUTF16LE, FileWriteWord EW_FPUTWS, // FileWriteUTF16LE, FileWriteWord
EW_FGETWS, // FileReadUTF16LE, FileReadWord EW_FGETWS, // FileReadUTF16LE, FileReadWord
/*
// since v3.06 the fllowing IDs codes was moved here:
// Opcodes listed here are not actually used in exehead. No exehead opcodes should be present after these!
EW_GETLABELADDR, // --> EW_ASSIGNVAR
EW_GETFUNCTIONADDR, // --> EW_ASSIGNVAR
*/
// The following IDs are not IDs in real order. // The following IDs are not IDs in real order.
// We just need some IDs to translate eny extended layout to main layout. // We just need some IDs to translate eny extended layout to main layout.
@@ -194,20 +208,20 @@ static const CCommandInfo k_Commands[kNumCmds] =
{ 3 }, // ReadEnvStr, ExpandEnvStrings { 3 }, // ReadEnvStr, ExpandEnvStrings
{ 6 }, // "IntCmp" }, { 6 }, // "IntCmp" },
{ 4 }, // "IntOp" }, { 4 }, // "IntOp" },
{ 3 }, // "IntFmt" }, { 4 }, // "IntFmt" }, EW_INTFMT
{ 6 }, // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage. { 6 }, // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage.
{ 5 }, // "FindWindow" }, { 5 }, // "FindWindow" },
{ 6 }, // "SendMessage" }, { 6 }, // "SendMessage" },
{ 3 }, // "IsWindow" }, { 3 }, // "IsWindow" },
{ 3 }, // "GetDlgItem" }, { 3 }, // "GetDlgItem" },
{ 2 }, // "SetCtlColors" }, { 2 }, // "SetCtlColors" },
{ 3 }, // "SetBrandingImage" }, { 4 }, // "SetBrandingImage" } // LoadAndSetImage
{ 5 }, // "CreateFont" }, { 5 }, // "CreateFont" },
{ 4 }, // ShowWindow, EnableWindow, HideWindow { 4 }, // ShowWindow, EnableWindow, HideWindow
{ 6 }, // "ExecShell" }, { 6 }, // "ExecShell" },
{ 3 }, // "Exec" }, // Exec, ExecWait { 3 }, // "Exec" }, // Exec, ExecWait
{ 3 }, // "GetFileTime" }, { 3 }, // "GetFileTime" },
{ 3 }, // "GetDLLVersion" }, { 4 }, // "GetDLLVersion" },
{ 6 }, // RegDLL, UnRegDLL, CallInstDLL // it must be 5 params. But some multi-command write garbage. { 6 }, // RegDLL, UnRegDLL, CallInstDLL // it must be 5 params. But some multi-command write garbage.
{ 6 }, // "CreateShortCut" }, { 6 }, // "CreateShortCut" },
{ 4 }, // "CopyFiles" }, { 4 }, // "CopyFiles" },
@@ -229,10 +243,14 @@ static const CCommandInfo k_Commands[kNumCmds] =
{ 4 }, // "WriteUninstaller" }, { 4 }, // "WriteUninstaller" },
{ 5 }, // "Section" }, // *** { 5 }, // "Section" }, // ***
{ 4 }, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType { 4 }, // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType
{ 6 }, // "GetLabelAddr" },
{ 2 }, // "GetFunctionAddress" }, // { 6 }, // "GetLabelAddr" }, // before 3.06
{ 6 }, // "GetOsInfo" }, GetKnownFolderPath, ReadMemory, // v3.06+
{ 2 }, // "GetFunctionAddress" }, // before 3.06
{ 1 }, // "LockWindow" }, { 1 }, // "LockWindow" },
{ 3 }, // "FileWrite" }, // FileWriteUTF16LE, FileWriteWord { 4 }, // "FileWrite" }, // FileWriteUTF16LE, FileWriteWord
{ 4 }, // "FileRead" }, // FileReadUTF16LE, FileReadWord { 4 }, // "FileRead" }, // FileReadUTF16LE, FileReadWord
{ 2 }, // "Log" }, // LogSet, LogText { 2 }, // "Log" }, // LogSet, LogText
@@ -274,9 +292,9 @@ static const char * const k_CommandNames[kNumCmds] =
, NULL // StrCpy, GetCurrentAddress , NULL // StrCpy, GetCurrentAddress
, "StrCmp" , "StrCmp"
, NULL // ReadEnvStr, ExpandEnvStrings , NULL // ReadEnvStr, ExpandEnvStrings
, "IntCmp" , NULL // IntCmp / Int64Cmp / EW_INTCMP
, "IntOp" , "IntOp"
, "IntFmt" , NULL // IntFmt / Int64Fmt / EW_INTFMT
, NULL // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage. , NULL // Push, Pop, Exch // it must be 3 params. But some multi-command write garbage.
, "FindWindow" , "FindWindow"
, "SendMessage" , "SendMessage"
@@ -311,8 +329,10 @@ static const char * const k_CommandNames[kNumCmds] =
, "WriteUninstaller" , "WriteUninstaller"
, "Section" // *** , "Section" // ***
, NULL // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType , NULL // InstTypeSetText, InstTypeGetText, SetCurInstType, GetCurInstType
, "GetLabelAddr"
, NULL // "GetOsInfo" // , "GetLabelAddr" //
, "GetFunctionAddress" , "GetFunctionAddress"
, "LockWindow" , "LockWindow"
, "FileWrite" // FileWriteUTF16LE, FileWriteWord , "FileWrite" // FileWriteUTF16LE, FileWriteWord
, "FileRead" // FileReadUTF16LE, FileReadWord , "FileRead" // FileReadUTF16LE, FileReadWord
@@ -1715,7 +1735,10 @@ static bool StringToUInt32(const char *s, UInt32 &res)
return (*end == 0); return (*end == 0);
} }
static const unsigned k_CtlColors_Size = 24; static const unsigned k_CtlColors32_Size = 24;
static const unsigned k_CtlColors64_Size = 28;
#define GET_CtlColors_SIZE(is64) ((is64) ? k_CtlColors64_Size : k_CtlColors32_Size)
struct CNsis_CtlColors struct CNsis_CtlColors
{ {
@@ -1725,16 +1748,27 @@ struct CNsis_CtlColors
UInt32 bkb; // HBRUSH UInt32 bkb; // HBRUSH
Int32 bkmode; Int32 bkmode;
Int32 flags; Int32 flags;
UInt32 bkb_hi32;
void Parse(const Byte *p); void Parse(const Byte *p, bool is64);
}; };
void CNsis_CtlColors::Parse(const Byte *p) void CNsis_CtlColors::Parse(const Byte *p, bool is64)
{ {
text = Get32(p); text = Get32(p);
bkc = Get32(p + 4); bkc = Get32(p + 4);
lbStyle = Get32(p + 8); if (is64)
bkb = Get32(p + 12); {
bkb = Get32(p + 8);
bkb_hi32 = Get32(p + 12);
lbStyle = Get32(p + 16);
p += 4;
}
else
{
lbStyle = Get32(p + 8);
bkb = Get32(p + 12);
}
bkmode = (Int32)Get32(p + 16); bkmode = (Int32)Get32(p + 16);
flags = (Int32)Get32(p + 20); flags = (Int32)Get32(p + 20);
} }
@@ -2427,11 +2461,22 @@ void CInArchive::FindBadCmd(const CBlockHeader &bh, const Byte *p)
if (BadCmd >= 0 && id >= (unsigned)BadCmd) if (BadCmd >= 0 && id >= (unsigned)BadCmd)
continue; continue;
unsigned i; unsigned i;
if (id == EW_GETLABELADDR || if (IsNsis3_OrHigher())
id == EW_GETFUNCTIONADDR)
{ {
BadCmd = id; if (id == EW_RESERVEDOPCODE)
continue; {
BadCmd = id;
continue;
}
}
else
{
// if (id == EW_GETLABELADDR || id == EW_GETFUNCTIONADDR)
if (id == EW_RESERVEDOPCODE || id == EW_GETOSINFO)
{
BadCmd = id;
continue;
}
} }
for (i = 6; i != 0; i--) for (i = 6; i != 0; i--)
{ {
@@ -3148,7 +3193,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
&& CompareCommands(p, k_InitPluginDir_Commands, ARRAY_SIZE(k_InitPluginDir_Commands))) && CompareCommands(p, k_InitPluginDir_Commands, ARRAY_SIZE(k_InitPluginDir_Commands)))
{ {
InitPluginsDir_Start = kkk; InitPluginsDir_Start = kkk;
InitPluginsDir_End = kkk + ARRAY_SIZE(k_InitPluginDir_Commands); InitPluginsDir_End = (int)(kkk + ARRAY_SIZE(k_InitPluginDir_Commands));
labels[kkk] |= CMD_REF_InitPluginDir; labels[kkk] |= CMD_REF_InitPluginDir;
break; break;
} }
@@ -3369,7 +3414,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
#ifdef NSIS_SCRIPT #ifdef NSIS_SCRIPT
s += isSetOutPath ? "SetOutPath" : "CreateDirectory"; s += isSetOutPath ? "SetOutPath" : "CreateDirectory";
AddParam(params[0]); AddParam(params[0]);
if (params[2] != 0) if (params[2] != 0) // 2.51+ & 3.0b3+
{ {
SmallSpaceComment(); SmallSpaceComment();
s += "CreateRestrictedDirectory"; s += "CreateRestrictedDirectory";
@@ -4017,7 +4062,12 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_INTCMP: case EW_INTCMP:
{ {
if (params[5] != 0) s += "Int";
const UInt32 param5 = params[5];
if (param5 & 0x8000)
s += "64"; // v3.03+
s += "Cmp";
if (IsNsis3_OrHigher() ? (param5 & 1) : (param5 != 0))
s += 'U'; s += 'U';
AddParams(params, 2); AddParams(params, 2);
Add_GotoVar1(params[2]); Add_GotoVar1(params[2]);
@@ -4029,13 +4079,13 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_INTOP: case EW_INTOP:
{ {
AddParam_Var(params[0]); AddParam_Var(params[0]);
const char * const kOps = "+-*/|&^!|&%<>"; // NSIS 2.01+ const char * const kOps = "+-*/|&^!|&%<>>"; // NSIS 2.01+
// "+-*/|&^!|&%"; // NSIS 2.0b4+ // "+-*/|&^!|&%"; // NSIS 2.0b4+
// "+-*/|&^~!|&%"; // NSIS old // "+-*/|&^~!|&%"; // NSIS old
UInt32 opIndex = params[3]; const UInt32 opIndex = params[3];
char c = (opIndex < 13) ? kOps[opIndex] : '?'; const char c = (opIndex < 14) ? kOps[opIndex] : '?';
char c2 = (opIndex < 8 || opIndex == 10) ? (char)0 : c; const char c2 = (opIndex < 8 || opIndex == 10) ? (char)0 : c;
int numOps = (opIndex == 7) ? 1 : 2; const int numOps = (opIndex == 7) ? 1 : 2;
AddParam(params[1]); AddParam(params[1]);
if (numOps == 2 && c == '^' && IsDirectString_Equal(params[2], "0xFFFFFFFF")) if (numOps == 2 && c == '^' && IsDirectString_Equal(params[2], "0xFFFFFFFF"))
s += " ~ ;"; s += " ~ ;";
@@ -4043,6 +4093,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
s += c; s += c;
if (numOps != 1) if (numOps != 1)
{ {
if (opIndex == 13) // v3.03+ : operation ">>>"
s += c;
if (c2 != 0) if (c2 != 0)
s += c2; s += c2;
AddParam(params[2]); AddParam(params[2]);
@@ -4052,6 +4104,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_INTFMT: case EW_INTFMT:
{ {
if (params[3])
s += "Int64Fmt"; // v3.03+
else
s += "IntFmt";
AddParam_Var(params[0]); AddParam_Var(params[0]);
AddParams(params + 1, 2); AddParams(params + 1, 2);
break; break;
@@ -4172,7 +4228,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
if (_size < bhCtlColors.Offset if (_size < bhCtlColors.Offset
|| _size - bhCtlColors.Offset < offset || _size - bhCtlColors.Offset < offset
|| _size - bhCtlColors.Offset - offset < k_CtlColors_Size) || _size - bhCtlColors.Offset - offset < GET_CtlColors_SIZE(Is64Bit))
{ {
AddError("bad offset"); AddError("bad offset");
break; break;
@@ -4180,7 +4236,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
const Byte *p2 = _data + bhCtlColors.Offset + offset; const Byte *p2 = _data + bhCtlColors.Offset + offset;
CNsis_CtlColors colors; CNsis_CtlColors colors;
colors.Parse(p2); colors.Parse(p2, Is64Bit);
if ((colors.flags & kColorsFlags_BK_SYS) != 0 || if ((colors.flags & kColorsFlags_BK_SYS) != 0 ||
(colors.flags & kColorsFlags_TEXT_SYS) != 0) (colors.flags & kColorsFlags_TEXT_SYS) != 0)
@@ -4214,6 +4270,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
break; break;
} }
// case EW_LOADANDSETIMAGE:
case EW_SETBRANDINGIMAGE: case EW_SETBRANDINGIMAGE:
{ {
s += " /IMGID="; s += " /IMGID=";
@@ -4312,6 +4369,9 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_GETFILETIME: case EW_GETFILETIME:
case EW_GETDLLVERSION: case EW_GETDLLVERSION:
{ {
if (commandId == EW_GETDLLVERSION)
if (params[3] == 2)
s += " /ProductVersion"; // v3.08+
AddParam(params[2]); AddParam(params[2]);
AddParam_Var(params[0]); AddParam_Var(params[0]);
AddParam_Var(params[1]); AddParam_Var(params[1]);
@@ -4354,11 +4414,15 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_CREATESHORTCUT: case EW_CREATESHORTCUT:
{ {
unsigned numParams; unsigned numParams;
#define IsNsis3d0b3_OrHigher() 0 // change it
const unsigned v3_0b3 = IsNsis3d0b3_OrHigher();
for (numParams = 6; numParams > 2; numParams--) for (numParams = 6; numParams > 2; numParams--)
if (params[numParams - 1] != 0) if (params[numParams - 1] != 0)
break; break;
UInt32 spec = params[4]; const UInt32 spec = params[4];
const unsigned sw_shift = v3_0b3 ? 12 : 8;
const UInt32 sw_mask = v3_0b3 ? 0x7000 : 0x7F;
if (spec & 0x8000) // NSIS 3.0b0 if (spec & 0x8000) // NSIS 3.0b0
s += " /NoWorkingDir"; s += " /NoWorkingDir";
@@ -4366,16 +4430,16 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
if (numParams <= 4) if (numParams <= 4)
break; break;
UInt32 icon = (spec & 0xFF); UInt32 icon = (spec & (v3_0b3 ? 0xFFF : 0xFF));
Space(); Space();
if (icon != 0) if (icon != 0)
Add_UInt(icon); Add_UInt(icon);
else else
AddQuotes(); AddQuotes();
if ((spec >> 8) == 0 && numParams < 6) if ((spec >> sw_shift) == 0 && numParams < 6)
break; break;
UInt32 sw = (spec >> 8) & 0x7F; UInt32 sw = (spec >> sw_shift) & sw_mask;
Space(); Space();
// NSIS encoder replaces these names: // NSIS encoder replaces these names:
if (sw == MY__SW_SHOWMINNOACTIVE) if (sw == MY__SW_SHOWMINNOACTIVE)
@@ -4485,6 +4549,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
s += "Key"; s += "Key";
if (params[4] & 2) if (params[4] & 2)
s += " /ifempty"; s += " /ifempty";
// TODO: /ifnosubkeys, /ifnovalues
} }
AddRegRoot(params[1]); AddRegRoot(params[1]);
AddParam(params[2]); AddParam(params[2]);
@@ -4507,6 +4572,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
} }
if (params[4] == 1 && params[5] == 2) if (params[4] == 1 && params[5] == 2)
s2 = "ExpandStr"; s2 = "ExpandStr";
if (params[4] == 3 && params[5] == 7)
s2 = "MultiStr"; // v3.02+
if (s2) if (s2)
s += s2; s += s2;
AddRegRoot(params[0]); AddRegRoot(params[0]);
@@ -4627,6 +4694,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
s += (params[2] == 0) ? "UTF16LE" : "Word"; s += (params[2] == 0) ? "UTF16LE" : "Word";
else if (params[2] != 0) else if (params[2] != 0)
s += "Byte"; s += "Byte";
if (params[2] == 0 && params[3])
s += " /BOM"; // v3.0b3+
AddParam_Var(params[0]); AddParam_Var(params[0]);
AddParam(params[1]); AddParam(params[1]);
break; break;
@@ -4755,6 +4824,34 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
AddParam_Var(params[1]); AddParam_Var(params[1]);
break; break;
} }
case EW_GETOSINFO:
{
if (IsNsis3_OrHigher())
{
// v3.06+
if (params[3] == 0) // GETOSINFO_KNOWNFOLDER
{
s += "GetKnownFolderPath";
AddParam_Var(params[1]);
AddParam(params[2]);
break;
}
else if (params[3] == 1) // GETOSINFO_READMEMORY
{
s += "ReadMemory";
AddParam_Var(params[1]);
AddParam(params[2]);
AddParam(params[4]);
// if (params[2] == "0") AddCommentAndString("GetWinVer");
}
else
s += "GetOsInfo";
break;
}
s += "GetLabelAddr"; // before v3.06+
break;
}
case EW_LOCKWINDOW: case EW_LOCKWINDOW:
{ {
@@ -5111,8 +5208,12 @@ HRESULT CInArchive::Parse()
} }
AddLF(); AddLF();
if (IsUnicode) if (Is64Bit)
AddStringLF("Target AMD64-Unicode"); // TODO: Read PE machine type and use the correct CPU type
else if (IsUnicode)
AddStringLF("Unicode true"); AddStringLF("Unicode true");
else if (IsNsis3_OrHigher())
AddStringLF("Unicode false"); // Unicode is the default in 3.07+
if (Method != NMethodType::kCopy) if (Method != NMethodType::kCopy)
{ {

View File

@@ -176,6 +176,7 @@ private:
int BadCmd; // -1: no bad command; in another cases lowest bad command id int BadCmd; // -1: no bad command; in another cases lowest bad command id
bool IsPark() const { return NsisType >= k_NsisType_Park1; } bool IsPark() const { return NsisType >= k_NsisType_Park1; }
bool IsNsis3_OrHigher() const { return NsisType == k_NsisType_Nsis3; }
UInt64 _fileSize; UInt64 _fileSize;

View File

@@ -763,6 +763,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
_forceCodePage = true; _forceCodePage = true;
_curCodePage = _specifiedCodePage = cp; _curCodePage = _specifiedCodePage = cp;
} }
else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
}
else if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{
}
else else
return E_INVALIDARG; return E_INVALIDARG;
} }

View File

@@ -109,7 +109,7 @@ static UString ParseDString(const Byte *data, unsigned size)
} }
} }
else else
return UString("[unknow]"); return UString("[unknown]");
*p = 0; *p = 0;
res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res)); res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res));
} }

View File

@@ -32,7 +32,17 @@ static const Byte k_Signature[] = SIGNATURE;
static const unsigned k_ClusterBits = 20; static const unsigned k_ClusterBits = 20;
static const UInt32 k_ClusterSize = (UInt32)1 << k_ClusterBits; static const UInt32 k_ClusterSize = (UInt32)1 << k_ClusterBits;
static const UInt32 k_UnusedCluster = 0xFFFFFFFF;
/*
VDI_IMAGE_BLOCK_FREE = (~0) // returns any random data
VDI_IMAGE_BLOCK_ZERO = (~1) // returns zeros
*/
// static const UInt32 k_ClusterType_Free = 0xffffffff;
static const UInt32 k_ClusterType_Zero = 0xfffffffe;
#define IS_CLUSTER_ALLOCATED(v) ((UInt32)(v) < k_ClusterType_Zero)
// static const UInt32 kDiskType_Dynamic = 1; // static const UInt32 kDiskType_Dynamic = 1;
@@ -135,8 +145,8 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
if (cluster < _table.Size()) if (cluster < _table.Size())
{ {
const Byte *p = (const Byte *)_table + (size_t)cluster; const Byte *p = (const Byte *)_table + (size_t)cluster;
UInt32 v = Get32(p); const UInt32 v = Get32(p);
if (v != k_UnusedCluster) if (IS_CLUSTER_ALLOCATED(v))
{ {
UInt64 offset = _dataOffset + ((UInt64)v << k_ClusterBits); UInt64 offset = _dataOffset + ((UInt64)v << k_ClusterBits);
offset += lowBits; offset += lowBits;
@@ -374,8 +384,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback * /* openCallbac
const Byte *data = _table; const Byte *data = _table;
for (UInt32 i = 0; i < totalBlocks; i++) for (UInt32 i = 0; i < totalBlocks; i++)
{ {
UInt32 v = Get32(data + (size_t)i * 4); const UInt32 v = Get32(data + (size_t)i * 4);
if (v == k_UnusedCluster) if (!IS_CLUSTER_ALLOCATED(v))
continue; continue;
if (v >= numAllocatedBlocks) if (v >= numAllocatedBlocks)
{ {

View File

@@ -877,8 +877,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
curStream = inStream; curStream = inStream;
else else
{ {
UString fullName = seqName.GetNextName(i); if (!openVolumeCallback)
HRESULT result = openVolumeCallback->GetStream(fullName, &curStream); continue;
const UString fullName = seqName.GetNextName(i);
const HRESULT result = openVolumeCallback->GetStream(fullName, &curStream);
if (result == S_FALSE) if (result == S_FALSE)
continue; continue;
if (result != S_OK) if (result != S_OK)
@@ -1207,6 +1209,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
RINOK(ParsePropToUInt32(L"", prop, image)); RINOK(ParsePropToUInt32(L"", prop, image));
_defaultImageNumber = image; _defaultImageNumber = image;
} }
else if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
}
else if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
{
}
else else
return E_INVALIDARG; return E_INVALIDARG;
} }

View File

@@ -151,7 +151,8 @@ IMP_IInArchive_ArcProps
#define PARSE_NUM(_num_, _dest_) \ #define PARSE_NUM(_num_, _dest_) \
{ const char *end; _dest_ = ConvertStringToUInt32(p, &end); \ { const char *end; _dest_ = ConvertStringToUInt32(p, &end); \
if ((unsigned)(end - p) != _num_) return 0; p += _num_ + 1; } if ((unsigned)(end - p) != _num_) return 0; \
p += _num_ + 1; }
static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res) static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res)
{ {

View File

@@ -117,7 +117,7 @@ class CHandler:
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
decoder._numThreads = _numThreads; decoder._numThreads = _numThreads;
#endif #endif
decoder._memUsage = _memUsage; decoder._memUsage = _memUsage_Decompress;
HRESULT hres = decoder.Decode(seqInStream, outStream, HRESULT hres = decoder.Decode(seqInStream, outStream,
NULL, // *outSizeLimit NULL, // *outSizeLimit
@@ -1129,14 +1129,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (IntToBool(newData)) if (IntToBool(newData))
{ {
UInt64 size; UInt64 dataSize;
{ {
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop)); RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = prop.uhVal.QuadPart; dataSize = prop.uhVal.QuadPart;
RINOK(updateCallback->SetTotal(size)); RINOK(updateCallback->SetTotal(dataSize));
} }
NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder; NCompress::NXz::CEncoder *encoderSpec = new NCompress::NXz::CEncoder;
@@ -1147,17 +1147,79 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
lzma2Props.lzmaProps.level = GetLevel(); lzma2Props.lzmaProps.level = GetLevel();
xzProps.reduceSize = size; xzProps.reduceSize = dataSize;
/* /*
{ {
NCOM::CPropVariant prop = (UInt64)size; NCOM::CPropVariant prop = (UInt64)dataSize;
RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop)); RINOK(encoderSpec->SetCoderProp(NCoderPropID::kReduceSize, prop));
} }
*/ */
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
xzProps.numTotalThreads = (int)_numThreads;
#endif UInt32 numThreads = _numThreads;
const UInt32 kNumThreads_Max = 1024;
if (numThreads > kNumThreads_Max)
numThreads = kNumThreads_Max;
if (!_numThreads_WasForced
&& _numThreads >= 1
&& _memUsage_WasSet)
{
COneMethodInfo oneMethodInfo;
if (!_methods.IsEmpty())
oneMethodInfo = _methods[0];
SetGlobalLevelTo(oneMethodInfo);
const bool numThreads_WasSpecifiedInMethod = (oneMethodInfo.Get_NumThreads() >= 0);
if (!numThreads_WasSpecifiedInMethod)
{
// here we set the (NCoderPropID::kNumThreads) property in each method, only if there is no such property already
CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(oneMethodInfo, numThreads);
}
UInt64 cs = _numSolidBytes;
if (cs != XZ_PROPS__BLOCK_SIZE__AUTO)
oneMethodInfo.AddProp_BlockSize2(cs);
cs = oneMethodInfo.Get_Xz_BlockSize();
if (cs != XZ_PROPS__BLOCK_SIZE__AUTO &&
cs != XZ_PROPS__BLOCK_SIZE__SOLID)
{
const UInt32 lzmaThreads = oneMethodInfo.Get_Lzma_NumThreads();
const UInt32 numBlockThreads_Original = numThreads / lzmaThreads;
if (numBlockThreads_Original > 1)
{
UInt32 numBlockThreads = numBlockThreads_Original;
{
const UInt64 lzmaMemUsage = oneMethodInfo.Get_Lzma_MemUsage(false);
for (; numBlockThreads > 1; numBlockThreads--)
{
UInt64 size = numBlockThreads * (lzmaMemUsage + cs);
UInt32 numPackChunks = numBlockThreads + (numBlockThreads / 8) + 1;
if (cs < ((UInt32)1 << 26)) numPackChunks++;
if (cs < ((UInt32)1 << 24)) numPackChunks++;
if (cs < ((UInt32)1 << 22)) numPackChunks++;
size += numPackChunks * cs;
// printf("\nnumBlockThreads = %d, size = %d\n", (unsigned)(numBlockThreads), (unsigned)(size >> 20));
if (size <= _memUsage_Compress)
break;
}
}
if (numBlockThreads == 0)
numBlockThreads = 1;
if (numBlockThreads != numBlockThreads_Original)
numThreads = numBlockThreads * lzmaThreads;
}
}
}
xzProps.numTotalThreads = (int)numThreads;
#endif // _7ZIP_ST
xzProps.blockSize = _numSolidBytes; xzProps.blockSize = _numSolidBytes;
if (_numSolidBytes == XZ_PROPS__BLOCK_SIZE__SOLID) if (_numSolidBytes == XZ_PROPS__BLOCK_SIZE__SOLID)

View File

@@ -1665,7 +1665,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
m_Archive, item, realOutStream, extractCallback, m_Archive, item, realOutStream, extractCallback,
progress, progress,
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
_props._numThreads, _props._memUsage, _props._numThreads, _props._memUsage_Decompress,
#endif #endif
res); res);

View File

@@ -89,6 +89,7 @@ namespace NFileHeader
kZip64 = 0x01, kZip64 = 0x01,
kNTFS = 0x0A, kNTFS = 0x0A,
kStrongEncrypt = 0x17, kStrongEncrypt = 0x17,
kIzNtSecurityDescriptor = 0x4453,
kUnixTime = 0x5455, kUnixTime = 0x5455,
kUnixExtra = 0x5855, kUnixExtra = 0x5855,
kIzUnicodeComment = 0x6375, kIzUnicodeComment = 0x6375,

View File

@@ -989,7 +989,8 @@ bool CInArchive::ReadFileName(unsigned size, AString &s)
bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra, bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk) UInt64 &unpackSize, UInt64 &packSize,
CItem *cdItem)
{ {
extra.Clear(); extra.Clear();
@@ -1017,18 +1018,40 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
{ {
extra.IsZip64 = true; extra.IsZip64 = true;
bool isOK = true; bool isOK = true;
if (!cdItem
&& size == 16
&& !ZIP64_IS_32_MAX(unpackSize)
&& !ZIP64_IS_32_MAX(packSize))
{
/* Win10 Explorer's "Send to Zip" for big (3500 MiB) files
creates Zip64 Extra in local file header.
But if both uncompressed and compressed sizes are smaller than 4 GiB,
Win10 doesn't store 0xFFFFFFFF in 32-bit fields as expected by zip specification.
21.04: we ignore these minor errors in Win10 zip archives. */
if (ReadUInt64() != unpackSize)
isOK = false;
if (ReadUInt64() != packSize)
isOK = false;
size = 0;
}
else
{
if (ZIP64_IS_32_MAX(unpackSize))
{ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }}
if (ZIP64_IS_32_MAX(unpackSize)) if (isOK && ZIP64_IS_32_MAX(packSize))
{ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }} { if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }}
if (isOK && ZIP64_IS_32_MAX(packSize)) if (cdItem)
{ if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }} {
if (isOK && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
if (isOK && ZIP64_IS_32_MAX(localOffset)) { if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
{ if (size < 8) isOK = false; else { size -= 8; localOffset = ReadUInt64(); }}
if (isOK && ZIP64_IS_16_MAX(cdItem->Disk))
if (isOK && ZIP64_IS_16_MAX(disk)) { if (size < 4) isOK = false; else { size -= 4; cdItem->Disk = ReadUInt32(); }}
{ if (size < 4) isOK = false; else { size -= 4; disk = ReadUInt32(); }} }
}
if (!isOK || size != 0) if (!isOK || size != 0)
{ {
@@ -1100,9 +1123,7 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
if (extraSize > 0) if (extraSize > 0)
{ {
UInt64 localOffset = 0; if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, NULL))
UInt32 disk = 0;
if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, localOffset, disk))
{ {
/* Most of archives are OK for Extra. But there are some rare cases /* Most of archives are OK for Extra. But there are some rare cases
that have error. And if error in first item, it can't open archive. that have error. And if error in first item, it can't open archive.
@@ -1557,7 +1578,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
ReadFileName(nameSize, item.Name); ReadFileName(nameSize, item.Name);
if (extraSize > 0) if (extraSize > 0)
ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk); ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, &item);
// May be these strings must be deleted // May be these strings must be deleted
/* /*

View File

@@ -312,7 +312,7 @@ class CInArchive
bool ReadFileName(unsigned nameSize, AString &dest); bool ReadFileName(unsigned nameSize, AString &dest);
bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra, bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk); UInt64 &unpackSize, UInt64 &packSize, CItem *cdItem);
bool ReadLocalItem(CItemEx &item); bool ReadLocalItem(CItemEx &item);
HRESULT FindDescriptor(CItemEx &item, unsigned numFiles); HRESULT FindDescriptor(CItemEx &item, unsigned numFiles);
HRESULT ReadCdItem(CItemEx &item); HRESULT ReadCdItem(CItemEx &item);

View File

@@ -37,6 +37,7 @@ static const CUInt32PCharPair g_ExtraTypes[] =
{ NExtraID::kUnix3Extra, "ux" }, { NExtraID::kUnix3Extra, "ux" },
{ NExtraID::kIzUnicodeComment, "uc" }, { NExtraID::kIzUnicodeComment, "uc" },
{ NExtraID::kIzUnicodeName, "up" }, { NExtraID::kIzUnicodeName, "up" },
{ NExtraID::kIzNtSecurityDescriptor, "SD" },
{ NExtraID::kWzAES, "WzAES" }, { NExtraID::kWzAES, "WzAES" },
{ NExtraID::kApkAlign, "ApkAlign" } { NExtraID::kApkAlign, "ApkAlign" }
}; };

View File

@@ -773,7 +773,7 @@ static HRESULT Update2(
if (numThreads < 1) if (numThreads < 1)
numThreads = 1; numThreads = 1;
const size_t kMemPerThread = (size_t)1 << 25; const size_t kMemPerThread = (size_t)sizeof(size_t) << 23;
const size_t kBlockSize = 1 << 16; const size_t kBlockSize = 1 << 16;
bool mtMode = (numThreads > 1); bool mtMode = (numThreads > 1);
@@ -791,6 +791,7 @@ static HRESULT Update2(
if (onem.FindProp(NCoderPropID::kNumThreads) < 0) if (onem.FindProp(NCoderPropID::kNumThreads) < 0)
{ {
// fixme: we should check the number of threads for xz mehod also
// fixed for 9.31. bzip2 default is just one thread. // fixed for 9.31. bzip2 default is just one thread.
onem.AddProp_NumThreads(numThreads); onem.AddProp_NumThreads(numThreads);
} }
@@ -801,8 +802,8 @@ static HRESULT Update2(
if (method == NFileHeader::NCompressionMethod::kStore && !options.PasswordIsDefined) if (method == NFileHeader::NCompressionMethod::kStore && !options.PasswordIsDefined)
numThreads = 1; numThreads = 1;
if (oneMethodMain) if (oneMethodMain)
{ {
if (method == NFileHeader::NCompressionMethod::kBZip2) if (method == NFileHeader::NCompressionMethod::kBZip2)
{ {
@@ -828,6 +829,7 @@ static HRESULT Update2(
int numXzThreads = oneMethodMain->Get_Xz_NumThreads(numLzmaThreads); int numXzThreads = oneMethodMain->Get_Xz_NumThreads(numLzmaThreads);
if (numXzThreads < 0) if (numXzThreads < 0)
{ {
// numXzThreads is unknown
const UInt64 averageSize = numBytesToCompress / numFilesToCompress; const UInt64 averageSize = numBytesToCompress / numFilesToCompress;
const UInt64 blockSize = oneMethodMain->Get_Xz_BlockSize(); const UInt64 blockSize = oneMethodMain->Get_Xz_BlockSize();
UInt64 averageNumberOfBlocks = 1; UInt64 averageNumberOfBlocks = 1;
@@ -844,18 +846,52 @@ static HRESULT Update2(
} }
numThreads /= (unsigned)numXzThreads; numThreads /= (unsigned)numXzThreads;
} }
else if (
method == NFileHeader::NCompressionMethod::kDeflate
|| method == NFileHeader::NCompressionMethod::kDeflate64
|| method == NFileHeader::NCompressionMethod::kPPMd)
{
if (numThreads > 1
&& options._memUsage_WasSet
&& !options._numThreads_WasForced)
{
UInt64 methodMemUsage;
if (method == NFileHeader::NCompressionMethod::kPPMd)
methodMemUsage = oneMethodMain->Get_Ppmd_MemSize();
else
methodMemUsage = (4 << 20); // for deflate
const UInt64 threadMemUsage = kMemPerThread + methodMemUsage;
const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage;
if (numThreads64 < numThreads)
numThreads = (UInt32)numThreads64;
}
}
else if (method == NFileHeader::NCompressionMethod::kLZMA) else if (method == NFileHeader::NCompressionMethod::kLZMA)
{ {
// we suppose that default LZMA is 2 thread. So we don't change it // we suppose that default LZMA is 2 thread. So we don't change it
UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads(); const UInt32 numLZMAThreads = oneMethodMain->Get_Lzma_NumThreads();
numThreads /= numLZMAThreads; numThreads /= numLZMAThreads;
if (numThreads > 1
&& options._memUsage_WasSet
&& !options._numThreads_WasForced)
{
const UInt64 methodMemUsage = oneMethodMain->Get_Lzma_MemUsage(true);
const UInt64 threadMemUsage = kMemPerThread + methodMemUsage;
const UInt64 numThreads64 = options._memUsage_Compress / threadMemUsage;
if (numThreads64 < numThreads)
numThreads = (UInt32)numThreads64;
}
} }
} } // (oneMethodMain)
if (numThreads > numFilesToCompress) if (numThreads > numFilesToCompress)
numThreads = (UInt32)numFilesToCompress; numThreads = (UInt32)numFilesToCompress;
if (numThreads <= 1) if (numThreads <= 1)
{
mtMode = false; mtMode = false;
numThreads = 1;
}
} }
// mtMode = true; // to test mtMode for seqMode // mtMode = true; // to test mtMode for seqMode

View File

@@ -44,7 +44,7 @@ RSC=rc.exe
# 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 /Gz /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "WIN_LONG_PATH" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.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
@@ -270,6 +270,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Common.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\ComTry.h SOURCE=..\..\..\Common\ComTry.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -290,6 +294,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\DynLimBuf.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\DynLimBuf.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp SOURCE=..\..\..\Common\IntToString.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -306,6 +318,18 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\LzFindPrepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyBuffer.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyBuffer2.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyCom.h SOURCE=..\..\..\Common\MyCom.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -322,6 +346,10 @@ SOURCE=..\..\..\Common\MyInitGuid.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\MyLinux.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyString.cpp SOURCE=..\..\..\Common\MyString.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -330,6 +358,10 @@ SOURCE=..\..\..\Common\MyString.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\MyTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyUnknown.h SOURCE=..\..\..\Common\MyUnknown.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -342,6 +374,10 @@ SOURCE=..\..\..\Common\MyVector.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\MyWindows.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -478,6 +514,10 @@ SOURCE=..\..\..\Windows\FileLink.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\FileMapping.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileName.cpp SOURCE=..\..\..\Windows\FileName.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -506,6 +546,10 @@ SOURCE=..\..\..\Windows\MemoryLock.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\NtCheck.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.cpp SOURCE=..\..\..\Windows\PropVariant.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -538,6 +582,10 @@ SOURCE=..\..\..\Windows\Registry.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\SecurityUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.cpp SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -654,6 +702,10 @@ SOURCE=..\..\Common\MemBlocks.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\MemBlocks.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\MethodId.cpp SOURCE=..\..\Common\MethodId.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -769,6 +821,10 @@ SOURCE=..\..\Common\VirtThread.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\Compress\BZip2Const.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\BZip2Crc.cpp SOURCE=..\..\Compress\BZip2Crc.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -909,10 +965,6 @@ SOURCE=..\..\Compress\DeflateEncoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Compress\DeflateExtConst.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\DeflateRegister.cpp SOURCE=..\..\Compress\DeflateRegister.cpp
# End Source File # End Source File
# End Group # End Group
@@ -1678,6 +1730,10 @@ SOURCE=..\..\UI\Common\DefaultName.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\Common\DirItem.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\EnumDirItems.cpp SOURCE=..\..\UI\Common\EnumDirItems.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1686,6 +1742,10 @@ SOURCE=..\..\UI\Common\EnumDirItems.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\Common\ExitCode.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\Extract.cpp SOURCE=..\..\UI\Common\Extract.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1702,6 +1762,10 @@ SOURCE=..\..\UI\Common\ExtractingFilePath.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\Common\ExtractMode.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\HashCalc.cpp SOURCE=..\..\UI\Common\HashCalc.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1710,6 +1774,10 @@ SOURCE=..\..\UI\Common\HashCalc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\Common\IFileExtractCallback.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\LoadCodecs.cpp SOURCE=..\..\UI\Common\LoadCodecs.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1726,6 +1794,10 @@ SOURCE=..\..\UI\Common\OpenArchive.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\Common\Property.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\PropIDUtils.cpp SOURCE=..\..\UI\Common\PropIDUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1912,6 +1984,10 @@ SOURCE=..\..\Crypto\RandGen.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Crypto\Sha1Cls.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\WzAes.cpp SOURCE=..\..\Crypto\WzAes.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1959,6 +2035,10 @@ SOURCE=..\..\ICoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\IDecl.h
# End Source File
# Begin Source File
SOURCE=..\..\IMyUnknown.h SOURCE=..\..\IMyUnknown.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1975,6 +2055,10 @@ SOURCE=..\..\IStream.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\MyVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\PropID.h SOURCE=..\..\PropID.h
# End Source File # End Source File
# End Group # End Group
@@ -2223,6 +2307,10 @@ SOURCE=..\..\..\..\C\7zTypes.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\7zVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Aes.c SOURCE=..\..\..\..\C\Aes.c
!IF "$(CFG)" == "Alone - Win32 Release" !IF "$(CFG)" == "Alone - Win32 Release"
@@ -2440,6 +2528,10 @@ SOURCE=..\..\..\..\C\BwtSort.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\Compiler.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\CpuArch.c SOURCE=..\..\..\..\C\CpuArch.c
!IF "$(CFG)" == "Alone - Win32 Release" !IF "$(CFG)" == "Alone - Win32 Release"
@@ -2593,6 +2685,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\LzFindOpt.c
!IF "$(CFG)" == "Alone - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzHash.h SOURCE=..\..\..\..\C\LzHash.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -1,13 +1,16 @@
PROG = 7za.exe PROG = 7za.exe
# USE_C_AES = 1 # USE_C_AES = 1
# USE_C_SHA = 1 # USE_C_SHA = 1
# USE_C_LZFINDOPT = 1
COMMON_OBJS = \ COMMON_OBJS = \
$O\CommandLineParser.obj \ $O\CommandLineParser.obj \
$O\CRC.obj \ $O\CRC.obj \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\DynLimBuf.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\ListFileUtils.obj \ $O\ListFileUtils.obj \
$O\LzFindPrepare.obj \
$O\NewHandler.obj \ $O\NewHandler.obj \
$O\StdInStream.obj \ $O\StdInStream.obj \
$O\StdOutStream.obj \ $O\StdOutStream.obj \
@@ -217,6 +220,7 @@ C_OBJS = \
!include "../../Aes.mak" !include "../../Aes.mak"
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../Crc64.mak" !include "../../Crc64.mak"
!include "../../LzFindOpt.mak"
!include "../../LzmaDec.mak" !include "../../LzmaDec.mak"
!include "../../Sha1.mak" !include "../../Sha1.mak"
!include "../../Sha256.mak" !include "../../Sha256.mak"

View File

@@ -108,8 +108,10 @@ COMMON_OBJS = \
$O/CommandLineParser.o \ $O/CommandLineParser.o \
$O/CRC.o \ $O/CRC.o \
$O/CrcReg.o \ $O/CrcReg.o \
$O/DynLimBuf.o \
$O/IntToString.o \ $O/IntToString.o \
$O/ListFileUtils.o \ $O/ListFileUtils.o \
$O/LzFindPrepare.o \
$O/MyString.o \ $O/MyString.o \
$O/NewHandler.o \ $O/NewHandler.o \
$O/StdInStream.o \ $O/StdInStream.o \
@@ -283,6 +285,7 @@ C_OBJS = \
$O/Delta.o \ $O/Delta.o \
$O/HuffEnc.o \ $O/HuffEnc.o \
$O/LzFind.o \ $O/LzFind.o \
$O/LzFindOpt.o \
$O/Lzma2Dec.o \ $O/Lzma2Dec.o \
$O/Lzma2DecMt.o \ $O/Lzma2DecMt.o \
$O/Lzma2Enc.o \ $O/Lzma2Enc.o \

View File

@@ -44,7 +44,7 @@ RSC=rc.exe
# 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 /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAc /Yu"StdAfx.h" /FD /c # ADD CPP /nologo /Gr /MT /W4 /WX /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "_7ZIP_LARGE_PAGES" /D "SUPPORT_DEVICE_FILE" /FAcs /Yu"StdAfx.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
@@ -290,6 +290,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\DynLimBuf.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\DynLimBuf.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp SOURCE=..\..\..\Common\IntToString.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -306,6 +314,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\LzFindPrepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyCom.h SOURCE=..\..\..\Common\MyCom.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1681,6 +1693,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\LzFindOpt.c
!IF "$(CFG)" == "Alone - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 ReleaseU"
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Alone - Win32 DebugU"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -8,8 +8,10 @@ COMMON_OBJS = \
$O\CommandLineParser.obj \ $O\CommandLineParser.obj \
$O\CRC.obj \ $O\CRC.obj \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\DynLimBuf.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\ListFileUtils.obj \ $O\ListFileUtils.obj \
$O\LzFindPrepare.obj \
$O\NewHandler.obj \ $O\NewHandler.obj \
$O\StdInStream.obj \ $O\StdInStream.obj \
$O\StdOutStream.obj \ $O\StdOutStream.obj \
@@ -152,6 +154,7 @@ C_OBJS = \
!include "../../Aes.mak" !include "../../Aes.mak"
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../Crc64.mak" !include "../../Crc64.mak"
!include "../../LzFindOpt.mak"
!include "../../LzmaDec.mak" !include "../../LzmaDec.mak"
!include "../../Sha256.mak" !include "../../Sha256.mak"

View File

@@ -27,6 +27,7 @@ else
MT_OBJS = \ MT_OBJS = \
$O/LzFindMt.o \ $O/LzFindMt.o \
$O/LzFindOpt.o \
$O/StreamBinder.o \ $O/StreamBinder.o \
$O/Synchronization.o \ $O/Synchronization.o \
$O/VirtThread.o \ $O/VirtThread.o \
@@ -72,6 +73,7 @@ LOCAL_FLAGS = \
CONSOLE_OBJS = \ CONSOLE_OBJS = \
$O/BenchCon.o \ $O/BenchCon.o \
$O/ConsoleClose.o \ $O/ConsoleClose.o \
$O/DynLimBuf.o \
$O/ExtractCallbackConsole.o \ $O/ExtractCallbackConsole.o \
$O/HashCon.o \ $O/HashCon.o \
$O/List.o \ $O/List.o \
@@ -110,6 +112,7 @@ COMMON_OBJS = \
$O/CrcReg.o \ $O/CrcReg.o \
$O/IntToString.o \ $O/IntToString.o \
$O/ListFileUtils.o \ $O/ListFileUtils.o \
$O/LzFindPrepare.o \
$O/MyString.o \ $O/MyString.o \
$O/MyVector.o \ $O/MyVector.o \
$O/NewHandler.o \ $O/NewHandler.o \

View File

@@ -1016,6 +1016,11 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\LzFindOpt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2Dec.c SOURCE=..\..\..\..\C\Lzma2Dec.c
# SUBTRACT CPP /YX /Yc /Yu # SUBTRACT CPP /YX /Yc /Yu
# End Source File # End Source File
@@ -1079,6 +1084,20 @@ SOURCE=..\..\..\..\C\MtDec.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\Sha1.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Sha1.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Sha1Opt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Sha256.c SOURCE=..\..\..\..\C\Sha256.c
!IF "$(CFG)" == "FM - Win32 Release" !IF "$(CFG)" == "FM - Win32 Release"
@@ -1128,6 +1147,16 @@ SOURCE=..\..\..\..\C\Threads.c
SOURCE=..\..\..\..\C\Threads.h SOURCE=..\..\..\..\C\Threads.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\..\..\C\XzCrc64.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\XzCrc64Opt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# End Group # End Group
# Begin Group "Windows" # Begin Group "Windows"
@@ -1478,6 +1507,14 @@ SOURCE=..\..\..\Common\DynamicBuffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\DynLimBuf.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\DynLimBuf.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Exception.h SOURCE=..\..\..\Common\Exception.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1514,6 +1551,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\LzFindPrepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyBuffer.h SOURCE=..\..\..\Common\MyBuffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1554,10 +1595,22 @@ SOURCE=..\..\..\Common\Random.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Sha1Prepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Sha1Reg.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Sha256Prepare.cpp SOURCE=..\..\..\Common\Sha256Prepare.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\Sha256Reg.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\StringConvert.cpp SOURCE=..\..\..\Common\StringConvert.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1592,6 +1645,14 @@ SOURCE=..\..\..\Common\Wildcard.cpp
SOURCE=..\..\..\Common\Wildcard.h SOURCE=..\..\..\Common\Wildcard.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\..\Common\XzCrc64Init.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\XzCrc64Reg.cpp
# End Source File
# End Group # End Group
# Begin Group "UI" # Begin Group "UI"

View File

@@ -8,6 +8,7 @@ COMMON_OBJS = \
$O\CRC.obj \ $O\CRC.obj \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\LzFindPrepare.obj \
$O\NewHandler.obj \ $O\NewHandler.obj \
$O\MyString.obj \ $O\MyString.obj \
$O\Sha256Reg.obj \ $O\Sha256Reg.obj \
@@ -137,6 +138,7 @@ C_OBJS = \
!include "../../Aes.mak" !include "../../Aes.mak"
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../LzFindOpt.mak"
!include "../../LzmaDec.mak" !include "../../LzmaDec.mak"
!include "../../Sha256.mak" !include "../../Sha256.mak"

View File

@@ -3,6 +3,7 @@ COMMON_OBJS = \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\DynLimBuf.obj \ $O\DynLimBuf.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\LzFindPrepare.obj \
$O\MyMap.obj \ $O\MyMap.obj \
$O\MyString.obj \ $O\MyString.obj \
$O\MyVector.obj \ $O\MyVector.obj \
@@ -287,6 +288,7 @@ C_OBJS = \
!include "../../Aes.mak" !include "../../Aes.mak"
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../Crc64.mak" !include "../../Crc64.mak"
!include "../../LzFindOpt.mak"
!include "../../LzmaDec.mak" !include "../../LzmaDec.mak"
!include "../../Sha1.mak" !include "../../Sha1.mak"
!include "../../Sha256.mak" !include "../../Sha256.mak"

View File

@@ -18,6 +18,7 @@ else
MT_OBJS = \ MT_OBJS = \
$O/LzFindMt.o \ $O/LzFindMt.o \
$O/LzFindOpt.o \
$O/StreamBinder.o \ $O/StreamBinder.o \
$O/Synchronization.o \ $O/Synchronization.o \
$O/VirtThread.o \ $O/VirtThread.o \
@@ -35,6 +36,7 @@ COMMON_OBJS = \
$O/CrcReg.o \ $O/CrcReg.o \
$O/DynLimBuf.o \ $O/DynLimBuf.o \
$O/IntToString.o \ $O/IntToString.o \
$O/LzFindPrepare.o \
$O/MyMap.o \ $O/MyMap.o \
$O/MyString.o \ $O/MyString.o \
$O/MyVector.o \ $O/MyVector.o \

View File

@@ -267,6 +267,10 @@ SOURCE=..\..\..\Common\IntToString.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\LzFindPrepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyBuffer.h SOURCE=..\..\..\Common\MyBuffer.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1869,6 +1873,22 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\LzFindOpt.c
!IF "$(CFG)" == "7z - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
# SUBTRACT CPP /YX /Yc /Yu
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzHash.h SOURCE=..\..\..\..\C\LzHash.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -7,6 +7,7 @@ COMMON_OBJS = \
$O\CRC.obj \ $O\CRC.obj \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\LzFindPrepare.obj \
$O\NewHandler.obj \ $O\NewHandler.obj \
$O\MyString.obj \ $O\MyString.obj \
$O\StringConvert.obj \ $O\StringConvert.obj \
@@ -111,6 +112,7 @@ C_OBJS = \
$O\Threads.obj \ $O\Threads.obj \
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../LzFindOpt.mak"
!include "../../LzmaDec.mak" !include "../../LzmaDec.mak"
!include "../../7zip.mak" !include "../../7zip.mak"

View File

@@ -212,6 +212,10 @@ SOURCE=..\..\..\Common\IntToString.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Common\LzFindPrepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyCom.h SOURCE=..\..\..\Common\MyCom.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -316,6 +320,14 @@ SOURCE=..\..\Common\MethodProps.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Common\StreamObjects.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamObjects.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\StreamUtils.cpp SOURCE=..\..\Common\StreamUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -441,6 +453,11 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\..\C\LzFindOpt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzHash.h SOURCE=..\..\..\..\C\LzHash.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -14,6 +14,7 @@ COMMON_OBJS = \
$O\CRC.obj \ $O\CRC.obj \
$O\CrcReg.obj \ $O\CrcReg.obj \
$O\IntToString.obj \ $O\IntToString.obj \
$O\LzFindPrepare.obj \
$O\MyString.obj \ $O\MyString.obj \
$O\MyVector.obj \ $O\MyVector.obj \
$O\NewHandler.obj \ $O\NewHandler.obj \
@@ -33,6 +34,7 @@ WIN_OBJS = \
$O\FileStreams.obj \ $O\FileStreams.obj \
$O\FilterCoder.obj \ $O\FilterCoder.obj \
$O\MethodProps.obj \ $O\MethodProps.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \ $O\StreamUtils.obj \
UI_COMMON_OBJS = \ UI_COMMON_OBJS = \
@@ -55,6 +57,7 @@ C_OBJS = \
$O\Threads.obj \ $O\Threads.obj \
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../LzFindOpt.mak"
!include "../../LzmaDec.mak" !include "../../LzmaDec.mak"
!include "../../7zip.mak" !include "../../7zip.mak"

View File

@@ -18,6 +18,7 @@ else
MT_OBJS = \ MT_OBJS = \
$O/LzFindMt.o \ $O/LzFindMt.o \
$O/LzFindOpt.o \
$O/Synchronization.o \ $O/Synchronization.o \
$O/Threads.o \ $O/Threads.o \
@@ -55,6 +56,7 @@ COMMON_OBJS = \
$O/CRC.o \ $O/CRC.o \
$O/CrcReg.o \ $O/CrcReg.o \
$O/IntToString.o \ $O/IntToString.o \
$O/LzFindPrepare.o \
$O/MyString.o \ $O/MyString.o \
$O/MyVector.o \ $O/MyVector.o \
$O/NewHandler.o \ $O/NewHandler.o \
@@ -83,6 +85,7 @@ CONSOLE_OBJS = \
$O/FileStreams.o \ $O/FileStreams.o \
$O/FilterCoder.o \ $O/FilterCoder.o \
$O/MethodProps.o \ $O/MethodProps.o \
$O/StreamObjects.o \
$O/StreamUtils.o \ $O/StreamUtils.o \
C_OBJS = \ C_OBJS = \

View File

@@ -537,6 +537,14 @@ SOURCE=..\..\..\Windows\Control\ListView.h
# End Group # End Group
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\Clipboard.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Clipboard.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\CommonDialog.cpp SOURCE=..\..\..\Windows\CommonDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -593,6 +601,14 @@ SOURCE=..\..\..\Windows\FileName.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\..\Windows\MemoryGlobal.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\MemoryGlobal.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.cpp SOURCE=..\..\..\Windows\PropVariant.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -31,6 +31,7 @@ COMMON_OBJS = \
$O\Wildcard.obj \ $O\Wildcard.obj \
WIN_OBJS = \ WIN_OBJS = \
$O\Clipboard.obj \
$O\CommonDialog.obj \ $O\CommonDialog.obj \
$O\DLL.obj \ $O\DLL.obj \
$O\ErrorMsg.obj \ $O\ErrorMsg.obj \
@@ -38,6 +39,7 @@ WIN_OBJS = \
$O\FileFind.obj \ $O\FileFind.obj \
$O\FileIO.obj \ $O\FileIO.obj \
$O\FileName.obj \ $O\FileName.obj \
$O\MemoryGlobal.obj \
$O\PropVariant.obj \ $O\PropVariant.obj \
$O\PropVariantConv.obj \ $O\PropVariantConv.obj \
$O\ResourceString.obj \ $O\ResourceString.obj \

View File

@@ -118,6 +118,7 @@ HRESULT CExternalCodecs::Load()
} }
RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
RINOK(ReadIsAssignedProp(GetCodecs, i, NMethodPropID::kIsFilter, info.IsFilter));
Codecs.Add(info); Codecs.Add(info);
} }

View File

@@ -35,8 +35,9 @@ struct CCodecInfoEx
UInt32 NumStreams; UInt32 NumStreams;
bool EncoderIsAssigned; bool EncoderIsAssigned;
bool DecoderIsAssigned; bool DecoderIsAssigned;
bool IsFilter; // it's unused
CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {} CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false), IsFilter(false) {}
}; };
struct CHasherInfoEx struct CHasherInfoEx

View File

@@ -67,7 +67,6 @@ HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
if (!CMemBlockManager::AllocateSpace_bool(numBlocks)) if (!CMemBlockManager::AllocateSpace_bool(numBlocks))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
Semaphore.Close();
// we need (maxCount = 1), if we want to create non-use empty Semaphore // we need (maxCount = 1), if we want to create non-use empty Semaphore
if (maxCount == 0) if (maxCount == 0)
maxCount = 1; maxCount = 1;
@@ -75,12 +74,13 @@ HRes CMemBlockManagerMt::AllocateSpace(size_t numBlocks, size_t numNoLockBlocks)
// printf("\n Synchro.Create() \n"); // printf("\n Synchro.Create() \n");
WRes wres; WRes wres;
#ifndef _WIN32 #ifndef _WIN32
Semaphore.Close();
wres = Synchro.Create(); wres = Synchro.Create();
if (wres != 0) if (wres != 0)
return HRESULT_FROM_WIN32(wres); return HRESULT_FROM_WIN32(wres);
wres = Semaphore.Create(&Synchro, (UInt32)numLockBlocks, maxCount); wres = Semaphore.Create(&Synchro, (UInt32)numLockBlocks, maxCount);
#else #else
wres = Semaphore.Create((UInt32)numLockBlocks, maxCount); wres = Semaphore.OptCreateInit((UInt32)numLockBlocks, maxCount);
#endif #endif
return HRESULT_FROM_WIN32(wres); return HRESULT_FROM_WIN32(wres);

View File

@@ -8,6 +8,36 @@
using namespace NWindows; using namespace NWindows;
UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents)
{
// if (percents == 0) return 0;
const UInt64 q = percents / 100;
const UInt32 r = (UInt32)(percents % 100);
UInt64 res = 0;
if (q != 0)
{
if (val > (UInt64)(Int64)-1 / q)
return (UInt64)(Int64)-1;
res = val * q;
}
if (r != 0)
{
UInt64 v2;
if (val <= (UInt64)(Int64)-1 / r)
v2 = val * r / 100;
else
v2 = val / 100 * r;
res += v2;
if (res < v2)
return (UInt64)(Int64)-1;
}
return res;
}
bool StringToBool(const wchar_t *s, bool &res) bool StringToBool(const wchar_t *s, bool &res)
{ {
if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON")) if (s[0] == 0 || (s[0] == '+' && s[1] == 0) || StringsAreEqualNoCase_Ascii(s, "ON"))
@@ -53,7 +83,7 @@ static unsigned ParseStringToUInt64(const UString &srcString, UInt64 &number)
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
{ {
// =VT_UI4 // =VT_UI4
// =VT_EMPTY // =VT_EMPTY : it doesn't change (resValue), and returns S_OK
// {stringUInt32}=VT_EMPTY // {stringUInt32}=VT_EMPTY
if (prop.vt == VT_UI4) if (prop.vt == VT_UI4)
@@ -74,66 +104,151 @@ HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &
return S_OK; return S_OK;
} }
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force)
{ {
force = false;
UString s;
if (name.IsEmpty()) if (name.IsEmpty())
{ {
switch (prop.vt) if (prop.vt == VT_UI4)
{ {
case VT_UI4: numThreads = prop.ulVal;
numThreads = prop.ulVal; force = true;
break; return S_OK;
default:
{
bool val;
RINOK(PROPVARIANT_to_bool(prop, val));
numThreads = (val ? defaultNumThreads : 1);
break;
}
} }
bool val;
HRESULT res = PROPVARIANT_to_bool(prop, val);
if (res == S_OK)
{
if (!val)
{
numThreads = 1;
force = true;
}
// force = true; for debug
// "(VT_BOOL = VARIANT_TRUE)" set "force = false" and doesn't change numThreads
return S_OK;
}
if (prop.vt != VT_BSTR)
return res;
s.SetFromBstr(prop.bstrVal);
if (s.IsEmpty())
return E_INVALIDARG;
}
else
{
if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
s = name;
}
s.MakeLower_Ascii();
const wchar_t *start = s;
UInt32 v = numThreads;
/* we force up, if threads number specified
only `d` will force it down */
bool force_loc = true;
for (;;)
{
const wchar_t c = *start;
if (!c)
break;
if (c == 'd')
{
force_loc = false; // force down
start++;
continue;
}
if (c == 'u')
{
force_loc = true; // force up
start++;
continue;
}
bool isPercent = false;
if (c == 'p')
{
isPercent = true;
start++;
}
const wchar_t *end;
v = ConvertStringToUInt32(start, &end);
if (end == start)
return E_INVALIDARG;
if (isPercent)
v = numThreads * v / 100;
start = end;
}
numThreads = v;
force = force_loc;
return S_OK;
}
static HRESULT SetLogSizeProp(UInt64 number, NCOM::CPropVariant &destProp)
{
if (number >= 64)
return E_INVALIDARG;
UInt32 val32;
if (number < 32)
val32 = (UInt32)1 << (unsigned)number;
/*
else if (number == 32 && reduce_4GB_to_32bits)
val32 = (UInt32)(Int32)-1;
*/
else
{
destProp = (UInt64)((UInt64)1 << (unsigned)number);
return S_OK; return S_OK;
} }
if (prop.vt != VT_EMPTY) destProp = (UInt32)val32;
return E_INVALIDARG; return S_OK;
return ParsePropToUInt32(name, prop, numThreads);
} }
static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp) static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
{ {
/* if (reduce_4GB_to_32bits) we can reduce (4 GiB) property to (4 GiB - 1).
to fit the value to UInt32 for clients that do not support 64-bit values */
const wchar_t *end; const wchar_t *end;
UInt32 number = ConvertStringToUInt32(s, &end); const UInt64 number = ConvertStringToUInt64(s, &end);
unsigned numDigits = (unsigned)(end - s.Ptr()); const unsigned numDigits = (unsigned)(end - s.Ptr());
if (numDigits == 0 || s.Len() > numDigits + 1) if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG; return E_INVALIDARG;
if (s.Len() == numDigits) if (s.Len() == numDigits)
{ return SetLogSizeProp(number, destProp);
if (number >= 64)
return E_INVALIDARG;
if (number < 32)
destProp = (UInt32)((UInt32)1 << (unsigned)number);
else
destProp = (UInt64)((UInt64)1 << (unsigned)number);
return S_OK;
}
unsigned numBits; unsigned numBits;
switch (MyCharLower_Ascii(s[numDigits])) switch (MyCharLower_Ascii(s[numDigits]))
{ {
case 'b': destProp = number; return S_OK; case 'b': numBits = 0; break;
case 'k': numBits = 10; break; case 'k': numBits = 10; break;
case 'm': numBits = 20; break; case 'm': numBits = 20; break;
case 'g': numBits = 30; break; case 'g': numBits = 30; break;
default: return E_INVALIDARG; default: return E_INVALIDARG;
} }
if (number < ((UInt32)1 << (32 - numBits))) const UInt64 range4g = ((UInt64)1 << (32 - numBits));
destProp = (UInt32)(number << numBits); if (number < range4g)
destProp = (UInt32)((UInt32)number << numBits);
/*
else if (number == range4g && reduce_4GB_to_32bits)
destProp = (UInt32)(Int32)-1;
*/
else if (numBits == 0)
destProp = (UInt64)number;
else if (number >= ((UInt64)1 << (64 - numBits)))
return E_INVALIDARG;
else else
destProp = (UInt64)((UInt64)number << numBits); destProp = (UInt64)((UInt64)number << numBits);
return S_OK; return S_OK;
} }
@@ -141,16 +256,8 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp) static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp)
{ {
if (prop.vt == VT_UI4) if (prop.vt == VT_UI4)
{ return SetLogSizeProp(prop.ulVal, destProp);
UInt32 v = prop.ulVal;
if (v >= 64)
return E_INVALIDARG;
if (v < 32)
destProp = (UInt32)((UInt32)1 << (unsigned)v);
else
destProp = (UInt64)((UInt64)1 << (unsigned)v);
return S_OK;
}
if (prop.vt == VT_BSTR) if (prop.vt == VT_BSTR)
{ {
UString s; UString s;
@@ -247,9 +354,9 @@ HRESULT CProps::SetCoderProps_DSReduce_Aff(
int CMethodProps::FindProp(PROPID id) const int CMethodProps::FindProp(PROPID id) const
{ {
for (int i = (int)Props.Size() - 1; i >= 0; i--) for (unsigned i = Props.Size(); i != 0;)
if (Props[(unsigned)i].Id == id) if (Props[--i].Id == id)
return i; return (int)i;
return -1; return -1;
} }
@@ -495,6 +602,59 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
return S_OK; return S_OK;
} }
static UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads)
{
UInt32 hs = dict - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
hs |= (hs >> 4);
hs |= (hs >> 8);
hs >>= 1;
if (hs >= (1 << 24))
hs >>= 1;
hs |= (1 << 16) - 1;
// if (numHashBytes >= 5)
if (!isBt)
hs |= (256 << 10) - 1;
hs++;
UInt64 size1 = (UInt64)hs * 4;
size1 += (UInt64)dict * 4;
if (isBt)
size1 += (UInt64)dict * 4;
size1 += (2 << 20);
if (numThreads > 1 && isBt)
size1 += (2 << 20) + (4 << 20);
return size1;
}
static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
UInt64 CMethodProps::Get_Lzma_MemUsage(bool addSlidingWindowSize) const
{
const UInt64 dicSize = Get_Lzma_DicSize();
const bool isBt = Get_Lzma_MatchFinder_IsBt();
const UInt32 dict32 = (dicSize >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dicSize);
const UInt32 numThreads = Get_Lzma_NumThreads();
UInt64 size = GetMemoryUsage_LZMA(dict32, isBt, numThreads);
if (addSlidingWindowSize)
{
const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
UInt64 blockSize = (UInt64)dict32 + (1 << 16)
+ (numThreads > 1 ? (1 << 20) : 0);
blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
if (blockSize >= kBlockSizeMax)
blockSize = kBlockSizeMax;
size += blockSize;
}
return size;
}
HRESULT COneMethodInfo::ParseMethodFromString(const UString &s) HRESULT COneMethodInfo::ParseMethodFromString(const UString &s)
{ {
MethodName.Empty(); MethodName.Empty();

View File

@@ -12,12 +12,38 @@
#include "../ICoder.h" #include "../ICoder.h"
// UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads);
inline UInt64 Calc_From_Val_Percents_Less100(UInt64 val, UInt64 percents)
{
if (percents == 0)
return 0;
if (val <= (UInt64)(Int64)-1 / percents)
return val * percents / 100;
return val / 100 * percents;
}
UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents);
bool StringToBool(const wchar_t *s, bool &res); bool StringToBool(const wchar_t *s, bool &res);
HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest); HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number); unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
/*
if (name.IsEmpty() && prop.vt == VT_EMPTY), it doesn't change (resValue) and returns S_OK.
So you must set (resValue) for default value before calling */
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue); HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads); /* input: (numThreads = the_number_of_processors) */
HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force);
inline HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 numCPUs, UInt32 &numThreads)
{
bool forced = false;
numThreads = numCPUs;
return ParseMtProp2(name, prop, numThreads, forced);
}
struct CProp struct CProp
{ {
@@ -64,23 +90,34 @@ public:
unsigned GetLevel() const; unsigned GetLevel() const;
int Get_NumThreads() const int Get_NumThreads() const
{ {
int i = FindProp(NCoderPropID::kNumThreads); const int i = FindProp(NCoderPropID::kNumThreads);
if (i >= 0) if (i >= 0)
if (Props[(unsigned)i].Value.vt == VT_UI4) {
return (int)Props[(unsigned)i].Value.ulVal; const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
if (val.vt == VT_UI4)
return (int)val.ulVal;
}
return -1; return -1;
} }
bool Get_DicSize(UInt32 &res) const bool Get_DicSize(UInt64 &res) const
{ {
res = 0; res = 0;
int i = FindProp(NCoderPropID::kDictionarySize); const int i = FindProp(NCoderPropID::kDictionarySize);
if (i >= 0) if (i >= 0)
if (Props[(unsigned)i].Value.vt == VT_UI4) {
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
if (val.vt == VT_UI4)
{ {
res = Props[(unsigned)i].Value.ulVal; res = val.ulVal;
return true; return true;
} }
if (val.vt == VT_UI8)
{
res = val.uhVal.QuadPart;
return true;
}
}
return false; return false;
} }
@@ -90,28 +127,43 @@ public:
{ {
int i = FindProp(NCoderPropID::kAlgorithm); int i = FindProp(NCoderPropID::kAlgorithm);
if (i >= 0) if (i >= 0)
if (Props[(unsigned)i].Value.vt == VT_UI4) {
return Props[(unsigned)i].Value.ulVal; const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
if (val.vt == VT_UI4)
return val.ulVal;
}
return GetLevel() >= 5 ? 1 : 0; return GetLevel() >= 5 ? 1 : 0;
} }
UInt32 Get_Lzma_DicSize() const UInt64 Get_Lzma_DicSize() const
{ {
int i = FindProp(NCoderPropID::kDictionarySize); UInt64 v;
if (i >= 0) if (Get_DicSize(v))
if (Props[(unsigned)i].Value.vt == VT_UI4) return v;
return Props[(unsigned)i].Value.ulVal; const unsigned level = GetLevel();
unsigned level = GetLevel(); const UInt32 dictSize =
return ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
( level <= 3 ? (1 << (level * 2 + 16)) : ( level <= 6 ? ((UInt32)1 << (level + 19)) :
( level <= 6 ? (1 << (level + 19)) : ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
( level <= 7 ? (1 << 25) : (1 << 26)
))); )));
return dictSize;
}
bool Get_Lzma_MatchFinder_IsBt() const
{
const int i = FindProp(NCoderPropID::kMatchFinder);
if (i >= 0)
{
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
if (val.vt == VT_BSTR)
return ((val.bstrVal[0] | 0x20) != 'h'); // check for "hc"
}
return GetLevel() >= 5;
} }
bool Get_Lzma_Eos() const bool Get_Lzma_Eos() const
{ {
int i = FindProp(NCoderPropID::kEndMarker); const int i = FindProp(NCoderPropID::kEndMarker);
if (i >= 0) if (i >= 0)
{ {
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
@@ -139,6 +191,9 @@ public:
return 2; return 2;
} }
UInt64 Get_Lzma_MemUsage(bool addSlidingWindowSize) const;
/* returns -1, if numThreads is unknown */
int Get_Xz_NumThreads(UInt32 &lzmaThreads) const int Get_Xz_NumThreads(UInt32 &lzmaThreads) const
{ {
lzmaThreads = 1; lzmaThreads = 1;
@@ -152,7 +207,7 @@ public:
UInt64 GetProp_BlockSize(PROPID id) const UInt64 GetProp_BlockSize(PROPID id) const
{ {
int i = FindProp(id); const int i = FindProp(id);
if (i >= 0) if (i >= 0)
{ {
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
@@ -176,7 +231,8 @@ public:
} }
const UInt32 kMinSize = (UInt32)1 << 20; const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28; const UInt32 kMaxSize = (UInt32)1 << 28;
UInt32 dictSize = Get_Lzma_DicSize(); const UInt64 dictSize = Get_Lzma_DicSize();
/* lzma2 code uses fake 4 GiB to calculate ChunkSize. So we do same */
UInt64 blockSize = (UInt64)dictSize << 2; UInt64 blockSize = (UInt64)dictSize << 2;
if (blockSize < kMinSize) blockSize = kMinSize; if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize; if (blockSize > kMaxSize) blockSize = kMaxSize;
@@ -204,29 +260,38 @@ public:
UInt32 Get_BZip2_BlockSize() const UInt32 Get_BZip2_BlockSize() const
{ {
int i = FindProp(NCoderPropID::kDictionarySize); const int i = FindProp(NCoderPropID::kDictionarySize);
if (i >= 0) if (i >= 0)
if (Props[(unsigned)i].Value.vt == VT_UI4) {
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
if (val.vt == VT_UI4)
{ {
UInt32 blockSize = Props[(unsigned)i].Value.ulVal; UInt32 blockSize = val.ulVal;
const UInt32 kDicSizeMin = 100000; const UInt32 kDicSizeMin = 100000;
const UInt32 kDicSizeMax = 900000; const UInt32 kDicSizeMax = 900000;
if (blockSize < kDicSizeMin) blockSize = kDicSizeMin; if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
if (blockSize > kDicSizeMax) blockSize = kDicSizeMax; if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
return blockSize; return blockSize;
} }
unsigned level = GetLevel(); }
const unsigned level = GetLevel();
return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1)); return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
} }
UInt32 Get_Ppmd_MemSize() const UInt64 Get_Ppmd_MemSize() const
{ {
int i = FindProp(NCoderPropID::kUsedMemorySize); const int i = FindProp(NCoderPropID::kUsedMemorySize);
if (i >= 0) if (i >= 0)
if (Props[(unsigned)i].Value.vt == VT_UI4) {
return Props[(unsigned)i].Value.ulVal; const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
unsigned level = GetLevel(); if (val.vt == VT_UI4)
return ((UInt32)1 << (level + 19)); return val.ulVal;
if (val.vt == VT_UI8)
return val.uhVal.QuadPart;
}
const unsigned level = GetLevel();
const UInt32 mem = (UInt32)1 << (level + 19);
return mem;
} }
void AddProp_Level(UInt32 level) void AddProp_Level(UInt32 level)
@@ -245,6 +310,17 @@ public:
AddPropBool(NCoderPropID::kEndMarker, eos); AddPropBool(NCoderPropID::kEndMarker, eos);
} }
void AddProp_BlockSize2(UInt64 blockSize2)
{
if (FindProp(NCoderPropID::kBlockSize2) < 0)
{
CProp &prop = Props.AddNew();
prop.IsOptional = true;
prop.Id = NCoderPropID::kBlockSize2;
prop.Value = blockSize2;
}
}
HRESULT ParseParamsFromString(const UString &srcString); HRESULT ParseParamsFromString(const UString &srcString);
HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value); HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
}; };

View File

@@ -20,13 +20,13 @@ STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *proc
STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{ {
UInt64 absoluteNewPosition;
if (seekOrigin == STREAM_SEEK_SET) if (seekOrigin == STREAM_SEEK_SET)
{ {
if (offset < 0) if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
offset += _offset; offset += _offset;
} }
UInt64 absoluteNewPosition = 0; // =0 for gcc-10
HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition); HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
if (newPosition) if (newPosition)
*newPosition = absoluteNewPosition - _offset; *newPosition = absoluteNewPosition - _offset;

View File

@@ -52,9 +52,9 @@ HRESULT CStreamBinder::Create_ReInit()
RINOK(Event__Create_or_Reset(_canRead_Event)); RINOK(Event__Create_or_Reset(_canRead_Event));
// RINOK(Event__Create_or_Reset(_canWrite_Event)); // RINOK(Event__Create_or_Reset(_canWrite_Event));
_canWrite_Semaphore.Close(); // _canWrite_Semaphore.Close();
// we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce() // we need at least 3 items of maxCount: 1 for normal unlock in Read(), 2 items for unlock in CloseRead_CallOnce()
_canWrite_Semaphore.Create(0, 3); _canWrite_Semaphore.OptCreateInit(0, 3);
// _readingWasClosed = false; // _readingWasClosed = false;
_readingWasClosed2 = false; _readingWasClosed2 = false;

View File

@@ -11,8 +11,8 @@ class CBZip2Crc
static UInt32 Table[256]; static UInt32 Table[256];
public: public:
static void InitTable(); static void InitTable();
CBZip2Crc(): _value(0xFFFFFFFF) {}; CBZip2Crc(UInt32 initVal = 0xFFFFFFFF): _value(initVal) {};
void Init() { _value = 0xFFFFFFFF; } void Init(UInt32 initVal = 0xFFFFFFFF) { _value = initVal; }
void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } void UpdateByte(Byte b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); } void UpdateByte(unsigned int b) { _value = Table[(_value >> 24) ^ b] ^ (_value << 8); }
UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; } UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }

View File

@@ -230,15 +230,12 @@ STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
value->ulVal = (ULONG)codec.NumStreams; value->ulVal = (ULONG)codec.NumStreams;
} }
break; break;
/*
case NMethodPropID::kIsFilter: case NMethodPropID::kIsFilter:
// if (codec.IsFilter)
{ {
value->vt = VT_BOOL; value->vt = VT_BOOL;
value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter); value->boolVal = BoolToVARIANT_BOOL(codec.IsFilter);
} }
break; break;
*/
/* /*
case NMethodPropID::kDecoderFlags: case NMethodPropID::kDecoderFlags:
{ {

View File

@@ -274,15 +274,24 @@ HRESULT CCoder::CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputPro
sym = m_DistDecoder.Decode(&m_InBitStream); sym = m_DistDecoder.Decode(&m_InBitStream);
if (sym >= _numDistLevels) if (sym >= _numDistLevels)
return S_FALSE; return S_FALSE;
UInt32 distance = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]); sym = kDistStart[sym] + m_InBitStream.ReadBits(kDistDirectBits[sym]);
if (!m_OutWindowStream.CopyBlock(distance, locLen)) /*
if (sym >= 4)
{
// sym &= 31;
const unsigned numDirectBits = (unsigned)(((sym >> 1) - 1));
sym = (2 | (sym & 1)) << numDirectBits;
sym += m_InBitStream.ReadBits(numDirectBits);
}
*/
if (!m_OutWindowStream.CopyBlock(sym, locLen))
return S_FALSE; return S_FALSE;
curSize -= locLen; curSize -= locLen;
len -= locLen; len -= locLen;
if (len != 0) if (len != 0)
{ {
_remainLen = (Int32)len; _remainLen = (Int32)len;
_rep0 = distance; _rep0 = sym;
break; break;
} }
} }

View File

@@ -44,7 +44,9 @@ static const Byte kNoLenStatPrice = 11;
static const Byte kNoPosStatPrice = 6; static const Byte kNoPosStatPrice = 6;
static Byte g_LenSlots[kNumLenSymbolsMax]; static Byte g_LenSlots[kNumLenSymbolsMax];
static Byte g_FastPos[1 << 9];
#define kNumLogBits 9 // do not change it
static Byte g_FastPos[1 << kNumLogBits];
class CFastPosInit class CFastPosInit
{ {
@@ -60,7 +62,7 @@ public:
g_LenSlots[c] = (Byte)i; g_LenSlots[c] = (Byte)i;
} }
const unsigned kFastSlots = 18; const unsigned kFastSlots = kNumLogBits * 2;
unsigned c = 0; unsigned c = 0;
for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++) for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
{ {
@@ -73,14 +75,24 @@ public:
static CFastPosInit g_FastPosInit; static CFastPosInit g_FastPosInit;
inline UInt32 GetPosSlot(UInt32 pos) inline UInt32 GetPosSlot(UInt32 pos)
{ {
/*
if (pos < 0x200) if (pos < 0x200)
return g_FastPos[pos]; return g_FastPos[pos];
return g_FastPos[pos >> 8] + 16; return g_FastPos[pos >> 8] + 16;
*/
// const unsigned zz = (pos < ((UInt32)1 << (kNumLogBits))) ? 0 : 8;
/*
const unsigned zz = (kNumLogBits - 1) &
((UInt32)0 - (((((UInt32)1 << kNumLogBits) - 1) - pos) >> 31));
*/
const unsigned zz = (kNumLogBits - 1) &
(((((UInt32)1 << kNumLogBits) - 1) - pos) >> (31 - 3));
return g_FastPos[pos >> zz] + (zz * 2);
} }
void CEncProps::Normalize() void CEncProps::Normalize()
{ {
int level = Level; int level = Level;
@@ -253,13 +265,13 @@ NO_INLINE void CCoder::GetMatches()
UInt32 distanceTmp[kMatchMaxLen * 2 + 3]; UInt32 distanceTmp[kMatchMaxLen * 2 + 3];
UInt32 numPairs = (_btMode) ? const UInt32 numPairs = (UInt32)((_btMode ?
Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp): Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp):
Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp); Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp)) - distanceTmp);
*m_MatchDistances = (UInt16)numPairs; *m_MatchDistances = (UInt16)numPairs;
if (numPairs > 0) if (numPairs != 0)
{ {
UInt32 i; UInt32 i;
for (i = 0; i < numPairs; i += 2) for (i = 0; i < numPairs; i += 2)

View File

@@ -112,12 +112,34 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return S_OK; return S_OK;
} }
if (propID == NCoderPropID::kDictionarySize)
{
if (prop.vt == VT_UI8)
{
// 21.03 : we support 64-bit VT_UI8 for dictionary and (dict == 4 GiB)
const UInt64 v = prop.uhVal.QuadPart;
if (v > ((UInt64)1 << 32))
return E_INVALIDARG;
UInt32 dict;
if (v == ((UInt64)1 << 32))
dict = (UInt32)(Int32)-1;
else
dict = (UInt32)v;
ep.dictSize = dict;
return S_OK;
}
}
if (prop.vt != VT_UI4) if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
UInt32 v = prop.ulVal; UInt32 v = prop.ulVal;
switch (propID) switch (propID)
{ {
case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break; case NCoderPropID::kDefaultProp:
if (v > 32)
return E_INVALIDARG;
ep.dictSize = (v == 32) ? (UInt32)(Int32)-1 : (UInt32)1 << (unsigned)v;
break;
SET_PROP_32(kLevel, level) SET_PROP_32(kLevel, level)
SET_PROP_32(kNumFastBytes, fb) SET_PROP_32(kNumFastBytes, fb)
SET_PROP_32U(kMatchFinderCycles, mc) SET_PROP_32U(kMatchFinderCycles, mc)

View File

@@ -59,7 +59,7 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA
for (UInt32 i = 0; i < numProps; i++) for (UInt32 i = 0; i < numProps; i++)
{ {
const PROPVARIANT &prop = coderProps[i]; const PROPVARIANT &prop = coderProps[i];
PROPID propID = propIDs[i]; const PROPID propID = propIDs[i];
if (propID > NCoderPropID::kReduceSize) if (propID > NCoderPropID::kReduceSize)
continue; continue;
if (propID == NCoderPropID::kReduceSize) if (propID == NCoderPropID::kReduceSize)
@@ -68,16 +68,50 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA
props.ReduceSize = (UInt32)prop.uhVal.QuadPart; props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
continue; continue;
} }
if (propID == NCoderPropID::kUsedMemorySize)
{
// here we have selected (4 GiB - 1 KiB) as replacement for (4 GiB) MEM_SIZE.
const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10);
UInt32 v;
if (prop.vt == VT_UI8)
{
// 21.03 : we support 64-bit values (for 4 GiB value)
const UInt64 v64 = prop.uhVal.QuadPart;
if (v64 > ((UInt64)1 << 32))
return E_INVALIDARG;
if (v64 == ((UInt64)1 << 32))
v = kPpmd_Default_4g;
else
v = (UInt32)v64;
}
else if (prop.vt == VT_UI4)
v = (UInt32)prop.ulVal;
else
return E_INVALIDARG;
if (v > PPMD7_MAX_MEM_SIZE)
v = kPpmd_Default_4g;
/* here we restrict MEM_SIZE for Encoder.
It's for better performance of encoding and decoding.
The Decoder still supports more MEM_SIZE values. */
if (v < ((UInt32)1 << 16) || (v & 3) != 0)
return E_INVALIDARG;
// if (v < PPMD7_MIN_MEM_SIZE) return E_INVALIDARG; // (1 << 11)
/*
Supported MEM_SIZE range :
[ (1 << 11) , 0xFFFFFFFF - 12 * 3 ] - current 7-Zip's Ppmd7 constants
[ 1824 , 0xFFFFFFFF ] - real limits of Ppmd7 code
*/
props.MemSize = v;
continue;
}
if (prop.vt != VT_UI4) if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
UInt32 v = (UInt32)prop.ulVal; UInt32 v = (UInt32)prop.ulVal;
switch (propID) switch (propID)
{ {
case NCoderPropID::kUsedMemorySize:
if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0)
return E_INVALIDARG;
props.MemSize = v;
break;
case NCoderPropID::kOrder: case NCoderPropID::kOrder:
if (v < 2 || v > 32) if (v < 2 || v > 32)
return E_INVALIDARG; return E_INVALIDARG;

View File

@@ -21,7 +21,8 @@
11 IFolderScanProgress 11 IFolderScanProgress
20 IFileExtractCallback.h::IGetProp 20 IFileExtractCallback.h::IGetProp
30 IFileExtractCallback.h::IFolderExtractToStreamCallback 30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old)
31 IFileExtractCallback.h::IFolderExtractToStreamCallback (new 21.04)
03 IStream.h 03 IStream.h
@@ -104,6 +105,7 @@
80 IArchiveUpdateCallback 80 IArchiveUpdateCallback
82 IArchiveUpdateCallback2 82 IArchiveUpdateCallback2
83 IArchiveUpdateCallbackFile 83 IArchiveUpdateCallbackFile
84 IArchiveGetDiskProperty
A0 IOutArchive A0 IOutArchive

View File

@@ -394,7 +394,8 @@ namespace NMethodPropID
kDescription, kDescription,
kDecoderIsAssigned, kDecoderIsAssigned,
kEncoderIsAssigned, kEncoderIsAssigned,
kDigestSize kDigestSize,
kIsFilter
}; };
} }

7
CPP/7zip/LzFindOpt.mak Normal file
View File

@@ -0,0 +1,7 @@
!IF defined(USE_C_LZFINDOPT) || "$(PLATFORM)" != "x64"
C_OBJS = $(C_OBJS) \
$O\LzFindOpt.obj
!ELSE
ASM_OBJS = $(ASM_OBJS) \
$O\LzFindOpt.obj
!ENDIF

View File

@@ -103,6 +103,9 @@ enum
kpidReadOnly, kpidReadOnly,
kpidOutName, kpidOutName,
kpidCopyLink, kpidCopyLink,
kpidArcFileName,
kpidIsHash,
kpid_NUM_DEFINED, kpid_NUM_DEFINED,

View File

@@ -27,6 +27,7 @@ CCodecs *g_CodecsObj;
#ifdef EXTERNAL_CODECS #ifdef EXTERNAL_CODECS
CExternalCodecs g_ExternalCodecs; CExternalCodecs g_ExternalCodecs;
const CExternalCodecs *g_ExternalCodecs_Ptr;
static CCodecs::CReleaser g_CodecsReleaser; static CCodecs::CReleaser g_CodecsReleaser;
#else #else
extern extern
@@ -53,6 +54,7 @@ void FreeGlobalCodecs()
g_CodecsReleaser.Set(NULL); g_CodecsReleaser.Set(NULL);
g_CodecsObj = NULL; g_CodecsObj = NULL;
g_ExternalCodecs.ClearAndRelease(); g_ExternalCodecs.ClearAndRelease();
g_ExternalCodecs_Ptr = NULL;
#else #else
g_CodecsRef.Release(); g_CodecsRef.Release();
#endif #endif
@@ -83,8 +85,11 @@ HRESULT LoadGlobalCodecs()
return E_NOTIMPL; return E_NOTIMPL;
} }
Codecs_AddHashArcHandler(g_CodecsObj);
#ifdef EXTERNAL_CODECS #ifdef EXTERNAL_CODECS
RINOK(g_ExternalCodecs.Load()); RINOK(g_ExternalCodecs.Load());
g_ExternalCodecs_Ptr = &g_ExternalCodecs;
#endif #endif
return S_OK; return S_OK;
@@ -1223,7 +1228,11 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
if (_agentSpec->Is_Attrib_ReadOnly()) if (_agentSpec->Is_Attrib_ReadOnly())
prop = true; prop = true;
else else
prop = _agentSpec->IsThereReadOnlyArc(); prop = _agentSpec->IsThere_ReadOnlyArc();
}
else if (propID == kpidIsHash)
{
prop = _agentSpec->_isHashHandler;
} }
else if (_proxy2) else if (_proxy2)
{ {
@@ -1446,6 +1455,10 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
IFolderArchiveExtractCallback *extractCallback2) IFolderArchiveExtractCallback *extractCallback2)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
if (!testMode && _agentSpec->_isHashHandler)
return E_NOTIMPL;
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UStringVector pathParts; UStringVector pathParts;
@@ -1500,6 +1513,9 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
if (_proxy2) if (_proxy2)
extractCallbackSpec->SetBaseParentFolderIndex(_proxy2->Dirs[_proxyDirIndex].ArcIndex); extractCallbackSpec->SetBaseParentFolderIndex(_proxy2->Dirs[_proxyDirIndex].ArcIndex);
// do we need another base folder for subfolders ?
extractCallbackSpec->DirPathPrefix_for_HashFiles = _agentSpec->_hashBaseFolderPrefix;
CUIntVector realIndices; CUIntVector realIndices;
GetRealIndices(indices, numItems, IntToBool(includeAltStreams), GetRealIndices(indices, numItems, IntToBool(includeAltStreams),
false, // includeFolderSubItemsInFlatMode false, // includeFolderSubItemsInFlatMode
@@ -1536,7 +1552,8 @@ CAgent::CAgent():
_proxy(NULL), _proxy(NULL),
_proxy2(NULL), _proxy2(NULL),
_updatePathPrefix_is_AltFolder(false), _updatePathPrefix_is_AltFolder(false),
_isDeviceFile(false) _isDeviceFile(false),
_isHashHandler(false)
{ {
} }
@@ -1571,9 +1588,11 @@ STDMETHODIMP CAgent::Open(
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
_archiveFilePath = filePath; _archiveFilePath = filePath;
_hashBaseFolderPrefix.Empty();
_attrib = 0; _attrib = 0;
NFile::NFind::CFileInfo fi;
_isDeviceFile = false; _isDeviceFile = false;
_isHashHandler = false;
NFile::NFind::CFileInfo fi;
if (!inStream) if (!inStream)
{ {
if (!fi.Find(us2fs(_archiveFilePath))) if (!fi.Find(us2fs(_archiveFilePath)))
@@ -1582,6 +1601,12 @@ STDMETHODIMP CAgent::Open(
return E_FAIL; return E_FAIL;
_attrib = fi.Attrib; _attrib = fi.Attrib;
_isDeviceFile = fi.IsDevice; _isDeviceFile = fi.IsDevice;
FString dirPrefix, fileName;
if (NFile::NDir::GetFullPathAndSplit(us2fs(_archiveFilePath), dirPrefix, fileName))
{
NFile::NName::NormalizeDirPathPrefix(dirPrefix);
_hashBaseFolderPrefix = dirPrefix;
}
} }
CArcInfoEx archiverInfo0, archiverInfo1; CArcInfoEx archiverInfo0, archiverInfo1;
@@ -1629,6 +1654,9 @@ STDMETHODIMP CAgent::Open(
{ {
RINOK(StringToBstr(ArchiveType, archiveType)); RINOK(StringToBstr(ArchiveType, archiveType));
} }
if (arc.IsHashHandler(options))
_isHashHandler = true;
} }
return res; return res;
@@ -1745,6 +1773,10 @@ STDMETHODIMP CAgent::Extract(
IFolderArchiveExtractCallback *extractCallback2) IFolderArchiveExtractCallback *extractCallback2)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
if (!testMode && _isHashHandler)
return E_NOTIMPL;
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec; CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
extractCallbackSpec->InitForMulti( extractCallbackSpec->InitForMulti(
@@ -1769,6 +1801,8 @@ STDMETHODIMP CAgent::Extract(
UStringVector(), false, UStringVector(), false,
(UInt64)(Int64)-1); (UInt64)(Int64)-1);
extractCallbackSpec->DirPathPrefix_for_HashFiles = _hashBaseFolderPrefix;
#ifdef SUPPORT_LINKS #ifdef SUPPORT_LINKS
if (!testMode) if (!testMode)

View File

@@ -234,7 +234,7 @@ public:
UString ArchiveType; UString ArchiveType;
FStringVector _names; FStringVector _names;
FString _folderPrefix; FString _folderPrefix; // for new files from disk
bool _updatePathPrefix_is_AltFolder; bool _updatePathPrefix_is_AltFolder;
UString _updatePathPrefix; UString _updatePathPrefix;
@@ -243,6 +243,8 @@ public:
UString _archiveFilePath; UString _archiveFilePath;
DWORD _attrib; DWORD _attrib;
bool _isDeviceFile; bool _isDeviceFile;
bool _isHashHandler;
FString _hashBaseFolderPrefix;
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
CObjectVector<UString> m_PropNames; CObjectVector<UString> m_PropNames;
@@ -258,7 +260,7 @@ public:
return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY); return _attrib != INVALID_FILE_ATTRIBUTES && (_attrib & FILE_ATTRIBUTE_READONLY);
} }
bool IsThereReadOnlyArc() const bool IsThere_ReadOnlyArc() const
{ {
FOR_VECTOR (i, _archiveLink.Arcs) FOR_VECTOR (i, _archiveLink.Arcs)
{ {

View File

@@ -158,6 +158,8 @@ static void SetInArchiveInterfaces(CAgent *agent, CArchiveUpdateCallback *upd)
const CArc &arc = agent->GetArc(); const CArc &arc = agent->GetArc();
upd->Arc = &arc; upd->Arc = &arc;
upd->Archive = arc.Archive; upd->Archive = arc.Archive;
upd->ArcFileName = ExtractFileNameFromPath(arc.Path);
} }
struct CDirItemsCallback_AgentOut: public IDirItemsCallback struct CDirItemsCallback_AgentOut: public IDirItemsCallback
@@ -190,6 +192,7 @@ struct CDirItemsCallback_AgentOut: public IDirItemsCallback
} }
}; };
STDMETHODIMP CAgent::DoOperation( STDMETHODIMP CAgent::DoOperation(
FStringVector *requestedPaths, FStringVector *requestedPaths,
FStringVector *processedPaths, FStringVector *processedPaths,

View File

@@ -70,6 +70,9 @@ HRESULT CAgentFolder::CommonUpdateOperation(
const UInt32 *indices, UInt32 numItems, const UInt32 *indices, UInt32 numItems,
IProgress *progress) IProgress *progress)
{ {
if (moveMode && _agentSpec->_isHashHandler)
return E_NOTIMPL;
if (!_agentSpec->CanUpdate()) if (!_agentSpec->CanUpdate())
return E_NOTIMPL; return E_NOTIMPL;

View File

@@ -153,7 +153,7 @@ HRESULT CUpdateCallbackAgent::ReportExtractResult(Int32 opRes, Int32 isEncrypted
return S_OK; return S_OK;
} }
HRESULT CUpdateCallbackAgent::ReportUpdateOpeartion(UInt32 op, const wchar_t *name, bool isDir) HRESULT CUpdateCallbackAgent::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir)
{ {
if (Callback2) if (Callback2)
{ {

View File

@@ -217,6 +217,7 @@ static const char * const kIncorrectCommand = "incorrect command";
static const char * const kTestingString = "Testing "; static const char * const kTestingString = "Testing ";
static const char * const kExtractingString = "Extracting "; static const char * const kExtractingString = "Extracting ";
static const char * const kSkippingString = "Skipping "; static const char * const kSkippingString = "Skipping ";
static const char * const kReadingString = "Reading ";
static const char * const kUnsupportedMethod = "Unsupported Method"; static const char * const kUnsupportedMethod = "Unsupported Method";
static const char * const kCRCFailed = "CRC Failed"; static const char * const kCRCFailed = "CRC Failed";
@@ -419,6 +420,9 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break; case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break;
case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break; case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break;
case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break; case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break;
case NArchive::NExtract::NAskMode::kReadExternal: Print(kReadingString); break;
default:
Print("??? "); break;
}; };
Print(_filePath); Print(_filePath);
return S_OK; return S_OK;

View File

@@ -133,6 +133,8 @@ enum Enum
kSfx, kSfx,
kEmail, kEmail,
kHash, kHash,
// kHashGenFile,
kHashDir,
kStdIn, kStdIn,
kStdOut, kStdOut,
@@ -141,6 +143,7 @@ enum Enum
kListfileCharSet, kListfileCharSet,
kConsoleCharSet, kConsoleCharSet,
kTechMode, kTechMode,
kListFields,
kPreserveATime, kPreserveATime,
kShareForWrite, kShareForWrite,
@@ -273,6 +276,8 @@ static const CSwitchForm kSwitchForms[] =
{ "sfx", SWFRM_STRING }, { "sfx", SWFRM_STRING },
{ "seml", SWFRM_STRING_SINGL(0) }, { "seml", SWFRM_STRING_SINGL(0) },
{ "scrc", SWFRM_STRING_MULT(0) }, { "scrc", SWFRM_STRING_MULT(0) },
// { "scrf", SWFRM_STRING_SINGL(1) },
{ "shd", SWFRM_STRING_SINGL(1) },
{ "si", SWFRM_STRING }, { "si", SWFRM_STRING },
{ "so", SWFRM_SIMPLE }, { "so", SWFRM_SIMPLE },
@@ -281,6 +286,7 @@ static const CSwitchForm kSwitchForms[] =
{ "scs", SWFRM_STRING }, { "scs", SWFRM_STRING },
{ "scc", SWFRM_STRING }, { "scc", SWFRM_STRING },
{ "slt", SWFRM_SIMPLE }, { "slt", SWFRM_SIMPLE },
{ "slf", SWFRM_STRING_SINGL(1) },
{ "ssp", SWFRM_SIMPLE }, { "ssp", SWFRM_SIMPLE },
{ "ssw", SWFRM_SIMPLE }, { "ssw", SWFRM_SIMPLE },
@@ -626,7 +632,21 @@ static void AddSwitchWildcardsToCensor(
errorMessage = "Too short switch"; errorMessage = "Too short switch";
break; break;
} }
if (!include)
{
if (name.IsEqualTo_Ascii_NoCase("td"))
{
censor.ExcludeDirItems = true;
continue;
}
if (name.IsEqualTo_Ascii_NoCase("tf"))
{
censor.ExcludeFileItems = true;
continue;
}
}
if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar) if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar)
{ {
pos++; pos++;
@@ -875,6 +895,11 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
options.StdInMode = parser[NKey::kStdIn].ThereIs; options.StdInMode = parser[NKey::kStdIn].ThereIs;
options.StdOutMode = parser[NKey::kStdOut].ThereIs; options.StdOutMode = parser[NKey::kStdOut].ThereIs;
options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
if (parser[NKey::kListFields].ThereIs)
{
const UString &s = parser[NKey::kListFields].PostStrings[0];
options.ListFields = GetAnsiString(s);
}
options.TechMode = parser[NKey::kTechMode].ThereIs; options.TechMode = parser[NKey::kTechMode].ThereIs;
options.ShowTime = parser[NKey::kShowTime].ThereIs; options.ShowTime = parser[NKey::kShowTime].ThereIs;
@@ -1094,6 +1119,27 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kHash].ThereIs) if (parser[NKey::kHash].ThereIs)
options.HashMethods = parser[NKey::kHash].PostStrings; options.HashMethods = parser[NKey::kHash].PostStrings;
/*
if (parser[NKey::kHashGenFile].ThereIs)
{
const UString &s = parser[NKey::kHashGenFile].PostStrings[0];
for (unsigned i = 0 ; i < s.Len();)
{
const wchar_t c = s[i++];
if (!options.HashOptions.ParseFlagCharOption(c, true))
{
if (c != '=')
throw CArcCmdLineException("Unsupported hash mode switch:", s);
options.HashOptions.HashFilePath = s.Ptr(i);
break;
}
}
}
*/
if (parser[NKey::kHashDir].ThereIs)
options.ExtractOptions.HashDir = parser[NKey::kHashDir].PostStrings[0];
if (parser[NKey::kElimDup].ThereIs) if (parser[NKey::kElimDup].ThereIs)
{ {
@@ -1232,6 +1278,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
{ {
CExtractOptionsBase &eo = options.ExtractOptions; CExtractOptionsBase &eo = options.ExtractOptions;
eo.ExcludeDirItems = options.Censor.ExcludeDirItems;
eo.ExcludeFileItems = options.Censor.ExcludeFileItems;
{ {
CExtractNtOptions &nt = eo.NtOptions; CExtractNtOptions &nt = eo.NtOptions;
nt.NtSecurity = options.NtSecurity; nt.NtSecurity = options.NtSecurity;
@@ -1252,6 +1301,11 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs; nt.ReplaceColonForAltStream = parser[NKey::kReplaceColonForAltStream].ThereIs;
nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs; nt.WriteToAltStreamIfColon = parser[NKey::kWriteToAltStreamIfColon].ThereIs;
if (parser[NKey::kPreserveATime].ThereIs)
nt.PreserveATime = true;
if (parser[NKey::kShareForWrite].ThereIs)
nt.OpenShareForWrite = true;
} }
options.Censor.AddPathsToCensor(NWildcard::k_AbsPath); options.Censor.AddPathsToCensor(NWildcard::k_AbsPath);
@@ -1405,11 +1459,13 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
else if (options.Command.CommandType == NCommandType::kBenchmark) else if (options.Command.CommandType == NCommandType::kBenchmark)
{ {
options.NumIterations = 1; options.NumIterations = 1;
options.NumIterations_Defined = false;
if (curCommandIndex < numNonSwitchStrings) if (curCommandIndex < numNonSwitchStrings)
{ {
if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations)) if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations))
throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]); throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]);
curCommandIndex++; curCommandIndex++;
options.NumIterations_Defined = true;
} }
} }
else if (options.Command.CommandType == NCommandType::kHash) else if (options.Command.CommandType == NCommandType::kHash)
@@ -1420,6 +1476,7 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
CHashOptions &hashOptions = options.HashOptions; CHashOptions &hashOptions = options.HashOptions;
hashOptions.PathMode = censorPathMode; hashOptions.PathMode = censorPathMode;
hashOptions.Methods = options.HashMethods; hashOptions.Methods = options.HashMethods;
// hashOptions.HashFilePath = options.HashFilePath;
if (parser[NKey::kPreserveATime].ThereIs) if (parser[NKey::kPreserveATime].ThereIs)
hashOptions.PreserveATime = true; hashOptions.PreserveATime = true;
if (parser[NKey::kShareForWrite].ThereIs) if (parser[NKey::kShareForWrite].ThereIs)

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