This commit is contained in:
Igor Pavlov
2021-11-28 19:01:13 -08:00
committed by fn ⌃ ⌥
parent 585698650f
commit d789d4137d
88 changed files with 5996 additions and 1875 deletions

View File

@@ -1,5 +1,5 @@
; 7zAsm.asm -- ASM macros
; 2021-02-07 : Igor Pavlov : Public domain
; 2021-07-13 : Igor Pavlov : Public domain
ifdef RAX
x64 equ 1
@@ -171,6 +171,7 @@ endm
; for fastcall and for WIN-x64
REG_PARAM_0_x equ x1
REG_PARAM_0 equ r1
REG_PARAM_1_x equ x2
REG_PARAM_1 equ r2
ifndef x64
@@ -178,6 +179,7 @@ ifndef x64
REG_ABI_PARAM_0_x equ REG_PARAM_0_x
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
else
@@ -186,28 +188,39 @@ else
if (IS_LINUX eq 0)
; for WIN-x64:
REG_PARAM_2 equ r8
REG_PARAM_3 equ r9
REG_PARAM_2_x equ x8
REG_PARAM_2 equ r8
REG_PARAM_3 equ r9
REG_ABI_PARAM_0_x equ REG_PARAM_0_x
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_2_x equ REG_PARAM_2_x
REG_ABI_PARAM_2 equ REG_PARAM_2
REG_ABI_PARAM_3 equ REG_PARAM_3
else
; for LINUX-x64:
REG_LINUX_PARAM_0_x equ x7
REG_LINUX_PARAM_0 equ r7
REG_LINUX_PARAM_1 equ r6
REG_LINUX_PARAM_2 equ r2
REG_LINUX_PARAM_3 equ r1
REG_LINUX_PARAM_0 equ r7
REG_LINUX_PARAM_1_x equ x6
REG_LINUX_PARAM_1 equ r6
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 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_2 equ REG_LINUX_PARAM_2
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
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-13: 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 + 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
2021-04-25 : Igor Pavlov : Public domain */
2021-07-13 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
@@ -62,6 +62,8 @@ typedef int SRes;
typedef unsigned WRes;
#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
// #define ENV_HAVE_LSTAT
@@ -95,6 +97,7 @@ typedef int WRes;
#define ERROR_DIRECTORY 267L
#define ERROR_TOO_MANY_POSTS 298L
#define ERROR_INTERNAL_ERROR 1359L
#define ERROR_INVALID_REPARSE_DATA 4392L
#define ERROR_REPARSE_TAG_INVALID 4393L
#define ERROR_REPARSE_TAG_MISMATCH 4394L
@@ -206,6 +209,8 @@ typedef size_t SIZE_T;
#endif // _WIN32
#define MY_HRES_ERROR__INTERNAL_ERROR ((HRESULT)0x8007054FL)
#ifdef _SZ_NO_INT_64

View File

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

10
C/Aes.c
View File

@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption
2021-04-01 : Igor Pavlov : Public domain */
2021-05-13 : Igor Pavlov : Public domain */
#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
*((UInt32 *)(void *)data) ^= t;
#else
data[0] ^= (t & 0xFF);
data[1] ^= ((t >> 8) & 0xFF);
data[2] ^= ((t >> 16) & 0xFF);
data[3] ^= ((t >> 24));
data[0] = (Byte)(data[0] ^ (t & 0xFF));
data[1] = (Byte)(data[1] ^ ((t >> 8) & 0xFF));
data[2] = (Byte)(data[2] ^ ((t >> 16) & 0xFF));
data[3] = (Byte)(data[3] ^ ((t >> 24)));
#endif
}
}

View File

@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
2020-10-29 : Igor Pavlov : Public domain */
2021-07-13 : Igor Pavlov : Public domain */
#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); }
const ISzAlloc g_Alloc = { SzAlloc, SzFree };
#ifdef _WIN32
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); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
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); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#endif
/*
uintptr_t : <stdint.h> C99 (optional)

View File

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

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
2021-04-28 : Igor Pavlov : Public domain */
2021-07-13 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -278,6 +278,30 @@ BoolInt CPU_IsSupported_SHA()
#include <Windows.h>
#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()
{
Cx86cpuid p;
@@ -329,10 +353,9 @@ BoolInt CPU_IsSupported_PageGB()
#include <Windows.h>
BoolInt CPU_IsSupported_CRC32()
{ 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_CRC32() { 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_NEON() { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; }
#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("machdep.cpu.brand_string");
*/
UInt32 val = 0;
if (My_sysctlbyname_Get_UInt32("hw.optional.armv8_crc32", &val) == 0 && val == 1)
return 1;
return 0;
BoolInt CPU_IsSupported_CRC32(void)
{
return My_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32");
}
BoolInt CPU_IsSupported_NEON(void)
{
return My_sysctlbyname_Get_BoolInt("hw.optional.neon");
}
#ifdef MY_CPU_ARM64
@@ -390,18 +423,25 @@ BoolInt CPU_IsSupported_AES (void) { return APPLE_CRYPTO_SUPPORT_VAL; }
#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
#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)
#define MY_HWCAP_CHECK_FUNC(name) \
BoolInt CPU_IsSupported_ ## name() { return (getauxval(AT_HWCAP2) & (HWCAP2_ ## name)) ? 1 : 0; }
MY_HWCAP_CHECK_FUNC_2(NEON, NEON)
#endif
#else // USE_HWCAP
#define MY_HWCAP_CHECK_FUNC(name) \
BoolInt CPU_IsSupported_ ## name() { return 0; }
MY_HWCAP_CHECK_FUNC(NEON)
#endif // USE_HWCAP

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2021-04-25 : Igor Pavlov : Public domain */
2021-07-13 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -225,7 +225,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#endif
#else
#ifdef __xlC__
// for XLC compiler:
#define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)")
#define MY_CPU_pragma_pop _Pragma("pack()")
#else
@@ -253,8 +252,12 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED)
|| defined(MY_CPU_ARM64)
#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
#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 GetUi32(p) (*(const UInt32 *)(const void *)(p))
#ifdef MY_CPU_LE_UNALIGN_64
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#endif
#define SetUi16(p, v) { *(UInt16 *)(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); }
#endif
#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))[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); \
_ppp_[0] = (Byte)_vvv_; \
_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_[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); \
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
#ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x)
#else
@@ -392,6 +407,7 @@ int x86cpuid_GetFirm(const Cx86cpuid *p);
BoolInt CPU_Is_InOrder(void);
BoolInt CPU_IsSupported_AES(void);
BoolInt CPU_IsSupported_AVX2(void);
BoolInt CPU_IsSupported_VAES_AVX2(void);
BoolInt CPU_IsSupported_SSSE3(void);
BoolInt CPU_IsSupported_SSE41(void);
@@ -401,6 +417,7 @@ BoolInt CPU_IsSupported_PageGB(void);
#elif defined(MY_CPU_ARM_OR_ARM64)
BoolInt CPU_IsSupported_CRC32(void);
BoolInt CPU_IsSupported_NEON(void);
#if defined(_WIN32)
BoolInt CPU_IsSupported_CRYPTO(void);

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
2021-02-09 : Igor Pavlov : Public domain */
2021-07-13 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
@@ -15,7 +15,7 @@ typedef struct _CMatchFinder
Byte *buffer;
UInt32 pos;
UInt32 posLimit;
UInt32 streamPos;
UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */
UInt32 lenLimit;
UInt32 cyclicBufferPos;
@@ -51,17 +51,19 @@ typedef struct _CMatchFinder
UInt64 expectedDataSize;
} 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) \
((p)->streamEndWasReached \
&& (p)->streamPos == (p)->pos \
&& (!(p)->directInput || (p)->directInputRem == 0))
*/
int MatchFinder_NeedMove(CMatchFinder *p);
// Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
/* Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); */
void MatchFinder_MoveBlock(CMatchFinder *p);
void MatchFinder_ReadIfRequired(CMatchFinder *p);
@@ -76,10 +78,21 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
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 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 maxLen);
/*
@@ -91,7 +104,7 @@ Conditions:
typedef void (*Mf_Init_Func)(void *object);
typedef UInt32 (*Mf_GetNumAvailableBytes_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 struct _IMatchFinder
@@ -101,21 +114,23 @@ typedef struct _IMatchFinder
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;
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_HighHash(CMatchFinder *p);
void MatchFinder_Init_3(CMatchFinder *p, int readData);
void MatchFinder_Init_4(CMatchFinder *p);
void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void LzFindPrepare(void);
EXTERN_C_END
#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
2019-11-05 : Igor Pavlov : Public domain */
2021-07-12 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H
@@ -11,22 +11,24 @@ EXTERN_C_BEGIN
typedef struct _CMtSync
{
UInt32 numProcessedBlocks;
CThread thread;
UInt64 affinity;
BoolInt wasCreated;
BoolInt needStart;
BoolInt csWasInitialized;
BoolInt csWasEntered;
BoolInt exit;
BoolInt stopWriting;
CThread thread;
CAutoResetEvent canStart;
CAutoResetEvent wasStarted;
CAutoResetEvent wasStopped;
CSemaphore freeSemaphore;
CSemaphore filledSemaphore;
BoolInt csWasInitialized;
BoolInt csWasEntered;
CCriticalSection cs;
UInt32 numProcessedBlocks;
UInt64 affinity;
// UInt32 numBlocks_Sent;
} CMtSync;
typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
@@ -42,8 +44,8 @@ typedef struct _CMatchFinderMt
/* LZ */
const Byte *pointerToCurPos;
UInt32 *btBuf;
UInt32 btBufPos;
UInt32 btBufPosLimit;
const UInt32 *btBufPos;
const UInt32 *btBufPosLimit;
UInt32 lzPos;
UInt32 btNumAvailBytes;
@@ -54,6 +56,10 @@ typedef struct _CMatchFinderMt
const UInt32 *crc;
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 */
CMtSync btSync;
@@ -64,6 +70,8 @@ typedef struct _CMatchFinderMt
UInt32 hashBufPos;
UInt32 hashBufPosLimit;
UInt32 hashNumAvail;
UInt32 failure_BT;
CLzRef *son;
UInt32 matchMaxLen;
@@ -71,7 +79,7 @@ typedef struct _CMatchFinderMt
UInt32 pos;
const Byte *buffer;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
UInt32 cutValue;
/* BT + Hash */
@@ -81,13 +89,19 @@ typedef struct _CMatchFinderMt
/* Hash */
Mf_GetHeads GetHeadsFunc;
CMatchFinder *MatchFinder;
// CMatchFinder MatchFinder;
} CMatchFinderMt;
// only for Mt part
void MatchFinderMt_Construct(CMatchFinderMt *p);
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
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);
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
2021-04-01: Igor Pavlov : Public domain */
2021-07-10: Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -12,6 +12,7 @@
#include <stdio.h>
#endif
#include "CpuArch.h"
#include "LzmaEnc.h"
#include "LzFind.h"
@@ -36,8 +37,8 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp);
static unsigned g_STAT_OFFSET = 0;
#endif
#define kLzmaMaxHistorySize ((UInt32)3 << 29)
/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
/* for good normalization speed we still reserve 256 MB before 4 GB range */
#define kLzmaMaxHistorySize ((UInt32)15 << 28)
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
@@ -78,13 +79,12 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (p->dictSize > p->reduceSize)
{
unsigned i;
UInt32 reduceSize = (UInt32)p->reduceSize;
for (i = 11; i <= 30; i++)
{
if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
}
UInt32 v = (UInt32)p->reduceSize;
const UInt32 kReduceMin = ((UInt32)1 << 12);
if (v < kReduceMin)
v = kReduceMin;
if (p->dictSize > v)
p->dictSize = v;
}
if (p->lc < 0) p->lc = 3;
@@ -113,18 +113,85 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
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
// #include <intrin.h>
#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;
BSR2_RET(pos, res);
@@ -133,10 +200,10 @@ static unsigned GetPosSlot1(UInt32 pos)
#define GetPosSlot2(pos, res) { 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)
/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
#else // ! LZMA_LOG_BSR
#define kNumLogBits (11 + sizeof(size_t) / 8 * 3)
#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 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
@@ -319,7 +386,7 @@ typedef UInt32 CProbPrice;
typedef struct
{
void *matchFinderObj;
IMatchFinder matchFinder;
IMatchFinder2 matchFinder;
unsigned optCur;
unsigned optEnd;
@@ -364,10 +431,14 @@ typedef struct
// begin of CMatchFinderMt is used in LZ thread
CMatchFinderMt matchFinderMt;
// end of CMatchFinderMt is used in BT and HASH threads
// #else
// CMatchFinder matchFinderBase;
#endif
CMatchFinder matchFinderBase;
// we suppose that we have 8-bytes alignment after CMatchFinder
#ifndef _7ZIP_ST
Byte pad[128];
#endif
@@ -375,8 +446,10 @@ typedef struct
// LZ thread
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 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
@@ -405,12 +478,19 @@ typedef struct
CSaveState saveState;
// BoolInt mf_Failure;
#ifndef _7ZIP_ST
Byte pad2[128];
#endif
} 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));
@@ -475,11 +555,21 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
if (props.lc > LZMA_LC_MAX
|| props.lp > LZMA_LP_MAX
|| props.pb > LZMA_PB_MAX
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|| props.dictSize > kLzmaMaxHistorySize)
|| props.pb > LZMA_PB_MAX)
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;
{
unsigned fb = (unsigned)props.fb;
@@ -494,7 +584,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->pb = (unsigned)props.pb;
p->fastMode = (props.algo == 0);
// p->_maxMode = True;
p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
MFB.btMode = (Byte)(props.btMode ? 1 : 0);
{
unsigned numHashBytes = 4;
if (props.btMode)
@@ -504,10 +594,10 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
}
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;
@@ -531,7 +621,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.expectedDataSize = expectedDataSiize;
MFB.expectedDataSize = expectedDataSiize;
}
@@ -1007,7 +1097,11 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
p->additionalOffset++;
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;
#ifdef SHOW_STAT
@@ -1023,7 +1117,7 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
if (numPairs == 0)
return 0;
{
unsigned len = p->matches[(size_t)numPairs - 2];
const unsigned len = p->matches[(size_t)numPairs - 2];
if (len != p->numFastBytes)
return len;
{
@@ -1033,7 +1127,7 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
{
const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
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;
for (; p2 != lim && *p2 == p2[dif]; p2++)
{}
@@ -1189,6 +1283,8 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
repLens[i] = len;
if (len > repLens[repMaxIndex])
repMaxIndex = i;
if (len == LZMA_MATCH_LEN_MAX) // 21.03 : optimization
break;
}
if (repLens[repMaxIndex] >= p->numFastBytes)
@@ -1201,10 +1297,12 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
}
matches = p->matches;
#define MATCHES matches
// #define MATCHES p->matches
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)
return mainLen;
}
@@ -1298,13 +1396,13 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
if (len < 2)
len = 2;
else
while (len > matches[offs])
while (len > MATCHES[offs])
offs += 2;
for (; ; len++)
{
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);
unsigned lenToPosState = GetLenToPosState(len);
@@ -1328,7 +1426,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
opt->extra = 0;
}
if (len == matches[offs])
if (len == MATCHES[offs])
{
offs += 2;
if (offs == numPairs)
@@ -1749,8 +1847,8 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
if (newLen > numAvail)
{
newLen = numAvail;
for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
matches[numPairs] = (UInt32)newLen;
for (numPairs = 0; newLen > MATCHES[numPairs]; numPairs += 2);
MATCHES[numPairs] = (UInt32)newLen;
numPairs += 2;
}
@@ -1769,9 +1867,9 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
}
offs = 0;
while (startLen > matches[offs])
while (startLen > MATCHES[offs])
offs += 2;
dist = matches[(size_t)offs + 1];
dist = MATCHES[(size_t)offs + 1];
// if (dist >= kNumFullDistances)
GetPosSlot2(dist, posSlot);
@@ -1798,7 +1896,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
}
}
if (len == matches[offs])
if (len == MATCHES[offs])
{
// if (p->_maxMode) {
// MATCH : LIT : REP_0
@@ -1863,7 +1961,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
offs += 2;
if (offs == numPairs)
break;
dist = matches[(size_t)offs + 1];
dist = MATCHES[(size_t)offs + 1];
// if (dist >= kNumFullDistances)
GetPosSlot2(dist, posSlot);
}
@@ -2081,8 +2179,23 @@ static SRes CheckErrors(CLzmaEnc *p)
return p->result;
if (p->rc.res != SZ_OK)
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;
if (p->result != SZ_OK)
p->finished = True;
return p->result;
@@ -2223,11 +2336,11 @@ MY_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p)
static void LzmaEnc_Construct(CLzmaEnc *p)
{
RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase);
MatchFinder_Construct(&MFB);
#ifndef _7ZIP_ST
p->matchFinderMt.MatchFinder = &MFB;
MatchFinderMt_Construct(&p->matchFinderMt);
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
#endif
{
@@ -2243,7 +2356,6 @@ static void LzmaEnc_Construct(CLzmaEnc *p)
LzmaEnc_InitPriceTables(p->ProbPrices);
p->litProbs = NULL;
p->saveState.litProbs = NULL;
}
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
@@ -2269,7 +2381,7 @@ static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBi
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
#endif
MatchFinder_Free(&p->matchFinderBase, allocBig);
MatchFinder_Free(&MFB, allocBig);
LzmaEnc_FreeLits(p, alloc);
RangeEnc_Free(&p->rc, alloc);
}
@@ -2287,6 +2399,12 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa
UInt32 nowPos32, startPos32;
if (p->needInit)
{
#ifndef _7ZIP_ST
if (p->mtMode)
{
RINOK(MatchFinderMt_InitMt(&p->matchFinderMt));
}
#endif
p->matchFinder.Init(p->matchFinderObj);
p->needInit = 0;
}
@@ -2582,11 +2700,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
UInt32 beforeSize = kNumOpts;
UInt32 dictSize;
if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM;
#ifndef _7ZIP_ST
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0));
#endif
{
@@ -2605,30 +2725,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
if (p->mtMode)
{
RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes,
LZMA_MATCH_LEN_MAX
+ 1 /* 18.04 */
RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize,
p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */
, allocBig));
p->matchFinderObj = &p->matchFinderMt;
p->matchFinderBase.bigHash = (Byte)(
(p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
MFB.bigHash = (Byte)(
(p->dictSize > kBigHashDicLimit && MFB.hashMask >= 0xFFFFFF) ? 1 : 0);
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
}
else
#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;
p->matchFinderObj = &p->matchFinderBase;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
p->matchFinderObj = &MFB;
MatchFinder_CreateVTable(&MFB, &p->matchFinder);
}
return SZ_OK;
@@ -2700,6 +2840,8 @@ static void LzmaEnc_Init(CLzmaEnc *p)
p->pbMask = ((unsigned)1 << p->pb) - 1;
p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
// p->mf_Failure = False;
}
@@ -2742,7 +2884,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS
ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream;
MFB.stream = inStream;
p->needInit = 1;
p->rc.outStream = outStream;
return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
@@ -2753,16 +2895,16 @@ SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
ISzAllocPtr alloc, ISzAllocPtr allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->matchFinderBase.stream = inStream;
MFB.stream = inStream;
p->needInit = 1;
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
}
static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
{
p->matchFinderBase.directInput = 1;
p->matchFinderBase.bufferBase = (Byte *)src;
p->matchFinderBase.directInputRem = srcLen;
MFB.directInput = 1;
MFB.bufferBase = (Byte *)src;
MFB.directInputRem = srcLen;
}
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
@@ -2895,7 +3037,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
LzmaEnc_Finish(p);
/*
if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB))
res = SZ_ERROR_FAIL;
}
*/
@@ -2914,29 +3056,37 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
unsigned i;
UInt32 dictSize = p->dictSize;
if (*size < LZMA_PROPS_SIZE)
return SZ_ERROR_PARAM;
*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;
if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
dictSize = (dictSize + kDictMask) & ~kDictMask;
}
else for (i = 11; i <= 30; i++)
{
if (dictSize <= ((UInt32)2 << i)) { dictSize = ((UInt32)2 << i); break; }
if (dictSize <= ((UInt32)3 << i)) { dictSize = ((UInt32)3 << i); break; }
}
const CLzmaEnc *p = (const CLzmaEnc *)pp;
const UInt32 dictSize = p->dictSize;
UInt32 v;
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
// we write aligned dictionary value to properties for lzma decoder
if (dictSize >= ((UInt32)1 << 21))
{
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++)
props[1 + i] = (Byte)(dictSize >> (8 * i));
return SZ_OK;
SetUi32(props + 1, v);
return SZ_OK;
}
}

View File

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

View File

@@ -1,5 +1,5 @@
/* 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. */
#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
#elif defined(MY_CPU_ARM_OR_ARM64)
#ifdef _MSC_VER
#if _MSC_VER >= 1910
#if _MSC_VER >= 1910 && _MSC_VER >= 1929 && _MSC_FULL_VER >= 192930037
#define _SHA_SUPPORTED
#endif
#elif defined(__clang__)
@@ -435,7 +435,37 @@ void Sha1Prepare()
#endif
{
// 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_HW = f_hw;

View File

@@ -1,5 +1,5 @@
/* Threads.c -- multithreading library
2021-04-25 : Igor Pavlov : Public domain */
2021-07-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -150,6 +150,17 @@ WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
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)
{ return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
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)
{
/* 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
__try
#endif
@@ -167,7 +180,7 @@ WRes CriticalSection_Init(CCriticalSection *p)
/* InitializeCriticalSectionAndSpinCount(p, 0); */
}
#ifdef _MSC_VER
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
__except (EXCEPTION_EXECUTE_HANDLER) { return ERROR_NOT_ENOUGH_MEMORY; }
#endif
return 0;
}
@@ -406,6 +419,27 @@ WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
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)
{
UInt32 newCount;

View File

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

View File

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

View File

@@ -13,6 +13,7 @@ C_OBJS = \
$O\Alloc.obj \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\LzFindOpt.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\LzmaLib.obj \

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
# USE_ASM = 1
# IS_X64 = 1
# MY_ARCH =
# USE_ASM=
MY_ARCH_2 = $(MY_ARCH)
@@ -23,6 +23,8 @@ CFLAGS_BASE = -O2 $(CFLAGS_BASE_LIST) $(CFLAGS_WARN_WALL) $(CFLAGS_WARN) \
-DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
-fPIC
# -D_7ZIP_AFFINITY_DISABLE
ifdef SystemDrive
IS_MINGW = 1
@@ -186,6 +188,8 @@ $O/Lang.o: ../../../Common/Lang.cpp
$(CXX) $(CXXFLAGS) $<
$O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp
$(CXX) $(CXXFLAGS) $<
$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp
$(CXX) $(CXXFLAGS) $<
$O/MyMap.o: ../../../Common/MyMap.cpp
$(CXX) $(CXXFLAGS) $<
$O/MyString.o: ../../../Common/MyString.cpp
@@ -1095,6 +1099,7 @@ $O/XzCrc64.o: ../../../../C/XzCrc64.c
ifdef USE_ASM
ifdef IS_X64
USE_X86_ASM=1
USE_X64_ASM=1
else
ifdef IS_X86
USE_X86_ASM=1
@@ -1126,6 +1131,13 @@ $O/AesOpt.o: ../../../../C/AesOpt.c
$(CC) $(CFLAGS) $<
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

View File

@@ -133,7 +133,7 @@ HRESULT CHandler::SetMainMethod(
if (_numSolidBytesDefined)
continue;
UInt32 dicSize;
UInt64 dicSize;
switch (methodFull.Id)
{
case k_LZMA:

View File

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

View File

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

View File

@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /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 RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -270,6 +270,10 @@ SOURCE=..\..\..\Common\CommandLineParser.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Common.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\ComTry.h
# End Source File
# Begin Source File
@@ -306,6 +310,18 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End 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
# End Source File
# Begin Source File
@@ -322,6 +338,10 @@ SOURCE=..\..\..\Common\MyInitGuid.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyLinux.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyString.cpp
# End Source File
# Begin Source File
@@ -330,6 +350,10 @@ SOURCE=..\..\..\Common\MyString.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyUnknown.h
# End Source File
# Begin Source File
@@ -342,6 +366,10 @@ SOURCE=..\..\..\Common\MyVector.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyWindows.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File
# Begin Source File
@@ -478,6 +506,10 @@ SOURCE=..\..\..\Windows\FileLink.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileMapping.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\FileName.cpp
# End Source File
# Begin Source File
@@ -506,6 +538,10 @@ SOURCE=..\..\..\Windows\MemoryLock.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\NtCheck.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\PropVariant.cpp
# End Source File
# Begin Source File
@@ -538,6 +574,10 @@ SOURCE=..\..\..\Windows\Registry.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\SecurityUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File
# Begin Source File
@@ -654,6 +694,10 @@ SOURCE=..\..\Common\MemBlocks.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\MemBlocks.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\MethodId.cpp
# End Source File
# Begin Source File
@@ -769,6 +813,10 @@ SOURCE=..\..\Common\VirtThread.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\BZip2Const.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\BZip2Crc.cpp
# End Source File
# Begin Source File
@@ -909,10 +957,6 @@ SOURCE=..\..\Compress\DeflateEncoder.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\DeflateExtConst.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\DeflateRegister.cpp
# End Source File
# End Group
@@ -1678,6 +1722,10 @@ SOURCE=..\..\UI\Common\DefaultName.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\DirItem.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\EnumDirItems.cpp
# End Source File
# Begin Source File
@@ -1686,6 +1734,10 @@ SOURCE=..\..\UI\Common\EnumDirItems.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\ExitCode.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\Extract.cpp
# End Source File
# Begin Source File
@@ -1702,6 +1754,10 @@ SOURCE=..\..\UI\Common\ExtractingFilePath.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\ExtractMode.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\HashCalc.cpp
# End Source File
# Begin Source File
@@ -1710,6 +1766,10 @@ SOURCE=..\..\UI\Common\HashCalc.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\IFileExtractCallback.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\LoadCodecs.cpp
# End Source File
# Begin Source File
@@ -1726,6 +1786,10 @@ SOURCE=..\..\UI\Common\OpenArchive.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\Property.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\Common\PropIDUtils.cpp
# End Source File
# Begin Source File
@@ -1912,6 +1976,10 @@ SOURCE=..\..\Crypto\RandGen.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\Sha1Cls.h
# End Source File
# Begin Source File
SOURCE=..\..\Crypto\WzAes.cpp
# End Source File
# Begin Source File
@@ -1959,6 +2027,10 @@ SOURCE=..\..\ICoder.h
# End Source File
# Begin Source File
SOURCE=..\..\IDecl.h
# End Source File
# Begin Source File
SOURCE=..\..\IMyUnknown.h
# End Source File
# Begin Source File
@@ -1975,6 +2047,10 @@ SOURCE=..\..\IStream.h
# End Source File
# Begin Source File
SOURCE=..\..\MyVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\PropID.h
# End Source File
# End Group
@@ -2223,6 +2299,10 @@ SOURCE=..\..\..\..\C\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\7zVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Aes.c
!IF "$(CFG)" == "Alone - Win32 Release"
@@ -2440,6 +2520,10 @@ SOURCE=..\..\..\..\C\BwtSort.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Compiler.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\CpuArch.c
!IF "$(CFG)" == "Alone - Win32 Release"
@@ -2593,6 +2677,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End 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
# End Source File
# Begin Source File

View File

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

View File

@@ -110,6 +110,7 @@ COMMON_OBJS = \
$O/CrcReg.o \
$O/IntToString.o \
$O/ListFileUtils.o \
$O/LzFindPrepare.o \
$O/MyString.o \
$O/NewHandler.o \
$O/StdInStream.o \
@@ -283,6 +284,7 @@ C_OBJS = \
$O/Delta.o \
$O/HuffEnc.o \
$O/LzFind.o \
$O/LzFindOpt.o \
$O/Lzma2Dec.o \
$O/Lzma2DecMt.o \
$O/Lzma2Enc.o \

View File

@@ -44,7 +44,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /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 RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -306,6 +306,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\LzFindPrepare.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\MyCom.h
# End Source File
# Begin Source File
@@ -1681,6 +1685,30 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End 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
# End Source File
# Begin Source File

View File

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

View File

@@ -27,6 +27,7 @@ else
MT_OBJS = \
$O/LzFindMt.o \
$O/LzFindOpt.o \
$O/StreamBinder.o \
$O/Synchronization.o \
$O/VirtThread.o \
@@ -110,6 +111,7 @@ COMMON_OBJS = \
$O/CrcReg.o \
$O/IntToString.o \
$O/ListFileUtils.o \
$O/LzFindPrepare.o \
$O/MyString.o \
$O/MyVector.o \
$O/NewHandler.o \

View File

@@ -1016,6 +1016,11 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzFindOpt.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Lzma2Dec.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -1514,6 +1519,10 @@ SOURCE=..\..\..\Common\ListFileUtils.h
# End 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

View File

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

View File

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

View File

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

View File

@@ -267,6 +267,10 @@ SOURCE=..\..\..\Common\IntToString.h
# End 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
@@ -1869,6 +1873,22 @@ SOURCE=..\..\..\..\C\LzFindMt.h
# End 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
# End Source File
# Begin Source File

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -99,41 +99,65 @@ HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 default
}
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;
}
destProp = (UInt32)val32;
return S_OK;
}
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;
UInt32 number = ConvertStringToUInt32(s, &end);
unsigned numDigits = (unsigned)(end - s.Ptr());
const UInt64 number = ConvertStringToUInt64(s, &end);
const unsigned numDigits = (unsigned)(end - s.Ptr());
if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG;
if (s.Len() == numDigits)
{
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;
}
return SetLogSizeProp(number, destProp);
unsigned numBits;
switch (MyCharLower_Ascii(s[numDigits]))
{
case 'b': destProp = number; return S_OK;
case 'b': numBits = 0; break;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
default: return E_INVALIDARG;
}
if (number < ((UInt32)1 << (32 - numBits)))
destProp = (UInt32)(number << numBits);
const UInt64 range4g = ((UInt64)1 << (32 - 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
destProp = (UInt64)((UInt64)number << numBits);
return S_OK;
}
@@ -141,16 +165,8 @@ static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp)
{
if (prop.vt == VT_UI4)
{
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;
}
return SetLogSizeProp(prop.ulVal, destProp);
if (prop.vt == VT_BSTR)
{
UString s;

View File

@@ -64,23 +64,34 @@ public:
unsigned GetLevel() const;
int Get_NumThreads() const
{
int i = FindProp(NCoderPropID::kNumThreads);
const int i = FindProp(NCoderPropID::kNumThreads);
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;
}
bool Get_DicSize(UInt32 &res) const
bool Get_DicSize(UInt64 &res) const
{
res = 0;
int i = FindProp(NCoderPropID::kDictionarySize);
const int i = FindProp(NCoderPropID::kDictionarySize);
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;
}
if (val.vt == VT_UI8)
{
res = val.uhVal.QuadPart;
return true;
}
}
return false;
}
@@ -90,23 +101,26 @@ public:
{
int i = FindProp(NCoderPropID::kAlgorithm);
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;
}
UInt32 Get_Lzma_DicSize() const
UInt64 Get_Lzma_DicSize() const
{
int i = FindProp(NCoderPropID::kDictionarySize);
if (i >= 0)
if (Props[(unsigned)i].Value.vt == VT_UI4)
return Props[(unsigned)i].Value.ulVal;
unsigned level = GetLevel();
return
( level <= 3 ? (1 << (level * 2 + 16)) :
( level <= 6 ? (1 << (level + 19)) :
( level <= 7 ? (1 << 25) : (1 << 26)
UInt64 v;
if (Get_DicSize(v))
return v;
const unsigned level = GetLevel();
const UInt32 dictSize =
( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
( level <= 6 ? ((UInt32)1 << (level + 19)) :
( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
)));
return dictSize;
}
bool Get_Lzma_Eos() const
@@ -152,7 +166,7 @@ public:
UInt64 GetProp_BlockSize(PROPID id) const
{
int i = FindProp(id);
const int i = FindProp(id);
if (i >= 0)
{
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
@@ -176,7 +190,7 @@ public:
}
const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28;
UInt32 dictSize = Get_Lzma_DicSize();
const UInt64 dictSize = Get_Lzma_DicSize();
UInt64 blockSize = (UInt64)dictSize << 2;
if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize;
@@ -204,29 +218,38 @@ public:
UInt32 Get_BZip2_BlockSize() const
{
int i = FindProp(NCoderPropID::kDictionarySize);
const int i = FindProp(NCoderPropID::kDictionarySize);
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 kDicSizeMax = 900000;
if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
return blockSize;
}
unsigned level = GetLevel();
}
const unsigned level = GetLevel();
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 (Props[(unsigned)i].Value.vt == VT_UI4)
return Props[(unsigned)i].Value.ulVal;
unsigned level = GetLevel();
return ((UInt32)1 << (level + 19));
{
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
if (val.vt == VT_UI4)
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)

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)
{
UInt64 absoluteNewPosition;
if (seekOrigin == STREAM_SEEK_SET)
{
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
offset += _offset;
}
UInt64 absoluteNewPosition = 0; // =0 for gcc-10
HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
if (newPosition)
*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(_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()
_canWrite_Semaphore.Create(0, 3);
_canWrite_Semaphore.OptCreateInit(0, 3);
// _readingWasClosed = false;
_readingWasClosed2 = false;

View File

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

View File

@@ -44,7 +44,9 @@ static const Byte kNoLenStatPrice = 11;
static const Byte kNoPosStatPrice = 6;
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
{
@@ -60,7 +62,7 @@ public:
g_LenSlots[c] = (Byte)i;
}
const unsigned kFastSlots = 18;
const unsigned kFastSlots = kNumLogBits * 2;
unsigned c = 0;
for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
{
@@ -73,14 +75,24 @@ public:
static CFastPosInit g_FastPosInit;
inline UInt32 GetPosSlot(UInt32 pos)
{
/*
if (pos < 0x200)
return g_FastPos[pos];
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()
{
int level = Level;
@@ -253,13 +265,13 @@ NO_INLINE void CCoder::GetMatches()
UInt32 distanceTmp[kMatchMaxLen * 2 + 3];
UInt32 numPairs = (_btMode) ?
const UInt32 numPairs = (UInt32)((_btMode ?
Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp):
Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp);
Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp)) - distanceTmp);
*m_MatchDistances = (UInt16)numPairs;
if (numPairs > 0)
if (numPairs != 0)
{
UInt32 i;
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;
}
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)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
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(kNumFastBytes, fb)
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++)
{
const PROPVARIANT &prop = coderProps[i];
PROPID propID = propIDs[i];
const PROPID propID = propIDs[i];
if (propID > NCoderPropID::kReduceSize)
continue;
if (propID == NCoderPropID::kReduceSize)
@@ -68,16 +68,50 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIA
props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
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)
return E_INVALIDARG;
UInt32 v = (UInt32)prop.ulVal;
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:
if (v < 2 || v > 32)
return E_INVALIDARG;

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

@@ -1405,11 +1405,13 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
options.NumIterations = 1;
options.NumIterations_Defined = false;
if (curCommandIndex < numNonSwitchStrings)
{
if (!StringToUInt32(nonSwitchStrings[curCommandIndex], options.NumIterations))
throw CArcCmdLineException("Incorrect number of benchmark iterations", nonSwitchStrings[curCommandIndex]);
curCommandIndex++;
options.NumIterations_Defined = true;
}
}
else if (options.Command.CommandType == NCommandType::kHash)

View File

@@ -109,6 +109,7 @@ struct CArcCmdLineOptions
// Benchmark
UInt32 NumIterations;
bool NumIterations_Defined;
CArcCmdLineOptions():
HelpMode(false),

View File

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,8 @@
#include "../../Common/CreateCoder.h"
#include "../../UI/Common/Property.h"
UInt64 Benchmark_GetUsage_Percents(UInt64 usage);
struct CBenchInfo
{
UInt64 GlobalTime;
@@ -17,26 +19,71 @@ struct CBenchInfo
UInt64 UnpackSize;
UInt64 PackSize;
UInt64 NumIterations;
/*
during Code(): we track benchInfo only from one thread (theads with index[0])
NumIterations means number of threads
UnpackSize and PackSize are total sizes of all iterations of current thread
after Code():
NumIterations means the number of Iterations
UnpackSize and PackSize are total sizes of all threads
*/
CBenchInfo(): NumIterations(0) {}
UInt64 GetUsage() const;
UInt64 GetRatingPerUsage(UInt64 rating) const;
UInt64 GetSpeed(UInt64 numCommands) const;
UInt64 GetSpeed(UInt64 numUnits) const;
UInt64 GetUnpackSizeSpeed() const { return GetSpeed(UnpackSize * NumIterations); }
UInt64 Get_UnpackSize_Full() const { return UnpackSize * NumIterations; }
UInt64 GetRating_LzmaEnc(UInt64 dictSize) const;
UInt64 GetRating_LzmaDec() const;
};
struct CTotalBenchRes
{
// UInt64 NumIterations1; // for Usage
UInt64 NumIterations2; // for Rating / RPU
UInt64 Rating;
UInt64 Usage;
UInt64 RPU;
UInt64 Speed;
void Init() { /* NumIterations1 = 0; */ NumIterations2 = 0; Rating = 0; Usage = 0; RPU = 0; Speed = 0; }
void SetSum(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
{
Rating = (r1.Rating + r2.Rating);
Usage = (r1.Usage + r2.Usage);
RPU = (r1.RPU + r2.RPU);
Speed = (r1.Speed + r2.Speed);
// NumIterations1 = (r1.NumIterations1 + r2.NumIterations1);
NumIterations2 = (r1.NumIterations2 + r2.NumIterations2);
}
void Generate_From_BenchInfo(const CBenchInfo &info);
void Mult_For_Weight(unsigned weight);
void Update_With_Res(const CTotalBenchRes &r);
};
struct IBenchCallback
{
virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0;
// virtual HRESULT SetFreq(bool showFreq, UInt64 cpuFreq) = 0;
virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;
virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
};
UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt64 numIterations);
const unsigned kBenchMinDicLogSize = 18;
UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary, bool totalBench = false);
UInt64 GetBenchMemoryUsage(UInt32 numThreads, int level, UInt64 dictionary, bool totalBench);
struct IBenchPrintCallback
{
@@ -45,22 +92,20 @@ struct IBenchPrintCallback
virtual HRESULT CheckBreak() = 0;
};
/*
struct IBenchFreqCallback
{
virtual void AddCpuFreq(UInt64 freq) = 0;
virtual HRESULT AddCpuFreq(unsigned numThreads, UInt64 freq, UInt64 usage) = 0;
virtual HRESULT FreqsFinished(unsigned numThreads) = 0;
};
*/
HRESULT Bench(
DECL_EXTERNAL_CODECS_LOC_VARS
IBenchPrintCallback *printCallback,
IBenchCallback *benchCallback,
// IBenchFreqCallback *freqCallback,
const CObjectVector<CProperty> &props,
UInt32 numIterations,
bool multiDict
);
bool multiDict,
IBenchFreqCallback *freqCallback = NULL);
AString GetProcessThreadsInfo(const NWindows::NSystem::CProcessAffinity &ti);

View File

@@ -272,7 +272,11 @@ void Benchmark(bool totalMode)
prop.Value = "*";
props.Add(prop);
}
result = Benchmark(EXTERNAL_CODECS_VARS_L props, g_HWND);
result = Benchmark(
EXTERNAL_CODECS_VARS_L
props,
k_NumBenchIterations_Default,
g_HWND);
MY_TRY_FINISH
}

View File

@@ -128,7 +128,7 @@ static const char * const kHelpString =
#ifndef _NO_CRYPTO
" -p{Password} : set Password\n"
#endif
" -r[-|0] : Recurse subdirectories\n"
" -r[-|0] : Recurse subdirectories for name search\n"
" -sa{a|e|s} : set Archive name mode\n"
" -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n"
" -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n"
@@ -200,63 +200,55 @@ static void ShowProgInfo(CStdOutStream *so)
#endif
*/
#ifdef __VERSION__
<< " compiler: " << __VERSION__
#endif
#ifdef __GNUC__
<< " GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__
#endif
#ifdef __clang__
<< " CLANG " << __clang_major__ << "." << __clang_minor__
#endif
#ifdef __xlC__
<< " XLC " << (__xlC__ >> 8) << "." << (__xlC__ & 0xFF)
#ifdef __xlC_ver__
<< "." << (__xlC_ver__ >> 8) << "." << (__xlC_ver__ & 0xFF)
#endif
#endif
#ifdef _MSC_VER
<< " MSC " << _MSC_VER
#endif
#ifdef __ARM_FEATURE_CRC32
<< " CRC32"
#endif
<< " " << (unsigned)(sizeof(void *)) * 8 << "-bit"
#ifdef __ILP32__
<< " ILP32"
#endif
#ifdef __ARM_ARCH
<< " arm_v:" << __ARM_ARCH
#ifdef __ARM_ARCH_ISA_THUMB
<< " thumb:" << __ARM_ARCH_ISA_THUMB
#endif
#endif
;
#ifdef ENV_HAVE_LOCALE
<< " locale=" << GetLocale()
*so << " locale=" << GetLocale();
#endif
#ifndef _WIN32
<< " UTF8=" << (IsNativeUTF8() ? "+" : "-")
<< " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-")
<< " wchar_t=" << (unsigned)(sizeof(wchar_t)) * 8 << "-bit"
<< " Files=" << (unsigned)(sizeof(off_t)) * 8 << "-bit"
{
const bool is_IsNativeUTF8 = IsNativeUTF8();
if (!is_IsNativeUTF8)
*so << " UTF8=" << (is_IsNativeUTF8 ? "+" : "-");
}
if (!g_ForceToUTF8)
*so << " use-UTF8=" << (g_ForceToUTF8 ? "+" : "-");
{
const unsigned wchar_t_size = (unsigned)sizeof(wchar_t);
if (wchar_t_size != 4)
*so << " wchar_t=" << wchar_t_size * 8 << "-bit";
}
{
const unsigned off_t_size = (unsigned)sizeof(off_t);
if (off_t_size != 8)
*so << " Files=" << off_t_size * 8 << "-bit";
}
#endif
;
{
const UInt32 numCpus = NWindows::NSystem::GetNumberOfProcessors();
*so << " Threads:" << numCpus;
}
#ifdef _7ZIP_ASM
*so << ", ASM";
#endif
/*
{
AString s;
GetCpuName(s);
@@ -264,9 +256,10 @@ static void ShowProgInfo(CStdOutStream *so)
*so << ", " << s;
}
#ifdef _7ZIP_ASM
*so << ",ASM";
#ifdef __ARM_FEATURE_CRC32
<< " CRC32"
#endif
#if (defined MY_CPU_X86_OR_AMD64 || defined(MY_CPU_ARM_OR_ARM64))
if (CPU_IsSupported_AES()) *so << ",AES";
@@ -281,6 +274,7 @@ static void ShowProgInfo(CStdOutStream *so)
if (CPU_IsSupported_SHA2()) *so << ",SHA2";
#endif
#endif
*/
*so << endl;
}

View File

@@ -19,7 +19,7 @@ static const UInt32 kLangIDs[] =
IDT_ABOUT_INFO
};
#define kHomePageURL TEXT("http://www.7-zip.org/")
#define kHomePageURL TEXT("https://www.7-zip.org/")
#define kHelpTopic "start.htm"
#define LLL_(quote) L##quote

View File

@@ -136,8 +136,11 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
case kCloseMessage:
{
KillTimer(_timer);
_timer = 0;
if (_timer)
{
KillTimer(kTimerID);
_timer = 0;
}
if (_inCancelMessageBox)
{
_externalCloseMessageWasReceived = true;

View File

@@ -348,7 +348,9 @@ bool CProgressDialog::OnInit()
INIT_AS_UNDEFINED(_processed_Prev);
INIT_AS_UNDEFINED(_packed_Prev);
INIT_AS_UNDEFINED(_ratio_Prev);
_filesStr_Prev.Empty();
_filesTotStr_Prev.Empty();
_foreground = true;
@@ -423,13 +425,14 @@ static const UINT kIDs[] =
IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL,
IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL,
IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL,
IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL,
0, IDT_PROGRESS_FILES_TOTAL,
IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL,
IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL,
IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL,
IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL,
IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL
IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL,
IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL
};
bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
@@ -546,6 +549,7 @@ bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
yPos = my;
x = mx + gSize + padSize;
}
if (kIDs[i] != 0)
MoveItem(kIDs[i], x, yPos, labelSize, sY);
MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY);
yPos += sStep;
@@ -617,6 +621,7 @@ static void ConvertSizeToString(UInt64 v, wchar_t *s)
s += MyStringLen(s);
*s++ = ' ';
*s++ = c;
*s++ = 'B';
*s++ = 0;
}
}
@@ -829,17 +834,25 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
{
wchar_t s[64];
ConvertUInt64ToString(completedFiles, s);
if (IS_DEFINED_VAL(totalFiles))
{
MyStringCat(s, L" / ");
ConvertUInt64ToString(totalFiles, s + MyStringLen(s));
}
if (_filesStr_Prev != s)
{
_filesStr_Prev = s;
SetItemText(IDT_PROGRESS_FILES_VAL, s);
}
s[0] = 0;
if (IS_DEFINED_VAL(totalFiles))
{
MyStringCopy(s, L" / ");
ConvertUInt64ToString(totalFiles, s + MyStringLen(s));
}
if (_filesTotStr_Prev != s)
{
_filesTotStr_Prev = s;
SetItemText(IDT_PROGRESS_FILES_TOTAL, s);
}
}
const UInt64 packSize = CompressingMode ? outSize : inSize;
@@ -1024,8 +1037,13 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
case kCloseMessage:
{
KillTimer(_timer);
_timer = 0;
if (_timer)
{
/* 21.03 : KillTimer(kTimerID) instead of KillTimer(_timer).
But (_timer == kTimerID) in Win10. So it worked too */
KillTimer(kTimerID);
_timer = 0;
}
if (_inCancelMessageBox)
{
_externalCloseMessageWasReceived = true;

View File

@@ -169,7 +169,9 @@ class CProgressDialog: public NWindows::NControl::CModalDialog
UInt64 _processed_Prev;
UInt64 _packed_Prev;
UInt64 _ratio_Prev;
UString _filesStr_Prev;
UString _filesTotStr_Prev;
unsigned _prevSpeed_MoveBits;
UInt64 _prevSpeed;

View File

@@ -28,6 +28,7 @@
#define IDT_PROGRESS_PACKED_VAL 110
#define IDT_PROGRESS_FILES_VAL 111
#define IDT_PROGRESS_FILES_TOTAL 112
#define IDT_PROGRESS_ELAPSED_VAL 120
#define IDT_PROGRESS_REMAINING_VAL 121
@@ -41,7 +42,7 @@
#ifdef UNDER_CE
#define MY_PROGRESS_VAL_UNITS 44
#else
#define MY_PROGRESS_VAL_UNITS 76
#define MY_PROGRESS_VAL_UNITS 72
#endif
#define MY_PROGRESS_LABEL_UNITS_MIN 60
#define MY_PROGRESS_LABEL_UNITS_START 90

View File

@@ -47,27 +47,32 @@ CAPTION "Progress"
PUSHBUTTON "&Pause", IDB_PAUSE, bx2, by, bxs, bys
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, m, y0, x0s, 8
LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, m, y1, x0s, 8
LTEXT "Files:", IDT_PROGRESS_FILES, m, y2, x0s, 8
LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, m, y3, x0s, 8
LTEXT "Errors:", IDT_PROGRESS_ERRORS, m, y4, x0s, 8
LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2s, 8
LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2s, 8
LTEXT "Processed:", IDT_PROGRESS_PROCESSED,x2, y2, x2s, 8
LTEXT "Compressed size:" , IDT_PROGRESS_PACKED, x2, y3, x2s, 8
LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, x2, y4, x2s, 8
RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_RATIO_VAL, x1, y3, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_FILES_TOTAL x1, y3, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3s, MY_TEXT_NOPREFIX
RTEXT "", IDT_PROGRESS_RATIO_VAL, x3, y4, x3s, MY_TEXT_NOPREFIX
LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX
CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s

View File

File diff suppressed because it is too large Load Diff

View File

@@ -3,190 +3,13 @@
#ifndef __BENCHMARK_DIALOG_H
#define __BENCHMARK_DIALOG_H
#include "../../../Windows/Synchronization.h"
#include "../../Common/CreateCoder.h"
#include "../../UI/Common/Property.h"
#include "../../../Windows/Control/ComboBox.h"
#include "../../../Windows/Control/Edit.h"
#include "../Common/Bench.h"
#include "../FileManager/DialogSize.h"
#include "BenchmarkDialogRes.h"
struct CBenchInfo2 : public CBenchInfo
{
void Init() { GlobalTime = UserTime = 0; }
UInt64 GetCompressRating(UInt32 dictSize) const
{
return ::GetCompressRating(dictSize, GlobalTime, GlobalFreq, UnpackSize * NumIterations);
}
UInt64 GetDecompressRating() const
{
return ::GetDecompressRating(GlobalTime, GlobalFreq, UnpackSize, PackSize, NumIterations);
}
};
class CBenchProgressSync
{
public:
bool Stopped;
bool Paused;
bool Changed;
UInt32 DictionarySize;
UInt32 NumThreads;
UInt64 NumPasses;
NWindows::NSynchronization::CManualResetEvent _startEvent;
NWindows::NSynchronization::CCriticalSection CS;
CBenchInfo2 CompressingInfoTemp;
CBenchInfo2 CompressingInfo;
UInt64 ProcessedSize;
CBenchInfo2 DecompressingInfoTemp;
CBenchInfo2 DecompressingInfo;
AString Text;
bool TextWasChanged;
// bool FirstPath;
// UInt64 Freq;
// UString Freq;
// bool FreqWasChanged;
CBenchProgressSync()
{
if (_startEvent.Create() != S_OK)
throw 3986437;
}
void Init()
{
Changed = false;
Stopped = false;
Paused = false;
CompressingInfoTemp.Init();
CompressingInfo.Init();
ProcessedSize = 0;
DecompressingInfoTemp.Init();
DecompressingInfo.Init();
NumPasses = 0;
// FirstPath = true;
// Freq = 0;
// Freq.SetFromAscii("MHz: ");
// FreqWasChanged = true;
Text.Empty();
TextWasChanged = true;
}
void Stop()
{
NWindows::NSynchronization::CCriticalSectionLock lock(CS);
Stopped = true;
}
bool WasStopped()
{
NWindows::NSynchronization::CCriticalSectionLock lock(CS);
return Stopped;
}
void Pause()
{
NWindows::NSynchronization::CCriticalSectionLock lock(CS);
Paused = true;
}
void Start()
{
NWindows::NSynchronization::CCriticalSectionLock lock(CS);
Paused = false;
}
bool WasPaused()
{
NWindows::NSynchronization::CCriticalSectionLock lock(CS);
return Paused;
}
void WaitCreating() { _startEvent.Lock(); }
};
struct CMyFont
{
HFONT _font;
CMyFont(): _font(NULL) {}
~CMyFont()
{
if (_font)
DeleteObject(_font);
}
void Create(const LOGFONT *lplf)
{
_font = CreateFontIndirect(lplf);
}
};
class CBenchmarkDialog:
public NWindows::NControl::CModalDialog
{
NWindows::NControl::CComboBox m_Dictionary;
NWindows::NControl::CComboBox m_NumThreads;
NWindows::NControl::CEdit _consoleEdit;
UINT_PTR _timer;
UInt32 _startTime;
CMyFont _font;
UInt64 ramSize;
bool ramSize_Defined;
bool OnSize(WPARAM /* wParam */, int xSize, int ySize);
bool OnTimer(WPARAM timerID, LPARAM callback);
virtual bool OnInit();
void OnRestartButton();
void OnStopButton();
void OnHelp();
virtual void OnCancel();
bool OnButtonClicked(int buttonID, HWND buttonHWND);
bool OnCommand(int code, int itemID, LPARAM lParam);
void PrintTime();
void PrintRating(UInt64 rating, UINT controlID);
void PrintUsage(UInt64 usage, UINT controlID);
void PrintResults(
UInt32 dictionarySize,
const CBenchInfo2 &info, UINT usageID, UINT speedID, UINT rpuID, UINT ratingID,
bool decompressMode = false);
UInt32 GetNumberOfThreads();
UInt32 OnChangeDictionary();
void OnChangeSettings();
void SetItemText_Number(int itemID, UInt64 val, LPCTSTR post = NULL);
public:
CBenchProgressSync Sync;
bool TotalMode;
CObjectVector<CProperty> Props;
CSysString Bench2Text;
CBenchmarkDialog(): _timer(0), TotalMode(false) {}
INT_PTR Create(HWND wndParent = 0)
{
BIG_DIALOG_SIZE(332, 228);
return CModalDialog::Create(TotalMode ? IDD_BENCH_TOTAL : SIZED_DIALOG(IDD_BENCH), wndParent);
}
void MessageBoxError(LPCWSTR message)
{
MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR);
}
};
const UInt32 k_NumBenchIterations_Default = 10;
HRESULT Benchmark(
DECL_EXTERNAL_CODECS_LOC_VARS
const CObjectVector<CProperty> &props, HWND hwndParent = NULL);
const CObjectVector<CProperty> &props, UInt32 numIterations, HWND hwndParent = NULL);
#endif

View File

@@ -23,25 +23,29 @@
#define g4x (m + m)
#define sRating 60
#define sSpeed 60
#define sUsage 60
#define sRpu 60
#define sFreq 34
#define sRating 58
#define sSpeed 60
#define sUsage 46
#define sRpu 58
#define sSize 52
// #define sFreq 34
#define xRating (xs - m - m - sRating)
#define xRpu (xRating - sRpu)
#define xUsage (xRpu - sUsage)
#define xSpeed (xUsage - sSpeed)
#define xSize (xSpeed - sSize)
#define xFreq (xUsage - sFreq)
// #define xFreq (xUsage - sFreq)
#define sLabel (xUsage - g4x)
#define sLabel (xSize - g4x)
#define sTotalRating (sUsage + sRpu + sRating + m + m)
#define xTotalRating (xs - m - sTotalRating)
#define g2xs 58
#define g3xs 36
#define sPasses 60
#define g2xs 60
#define g3xs 64
#define g3x (m + g2xs)
#undef GROUP_Y_SIZE
@@ -56,7 +60,10 @@
#define g7xs bx1 - m - g0xs - g1xs - m
IDD_BENCH DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
#define sLog 140 + 0
// MY_MODAL_DIALOG_STYLE
IDD_BENCH DIALOG 0, 0, xs + sLog, ys MY_MODAL_RESIZE_DIALOG_STYLE | WS_MINIMIZEBOX
CAPTION "Benchmark"
MY_FONT
BEGIN
@@ -70,71 +77,79 @@ BEGIN
COMBOBOX IDC_BENCH_DICTIONARY, g1x, m, g1xs, 140, MY_COMBO
LTEXT "Memory usage:", IDT_BENCH_MEMORY, gc2x, m - 2, g7xs, 8
LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x, m + 8, g7xs, 8
LTEXT "", IDT_BENCH_MEMORY_VAL, gc2x, m + 8, g7xs, MY_TEXT_NOPREFIX
LTEXT "&Number of CPU threads:", IDT_BENCH_NUM_THREADS, m, 30, g0xs, 8
COMBOBOX IDC_BENCH_NUM_THREADS, g1x, 29, g1xs, 140, MY_COMBO
LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 32, g7xs, 8
LTEXT "", IDT_BENCH_HARDWARE_THREADS, gc2x, 30, g7xs, MY_TEXT_NOPREFIX
RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, 8
RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, 8
RTEXT "Rating / Usage", IDT_BENCH_RPU_LABEL, xRpu, 54, sRpu, 8
RTEXT "Rating", IDT_BENCH_RATING_LABEL, xRating, 54, sRating, 8
RTEXT "Size", IDT_BENCH_SIZE, xSize, 54, sSize, MY_TEXT_NOPREFIX
RTEXT "CPU Usage", IDT_BENCH_USAGE_LABEL, xUsage, 54, sUsage, MY_TEXT_NOPREFIX
RTEXT "Speed", IDT_BENCH_SPEED, xSpeed, 54, sSpeed, MY_TEXT_NOPREFIX
RTEXT "Rating / Usage", IDT_BENCH_RPU_LABEL, xRpu, 54, sRpu, MY_TEXT_NOPREFIX
RTEXT "Rating", IDT_BENCH_RATING_LABEL, xRating, 54, sRating, MY_TEXT_NOPREFIX
GROUPBOX "Compressing", IDG_BENCH_COMPRESSING, m, 64, xc, GROUP_Y_SIZE
LTEXT "Current", IDT_BENCH_CURRENT, g4x, 76, sLabel, 8
RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 76, sUsage, 8
RTEXT "", IDT_BENCH_COMPRESS_SPEED1, xSpeed, 76, sSpeed, 8
RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 76, sRpu, 8
RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 76, sRating, 8
LTEXT "Current", IDT_BENCH_CURRENT, g4x, 76, sLabel, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_SIZE1, xSize, 76, sSize, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_USAGE1, xUsage, 76, sUsage, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_SPEED1, xSpeed, 76, sSpeed, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_RPU1, xRpu, 76, sRpu, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_RATING1, xRating, 76, sRating, MY_TEXT_NOPREFIX
LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 89, sLabel, 8
RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 89, sUsage, 8
RTEXT "", IDT_BENCH_COMPRESS_SPEED2, xSpeed, 89, sSpeed, 8
RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 89, sRpu, 8
RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 89, sRating, 8
LTEXT "Resulting", IDT_BENCH_RESULTING, g4x, 89, sLabel, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_SIZE2, xSize, 89, sSize, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_USAGE2, xUsage, 89, sUsage, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_SPEED2, xSpeed, 89, sSpeed, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_RPU2, xRpu, 89, sRpu, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_COMPRESS_RATING2, xRating, 89, sRating, MY_TEXT_NOPREFIX
GROUPBOX "Decompressing", IDG_BENCH_DECOMPRESSING, m, 111, xc, GROUP_Y_SIZE
LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 123, sLabel, 8
RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 123, sUsage, 8
RTEXT "", IDT_BENCH_DECOMPR_SPEED1, xSpeed, 123, sSpeed, 8
RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 123, sRpu, 8
RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 123, sRating, 8
LTEXT "Current", IDT_BENCH_CURRENT2, g4x, 123, sLabel, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_SIZE1, xSize, 123, sSize, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_USAGE1, xUsage, 123, sUsage, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_SPEED1, xSpeed, 123, sSpeed, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_RPU1, xRpu, 123, sRpu, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_RATING1, xRating, 123, sRating, MY_TEXT_NOPREFIX
LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 136, sLabel, 8
RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 136, sUsage, 8
RTEXT "", IDT_BENCH_DECOMPR_SPEED2, xSpeed, 136, sSpeed, 8
RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 136, sRpu, 8
RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 136, sRating, 8
LTEXT "Resulting", IDT_BENCH_RESULTING2, g4x, 136, sLabel, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_SIZE2, xSize, 136, sSize, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_USAGE2, xUsage, 136, sUsage, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_SPEED2, xSpeed, 136, sSpeed, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_RPU2, xRpu, 136, sRpu, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_DECOMPR_RATING2, xRating, 136, sRating, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_ERROR_MESSAGE, m, 155, xc, MY_TEXT_NOPREFIX
GROUPBOX "Total Rating", IDG_BENCH_TOTAL_RATING, xTotalRating, 163, sTotalRating, GROUP_Y2_SIZE
RTEXT "", IDT_BENCH_TOTAL_USAGE_VAL, xUsage, 176, sUsage, 8
RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 176, sRpu, 8
RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, 8
RTEXT "", IDT_BENCH_TOTAL_USAGE_VAL, xUsage, 176, sUsage, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_TOTAL_RPU_VAL, xRpu, 176, sRpu, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_TOTAL_RATING_VAL, xRating, 176, sRating, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_CPU, m, 202, xc, 8
RTEXT "", IDT_BENCH_VER, m + xc - 100, 216, 100, 8
// RTEXT "", IDT_BENCH_CPU, m + sPasses, 202, xc - sPasses, 16, SS_NOPREFIX
RTEXT "", IDT_BENCH_CPU, m + 0, 202, xc - 0, 16, SS_NOPREFIX
RTEXT "", IDT_BENCH_VER, m + xc - 100, 222, 100, MY_TEXT_NOPREFIX
LTEXT "", IDT_BENCH_CPU_FEATURE, m, 228, xc - 100, 8
LTEXT "", IDT_BENCH_SYS1, m, 238, xc - 140, 8
LTEXT "", IDT_BENCH_SYS2, m, 248, xc - 140, 8
// LTEXT "", IDT_BENCH_SYSTEM, m, 232, xc - 80, 8
// LTEXT "", IDT_BENCH_FREQ_RES, m, 242, 80, 8
LTEXT "", IDT_BENCH_CPU_FEATURE, m, 222, xc - 100, 16, SS_NOPREFIX // - 100
LTEXT "", IDT_BENCH_SYS1, m, 238, xc - 140, MY_TEXT_NOPREFIX
LTEXT "", IDT_BENCH_SYS2, m, 248, xc - 140, MY_TEXT_NOPREFIX
LTEXT "", IDT_BENCH_LOG, m + xc + m, m, sLog - m, yc, SS_LEFTNOWORDWRAP | SS_NOPREFIX
LTEXT "Elapsed time:", IDT_BENCH_ELAPSED, m, 163, g2xs, 8
LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8
LTEXT "Passes:", IDT_BENCH_PASSES, m, 189, g2xs, 8
// LTEXT "Size:", IDT_BENCH_SIZE, m, 176, g2xs, 8
LTEXT "Passes:", IDT_BENCH_PASSES, m, 176, g2xs, 8
COMBOBOX IDC_BENCH_NUM_PASSES, m, 187, sPasses, 140, MY_COMBO
RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 163, g3xs, MY_TEXT_NOPREFIX
// RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 176, g3xs, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 176, g3xs, MY_TEXT_NOPREFIX
RTEXT "", IDT_BENCH_ELAPSED_VAL, g3x, 163, g3xs, 8
RTEXT "", IDT_BENCH_SIZE_VAL, g3x, 176, g3xs, 8
RTEXT "", IDT_BENCH_PASSES_VAL, g3x, 189, g3xs, 8
END
#ifdef UNDER_CE

View File

@@ -38,9 +38,17 @@
#define IDT_BENCH_TOTAL_USAGE_VAL 133
#define IDT_BENCH_ELAPSED_VAL 140
#define IDT_BENCH_SIZE_VAL 141
// #define IDT_BENCH_SIZE_VAL 141
#define IDT_BENCH_PASSES_VAL 142
#define IDC_BENCH_NUM_PASSES 143
#define IDT_BENCH_LOG 160
#define IDT_BENCH_ERROR_MESSAGE 161
#define IDT_BENCH_COMPRESS_SIZE1 170
#define IDT_BENCH_COMPRESS_SIZE2 171
#define IDT_BENCH_DECOMPR_SIZE1 172
#define IDT_BENCH_DECOMPR_SIZE2 173
// #define IDT_BENCH_FREQ_CUR 150
// #define IDT_BENCH_FREQ_RES 151

View File

@@ -83,6 +83,8 @@ static const unsigned kHistorySize = 20;
static const UInt32 kNoSolidBlockSize = 0;
static const UInt32 kSolidBlockSize = 64;
static const UInt32 kLzmaMaxDictSize = (UInt32)15 << 28;
static LPCSTR const kExeExt = ".exe";
#define k7zFormat "7z"
@@ -254,18 +256,20 @@ static bool IsMethodSupportedBySfx(int methodID)
return false;
}
static bool GetMaxRamSizeForProgram(UInt64 &physSize)
static bool GetMaxRamSizeForProgram(UInt64 &ramSize, UInt64 &size)
{
physSize = (UInt64)(sizeof(size_t)) << 29;
bool ramSize_Defined = NSystem::GetRamSize(physSize);
size = (UInt64)(sizeof(size_t)) << 29;
bool ramSize_Defined = NSystem::GetRamSize(size);
ramSize = size;
size = size / 16 * 15;
const UInt64 kMinSysSize = (1 << 24);
if (physSize <= kMinSysSize)
physSize = 0;
if (size <= kMinSysSize)
size = 0;
else
physSize -= kMinSysSize;
size -= kMinSysSize;
const UInt64 kMinUseSize = (1 << 24);
if (physSize < kMinUseSize)
physSize = kMinUseSize;
if (size < kMinUseSize)
size = kMinUseSize;
return ramSize_Defined;
}
@@ -411,7 +415,7 @@ bool CCompressDialog::OnInit()
SetSolidBlockSize();
SetNumThreads();
TCHAR s[40] = { TEXT('/'), TEXT(' '), 0 };
TCHAR s[32] = { TEXT('/'), TEXT(' '), 0 };
ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2);
SetItemText(IDT_COMPRESS_HARDWARE_THREADS, s);
@@ -687,6 +691,48 @@ static bool IsAsciiString(const UString &s)
return true;
}
static void AddSize_MB(UString &s, UInt64 size)
{
char temp[32];
ConvertUInt64ToString((size + (1 << 20) - 1) >> 20, temp);
s += temp;
s += " MB";
}
void SetErrorMessage_MemUsage(UString &s, UInt64 reqSize, UInt64 ramSize, UInt64 ramLimit, const UString &usageString)
{
s += "The operation was blocked by 7-Zip";
s.Add_LF();
s += "The operation can require big amount of RAM (memory):";
s.Add_LF();
s.Add_LF();
AddSize_MB(s, reqSize);
if (!usageString.IsEmpty())
{
s += " : ";
s += usageString;
}
s.Add_LF();
AddSize_MB(s, ramSize);
s += " : RAM";
if (ramLimit != 0)
{
s.Add_LF();
AddSize_MB(s, ramLimit);
s += " : 7-Zip limit";
}
s.Add_LF();
s.Add_LF();
s += LangString(IDS_MEM_ERROR);
}
void CCompressDialog::OnOK()
{
_password1Control.GetText(Info.Password);
@@ -718,6 +764,24 @@ void CCompressDialog::OnOK()
}
}
{
UInt64 ramSize;
UInt64 maxRamSize;
const bool maxRamSize_Defined = GetMaxRamSizeForProgram(ramSize, maxRamSize);
UInt64 decompressMem;
const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem);
if (maxRamSize_Defined && memUsage > maxRamSize)
{
UString s;
UString s2 = LangString(IDT_COMPRESS_MEMORY);
if (s2.IsEmpty())
GetItemText(IDT_COMPRESS_MEMORY, s2);
SetErrorMessage_MemUsage(s, memUsage, ramSize, maxRamSize, s2);
MessageBoxError(s);
return;
}
}
SaveOptionsInMem();
{
UString s;
@@ -736,7 +800,7 @@ void CCompressDialog::OnOK()
Info.PathMode = (NWildcard::ECensorPathMode)k_PathMode_Vals[m_PathMode.GetCurSel()];
Info.Level = GetLevelSpec();
Info.Dictionary = GetDictionarySpec();
Info.Dict64 = GetDictSpec();
Info.Order = GetOrderSpec();
Info.OrderMode = GetOrderMode();
Info.NumThreads = GetNumThreadsSpec();
@@ -1207,29 +1271,37 @@ UString CCompressDialog::GetEncryptionMethodSpec()
return s;
}
void CCompressDialog::AddDictionarySize(UInt32 size)
void CCompressDialog::AddDict2(size_t sizeReal, size_t sizeShow)
{
Byte c = 0;
unsigned moveBits = 0;
if ((size & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; }
else if ((size & 0x3FF) == 0) { moveBits = 10; c = 'K'; }
TCHAR s[40];
ConvertUInt32ToString(size >> moveBits, s);
if ((sizeShow & 0xFFFFF) == 0) { moveBits = 20; c = 'M'; }
else if ((sizeShow & 0x3FF) == 0) { moveBits = 10; c = 'K'; }
TCHAR s[32];
ConvertUInt64ToString(sizeShow >> moveBits, s);
unsigned pos = MyStringLen(s);
s[pos++] = ' ';
if (moveBits != 0)
s[pos++] = c;
s[pos++] = 'B';
s[pos++] = 0;
int index = (int)m_Dictionary.AddString(s);
m_Dictionary.SetItemData(index, size);
const int index = (int)m_Dictionary.AddString(s);
m_Dictionary.SetItemData(index, sizeReal);
}
void CCompressDialog::AddDict(size_t size)
{
AddDict2(size, size);
}
void CCompressDialog::SetDictionary()
{
m_Dictionary.ResetContent();
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
int index = FindRegistryFormat(ai.Name);
const int index = FindRegistryFormat(ai.Name);
UInt32 defaultDict = (UInt32)(Int32)-1;
if (index >= 0)
@@ -1239,12 +1311,13 @@ void CCompressDialog::SetDictionary()
defaultDict = fo.Dictionary;
}
int methodID = GetMethodID();
UInt32 level = GetLevel2();
const int methodID = GetMethodID();
const UInt32 level = GetLevel2();
if (methodID < 0)
return;
UInt64 ramSize;
UInt64 maxRamSize;
bool maxRamSize_Defined = GetMaxRamSizeForProgram(maxRamSize);
const bool maxRamSize_Defined = GetMaxRamSizeForProgram(ramSize, maxRamSize);
switch (methodID)
{
@@ -1254,38 +1327,44 @@ void CCompressDialog::SetDictionary()
if (defaultDict == (UInt32)(Int32)-1)
{
defaultDict =
( level <= 3 ? (1 << (level * 2 + 16)) :
( level <= 6 ? (1 << (level + 19)) :
( level <= 7 ? (1 << 25) : (1 << 26)
)));
( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
( level <= 6 ? ((UInt32)1 << (level + 19)) :
( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
)));
}
AddDictionarySize(1 << 16);
AddDictionarySize(1 << 18);
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
for (unsigned i = 20; i <= 31; i++)
for (unsigned j = 0; j < 2; j++)
{
if (i == 20 && j > 0)
continue;
UInt32 dict = ((UInt32)(2 + j) << (i - 1));
if (dict >
#ifdef MY_CPU_64BIT
(3 << 29)
#else
(1 << 26)
#endif
)
continue;
AddDictionarySize(dict);
UInt64 decomprSize;
UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize);
if (dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize))
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
}
// we use threshold 3.75 GiB to switch to kLzmaMaxDictSize.
if (defaultDict >= ((UInt32)15 << 28))
defaultDict = kLzmaMaxDictSize;
const size_t kLzmaMaxDictSize_Up = (size_t)1 << (20 + sizeof(size_t) / 4 * 6);
int curSel = 0;
for (unsigned i = (16 - 1) * 2; i <= (32 - 1) * 2; i++)
{
if (i < (20 - 1) * 2
&& i != (16 - 1) * 2
&& i != (18 - 1) * 2)
continue;
if (i == (20 - 1) * 2 + 1)
continue;
const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2);
size_t dict = dict_up;
if (dict_up >= kLzmaMaxDictSize)
dict = kLzmaMaxDictSize; // we reduce dictionary
AddDict(dict);
// AddDict2(dict, dict_up); // for debug : we show 4 GB
const UInt64 memUsage = GetMemoryUsageComp_Dict(dict);
if (dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize))
curSel = m_Dictionary.GetCount() - 1;
if (dict_up >= kLzmaMaxDictSize_Up)
break;
}
m_Dictionary.SetCurSel(curSel);
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
break;
}
@@ -1293,46 +1372,63 @@ void CCompressDialog::SetDictionary()
case kPPMd:
{
if (defaultDict == (UInt32)(Int32)-1)
{
defaultDict = (UInt32)1 << (level + 19);
}
for (unsigned i = 20; i < 31; i++)
for (unsigned j = 0; j < 2; j++)
{
if (i == 20 && j > 0)
continue;
UInt32 dict = ((UInt32)(2 + j) << (i - 1));
if (dict >
#ifdef MY_CPU_64BIT
(1 << 30)
#else
(1 << 29)
#endif
)
continue;
AddDictionarySize(dict);
UInt64 decomprSize;
UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize);
if ((dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize))
|| m_Dictionary.GetCount() == 1)
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
}
const UInt32 kPpmd_Default_4g = (UInt32)0 - ((UInt32)1 << 10);
const size_t kPpmd_MaxDictSize_Up = (size_t)1 << (29 + sizeof(size_t) / 8);
if (defaultDict >= ((UInt32)15 << 28)) // threshold
defaultDict = kPpmd_Default_4g;
int curSel = 0;
for (unsigned i = (20 - 1) * 2; i <= (32 - 1) * 2; i++)
{
if (i == (20 - 1) * 2 + 1)
continue;
const size_t dict_up = (size_t)(2 + (i & 1)) << (i / 2);
size_t dict = dict_up;
if (dict_up >= kPpmd_Default_4g)
dict = kPpmd_Default_4g;
AddDict2(dict, dict_up);
// AddDict2((UInt32)((UInt32)0 - 2), dict_up); // for debug
// AddDict(dict_up); // for debug
const UInt64 memUsage = GetMemoryUsageComp_Dict(dict);
if (dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize))
curSel = m_Dictionary.GetCount() - 1;
if (dict_up >= kPpmd_MaxDictSize_Up)
break;
}
m_Dictionary.SetCurSel(curSel);
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
break;
}
case kPPMdZip:
{
if (defaultDict == (UInt32)(Int32)-1)
defaultDict = (UInt32)1 << (level + 19);
int curSel = 0;
for (unsigned i = 20; i <= 28; i++)
{
const UInt32 dict = (UInt32)1 << i;
AddDict(dict);
const UInt64 memUsage = GetMemoryUsageComp_Dict(dict);
if ((dict <= defaultDict && (!maxRamSize_Defined || memUsage <= maxRamSize)))
curSel = m_Dictionary.GetCount() - 1;
}
m_Dictionary.SetCurSel(curSel);
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
break;
}
case kDeflate:
{
AddDictionarySize(32 << 10);
m_Dictionary.SetCurSel(0);
break;
}
case kDeflate64:
{
AddDictionarySize(64 << 10);
const UInt32 dict = (methodID == kDeflate ? (UInt32)(1 << 15) : (UInt32)(1 << 16));
AddDict(dict);
m_Dictionary.SetCurSel(0);
break;
}
@@ -1346,39 +1442,22 @@ void CCompressDialog::SetDictionary()
else defaultDict = (100 << 10);
}
int curSel = 0;
for (unsigned i = 1; i <= 9; i++)
{
UInt32 dict = ((UInt32)i * 100) << 10;
AddDictionarySize(dict);
if (dict <= defaultDict || m_Dictionary.GetCount() == 0)
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
const UInt32 dict = ((UInt32)i * 100) << 10;
AddDict(dict);
// AddDict2(i * 100000, dict);
if (i <= defaultDict / 100000)
curSel = m_Dictionary.GetCount() - 1;
}
break;
}
case kPPMdZip:
{
if (defaultDict == (UInt32)(Int32)-1)
defaultDict = (UInt32)1 << (level + 19);
for (unsigned i = 20; i <= 28; i++)
{
UInt32 dict = (1 << i);
AddDictionarySize(dict);
UInt64 decomprSize;
UInt64 requiredComprSize = GetMemoryUsage(dict, decomprSize);
if ((dict <= defaultDict && (!maxRamSize_Defined || requiredComprSize <= maxRamSize))
|| m_Dictionary.GetCount() == 1)
m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1);
}
// SetNearestSelectComboBox(m_Dictionary, defaultDict);
m_Dictionary.SetCurSel(curSel);
break;
}
}
}
UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defMax)
{
if (c.GetCount() <= defMax)
@@ -1386,6 +1465,15 @@ UInt32 CCompressDialog::GetComboValue(NWindows::NControl::CComboBox &c, int defM
return (UInt32)c.GetItemData_of_CurSel();
}
UInt64 CCompressDialog::GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax)
{
if (c.GetCount() <= defMax)
return (UInt64)(Int64)-1;
// LRESULT is signed. so we cast it to unsigned size_t at first:
return (UInt64)(size_t)c.GetItemData_of_CurSel();
}
UInt32 CCompressDialog::GetLevel2()
{
UInt32 level = GetLevel();
@@ -1396,7 +1484,7 @@ UInt32 CCompressDialog::GetLevel2()
int CCompressDialog::AddOrder(UInt32 size)
{
TCHAR s[40];
TCHAR s[32];
ConvertUInt32ToString(size, s);
int index = (int)m_Order.AddString(s);
m_Order.SetItemData(index, size);
@@ -1517,7 +1605,7 @@ bool CCompressDialog::GetOrderMode()
}
static UInt64 Get_Lzma2_ChunkSize(UInt32 dict)
static UInt64 Get_Lzma2_ChunkSize(UInt64 dict)
{
// we use same default chunk sizes as defined in 7z encoder and lzma2 encoder
UInt64 cs = (UInt64)dict << 2;
@@ -1543,8 +1631,8 @@ void CCompressDialog::SetSolidBlockSize(bool useDictionary)
if (level == 0)
return;
UInt32 dict = GetDictionarySpec();
if (dict == (UInt32)(Int32)-1)
UInt64 dict = GetDictSpec();
if (dict == (UInt64)(Int64)-1)
dict = 1;
UInt32 defaultBlockSize = (UInt32)(Int32)-1;
@@ -1603,7 +1691,7 @@ void CCompressDialog::SetSolidBlockSize(bool useDictionary)
if (defaultBlockSize == (UInt32)(Int32)-1 && ((UInt64)1 << i) >= blockSize)
defaultBlockSize = i;
TCHAR s[40];
TCHAR s[32];
char post;
ConvertUInt32ToString(1 << (i % 10), s);
if (i < 20) post = 'K';
@@ -1665,7 +1753,7 @@ void CCompressDialog::SetNumThreads()
numAlgoThreadsMax = 128;
for (UInt32 i = 1; i <= numHardwareThreads * 2 && i <= numAlgoThreadsMax; i++)
{
TCHAR s[40];
TCHAR s[32];
ConvertUInt32ToString(i, s);
int index = (int)m_NumThreads.AddString(s);
m_NumThreads.SetItemData(index, (UInt32)i);
@@ -1673,7 +1761,8 @@ void CCompressDialog::SetNumThreads()
SetNearestSelectComboBox(m_NumThreads, defaultValue);
}
UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
UInt64 CCompressDialog::GetMemoryUsage_Dict_DecompMem(UInt64 dict64, UInt64 &decompressMemory)
{
decompressMemory = UInt64(Int64(-1));
UInt32 level = GetLevel2();
@@ -1706,6 +1795,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
case kLZMA:
case kLZMA2:
{
const UInt32 dict = (dict64 >= kLzmaMaxDictSize ? kLzmaMaxDictSize : (UInt32)dict64);
UInt32 hs = dict - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
@@ -1757,7 +1847,15 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
}
if (chunkSize == 0)
size += numBlockThreads * (size1 + (UInt64)dict * 3 / 2);
{
const UInt32 kBlockSizeMax = (UInt32)0 - (UInt32)(1 << 16);
UInt64 blockSize = (UInt64)dict + (1 << 16)
+ (numThreads1 > 1 ? (1 << 20) : 0);
blockSize += (blockSize >> (blockSize < ((UInt32)1 << 30) ? 1 : 2));
if (blockSize >= kBlockSizeMax)
blockSize = kBlockSizeMax;
size += numBlockThreads * (size1 + blockSize);
}
else
{
size += numBlockThreads * (size1 + chunkSize);
@@ -1771,7 +1869,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
case kPPMd:
{
decompressMemory = dict + (2 << 20);
decompressMemory = dict64 + (2 << 20);
return size + decompressMemory;
}
@@ -1799,7 +1897,7 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
case kPPMdZip:
{
decompressMemory = dict + (2 << 20);
decompressMemory = dict64 + (2 << 20);
return size + (UInt64)decompressMemory * numThreads;
}
}
@@ -1807,9 +1905,15 @@ UInt64 CCompressDialog::GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory)
return (UInt64)(Int64)-1;
}
UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory)
UInt64 CCompressDialog::GetMemoryUsage_DecompMem(UInt64 &decompressMemory)
{
return GetMemoryUsage(GetDictionary(), decompressMemory);
return GetMemoryUsage_Dict_DecompMem(GetDict(), decompressMemory);
}
UInt64 CCompressDialog::GetMemoryUsageComp_Dict(UInt64 dict64)
{
UInt64 decompressMemory;
return GetMemoryUsage_Dict_DecompMem(dict64, decompressMemory);
}
void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
@@ -1819,7 +1923,7 @@ void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
SetItemText(res, TEXT("?"));
return;
}
TCHAR s[40];
TCHAR s[32];
if (value <= ((UInt64)16 << 30))
{
value = (value + (1 << 20) - 1) >> 20;
@@ -1838,7 +1942,7 @@ void CCompressDialog::PrintMemUsage(UINT res, UInt64 value)
void CCompressDialog::SetMemoryUsage()
{
UInt64 decompressMem;
UInt64 memUsage = GetMemoryUsage(decompressMem);
const UInt64 memUsage = GetMemoryUsage_DecompMem(decompressMem);
PrintMemUsage(IDT_COMPRESS_MEMORY_VALUE, memUsage);
PrintMemUsage(IDT_COMPRESS_MEMORY_DE_VALUE, decompressMem);
}
@@ -1847,7 +1951,7 @@ void CCompressDialog::SetParams()
{
const CArcInfoEx &ai = (*ArcFormats)[GetFormatIndex()];
m_Params.SetText(TEXT(""));
int index = FindRegistryFormat(ai.Name);
const int index = FindRegistryFormat(ai.Name);
if (index >= 0)
{
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
@@ -1858,13 +1962,34 @@ void CCompressDialog::SetParams()
void CCompressDialog::SaveOptionsInMem()
{
const CArcInfoEx &ai = (*ArcFormats)[Info.FormatIndex];
int index = FindRegistryFormatAlways(ai.Name);
const int index = FindRegistryFormatAlways(ai.Name);
m_Params.GetText(Info.Options);
Info.Options.Trim();
NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
fo.Options = Info.Options;
fo.Level = GetLevelSpec();
fo.Dictionary = GetDictionarySpec();
{
const UInt64 dict64 = GetDictSpec();
UInt32 dict32;
if (dict64 == (UInt64)(Int64)-1)
dict32 = (UInt32)(Int32)-1;
else
{
dict32 = (UInt32)dict64;
if (dict64 != dict32)
{
/* here we must write 32-bit value for registry that indicates big_value
(UInt32)(Int32)-1 : is used as marker for default size
(UInt32)(Int32)-2 : it can be used to indicate big value (4 GiB)
the value must be larger than threshold
*/
dict32 = (UInt32)(Int32)-2;
// dict32 = kLzmaMaxDictSize; // it must be larger than threshold
}
}
fo.Dictionary = dict32;
}
fo.Order = GetOrderSpec();
fo.Method = GetMethodSpec();
fo.EncryptionMethod = GetEncryptionMethodSpec();

View File

@@ -42,7 +42,7 @@ namespace NCompressDialog
UInt32 Level;
UString Method;
UInt32 Dictionary;
UInt64 Dict64;
bool OrderMode;
UInt32 Order;
UString Options;
@@ -79,7 +79,8 @@ namespace NCompressDialog
DeleteAfterCompressing(false),
FormatIndex(-1)
{
Level = Dictionary = Order = UInt32(-1);
Level = Order = (UInt32)(Int32)-1;
Dict64 = (UInt64)(Int64)(-1);
OrderMode = false;
Method.Empty();
Options.Empty();
@@ -88,6 +89,7 @@ namespace NCompressDialog
};
}
class CCompressDialog: public NWindows::NControl::CModalDialog
{
NWindows::NControl::CComboBox m_ArchivePath;
@@ -142,17 +144,19 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void SetEncryptionMethod();
void AddDictionarySize(UInt32 size);
void AddDict2(size_t sizeReal, size_t sizeShow);
void AddDict(size_t size);
void SetDictionary();
UInt32 GetComboValue(NWindows::NControl::CComboBox &c, int defMax = 0);
UInt64 GetComboValue_64(NWindows::NControl::CComboBox &c, int defMax = 0);
UInt32 GetLevel() { return GetComboValue(m_Level); }
UInt32 GetLevelSpec() { return GetComboValue(m_Level, 1); }
UInt32 GetLevel2();
UInt32 GetDictionary() { return GetComboValue(m_Dictionary); }
UInt32 GetDictionarySpec() { return GetComboValue(m_Dictionary, 1); }
UInt64 GetDict() { return GetComboValue_64(m_Dictionary); }
UInt64 GetDictSpec() { return GetComboValue_64(m_Dictionary, 1); }
UInt32 GetOrder() { return GetComboValue(m_Order); }
UInt32 GetOrderSpec() { return GetComboValue(m_Order, 1); }
UInt32 GetNumThreadsSpec() { return GetComboValue(m_NumThreads, 1); }
@@ -166,8 +170,10 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
void SetSolidBlockSize(bool useDictionary = false);
void SetNumThreads();
UInt64 GetMemoryUsage(UInt32 dict, UInt64 &decompressMemory);
UInt64 GetMemoryUsage(UInt64 &decompressMemory);
UInt64 GetMemoryUsage_Dict_DecompMem(UInt64 dict, UInt64 &decompressMemory);
UInt64 GetMemoryUsage_DecompMem(UInt64 &decompressMemory);
UInt64 GetMemoryUsageComp_Dict(UInt64 dict64);
void PrintMemUsage(UINT res, UInt64 value);
void SetMemoryUsage();
void SetParams();
@@ -196,6 +202,11 @@ public:
CCompressDialog(): CurrentDirWasChanged(false) {};
void MessageBoxError(LPCWSTR message)
{
MessageBoxW(*this, message, L"7-Zip", MB_ICONERROR);
}
protected:
void CheckSFXControlsEnable();

View File

@@ -193,7 +193,12 @@ static int Main2()
if (options.Command.CommandType == NCommandType::kBenchmark)
{
HRESULT res = Benchmark(EXTERNAL_CODECS_VARS_L options.Properties);
HRESULT res = Benchmark(
EXTERNAL_CODECS_VARS_L
options.Properties,
options.NumIterations_Defined ?
options.NumIterations :
k_NumBenchIterations_Default);
/*
if (res == S_FALSE)
{

View File

@@ -1164,6 +1164,10 @@ SOURCE=..\..\..\Windows\SystemInfo.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\Thread.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Windows\TimeUtils.cpp
# End Source File
# Begin Source File

View File

@@ -142,7 +142,7 @@ static void SetOutProperties(
UInt32 level,
bool setMethod,
const UString &method,
UInt32 dictionary,
UInt64 dict64,
bool orderMode,
UInt32 order,
bool solidIsSpecified, UInt64 solidBlockSize,
@@ -157,13 +157,13 @@ static void SetOutProperties(
{
if (!method.IsEmpty())
AddProp(properties, is7z ? "0": "m", method);
if (dictionary != (UInt32)(Int32)-1)
if (dict64 != (UInt64)(Int64)-1)
{
AString name;
if (is7z)
name = "0";
name += (orderMode ? "mem" : "d");
AddProp(properties, name, GetNumInBytesString(dictionary));
AddProp(properties, name, GetNumInBytesString(dict64));
}
if (order != (UInt32)(Int32)-1)
{
@@ -389,7 +389,7 @@ static HRESULT ShowDialog(
di.Level,
!methodOverride,
di.Method,
di.Dictionary,
di.Dict64,
di.OrderMode, di.Order,
di.SolidIsSpecified, di.SolidBlockSize,
di.MultiThreadIsAllowed, di.NumThreads,

View File

@@ -27,6 +27,8 @@ CFLAGS_WARN_CLANG_12= $(CFLAGS_WARN_CLANG_3_8) \
-Wno-atomic-implicit-seq-cst \
-Wconversion \
-Wno-sign-conversion \
-Wno-suggest-override \
-Wno-suggest-destructor-override \
CFLAGS_WARN_MAC = \
-Wno-poison-system-directories \

View File

@@ -42,6 +42,10 @@ CFLAGS_WARN_GCC_9 = \
# -Wno-sign-conversion \
CFLAGS_WARN_GCC_10 = $(CFLAGS_WARN_GCC_9) \
-Wmaybe-uninitialized \
-Wmisleading-indentation \
CFLAGS_WARN_GCC_PPMD_UNALIGNED = \
-Wno-strict-aliasing \

View File

@@ -0,0 +1,7 @@
// Sha256Prepare.cpp
#include "StdAfx.h"
#include "../../C/LzFind.h"
static struct CLzFindPrepare { CLzFindPrepare() { LzFindPrepare(); } } g_CLzFindPrepare;

View File

@@ -25,6 +25,19 @@ public:
operator const Byte *() const { return _data; }
size_t Size() const { return _size; }
void Alloc(size_t size)
{
if (!_data || size != _size)
{
::MidFree(_data);
_size = 0;
_data = NULL;
_data = (Byte *)::MidAlloc(size);
if (_data)
_size = size;
}
}
void AllocAtLeast(size_t size)
{
if (!_data || size > _size)
@@ -105,5 +118,22 @@ public:
}
};
/*
CMidAlignedBuffer must return aligned pointer.
- in Windows it uses CMidBuffer(): MidAlloc() : VirtualAlloc()
VirtualAlloc(): Memory allocated is automatically initialized to zero.
MidAlloc(0) returns NULL
- in non-Windows systems it uses g_AlignedAlloc.
g_AlignedAlloc::Alloc(size = 0) can return non NULL.
*/
typedef
#ifdef _WIN32
CMidBuffer
#else
CAlignedBuffer
#endif
CMidAlignedBuffer;
#endif

View File

@@ -26,6 +26,14 @@ static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message, WPARAM wP
return FALSE;
if (message == WM_INITDIALOG)
dialog->Attach(dialogHWND);
/* MSDN: The dialog box procedure should return
TRUE - if it processed the message
FALSE - if it did not process the message
If the dialog box procedure returns FALSE,
the dialog manager performs the default dialog operation in response to the message.
*/
try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
catch(...) { return TRUE; }
}
@@ -39,6 +47,7 @@ bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
case WM_NOTIFY: return OnNotify((UINT)wParam, (LPNMHDR) lParam);
case WM_TIMER: return OnTimer(wParam, lParam);
case WM_SIZE: return OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
case WM_DESTROY: return OnDestroy();
case WM_HELP: OnHelp(); return true;
/*
OnHelp(

View File

@@ -31,6 +31,12 @@ public:
bool SetItemText(int itemID, LPCTSTR s)
{ return BOOLToBool(SetDlgItemText(_window, itemID, s)); }
bool SetItemTextA(int itemID, LPCSTR s)
{ return BOOLToBool(SetDlgItemTextA(_window, itemID, s)); }
bool SetItemText_Empty(int itemID)
{ return SetItemText(itemID, TEXT("")); }
#ifndef _UNICODE
bool SetItemText(int itemID, LPCWSTR s)
{
@@ -51,6 +57,12 @@ public:
*/
#endif
bool GetItemText(int itemID, UString &s)
{
CWindow window(GetItem(itemID));
return window.GetText(s);
}
bool SetItemInt(int itemID, UINT value, bool isSigned)
{ return BOOLToBool(SetDlgItemInt(_window, itemID, value, BoolToBOOL(isSigned))); }
bool GetItemInt(int itemID, bool isSigned, UINT &value)
@@ -65,6 +77,13 @@ public:
HWND GetNextTabItem(HWND control, bool previous)
{ return GetNextDlgTabItem(_window, control, BoolToBOOL(previous)); }
LRESULT SendMsg_NextDlgCtl(WPARAM wParam, LPARAM lParam)
{ return SendMsg(WM_NEXTDLGCTL, wParam, lParam); }
LRESULT SendMsg_NextDlgCtl_HWND(HWND hwnd) { return SendMsg_NextDlgCtl((WPARAM)hwnd, TRUE); }
LRESULT SendMsg_NextDlgCtl_CtlId(int id) { return SendMsg_NextDlgCtl_HWND(GetItem(id)); }
LRESULT SendMsg_NextDlgCtl_Next() { return SendMsg_NextDlgCtl(0, FALSE); }
LRESULT SendMsg_NextDlgCtl_Prev() { return SendMsg_NextDlgCtl(1, FALSE); }
bool MapRect(LPRECT rect)
{ return BOOLToBool(MapDialogRect(_window, rect)); }
@@ -92,6 +111,7 @@ public:
virtual bool OnCommand(WPARAM wParam, LPARAM lParam);
virtual bool OnCommand(int code, int itemID, LPARAM lParam);
virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; }
virtual bool OnDestroy() { return false; }
/*
#ifdef UNDER_CE

View File

@@ -19,6 +19,14 @@ namespace NError {
static bool MyFormatMessage(DWORD errorCode, UString &message)
{
#ifndef _SFX
if ((HRESULT)errorCode == MY_HRES_ERROR__INTERNAL_ERROR)
{
message = "Internal Error: The failure in hardware (RAM or CPU), OS or program";
return true;
}
#endif
#ifdef _WIN32
LPVOID msgBuf;

View File

@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include <wchar.h>
// #include <stdio.h>
#ifndef _UNICODE
#include "../Common/StringConvert.h"
@@ -17,12 +18,27 @@ namespace NWindows {
namespace NRegistry {
#define MYASSERT(expr) // _ASSERTE(expr)
#define MY_ASSUME(expr)
/*
static void Error()
{
#ifdef _CONSOLE
printf("\nregistry error\n");
#else
MessageBoxW(0, L"registry error", L"", 0);
// exit(1);
#endif
}
#define MY_ASSUME(expr) { if (!(expr)) Error(); }
*/
LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
LPTSTR keyClass, DWORD options, REGSAM accessMask,
LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition) throw()
{
MYASSERT(parentKey != NULL);
MY_ASSUME(parentKey != NULL);
DWORD dispositionReal;
HKEY key = NULL;
LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
@@ -39,7 +55,7 @@ LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) throw()
{
MYASSERT(parentKey != NULL);
MY_ASSUME(parentKey != NULL);
HKEY key = NULL;
LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
if (res == ERROR_SUCCESS)
@@ -66,7 +82,7 @@ LONG CKey::Close() throw()
// winNT to be deleted must not have subkeys
LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw()
{
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
return RegDeleteKey(_object, subKeyName);
}
@@ -101,14 +117,14 @@ static inline bool UINT32ToBool(UInt32 value) { return (value != 0); }
LONG CKey::DeleteValue(LPCTSTR name) throw()
{
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
return ::RegDeleteValue(_object, name);
}
#ifndef _UNICODE
LONG CKey::DeleteValue(LPCWSTR name)
{
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
if (g_IsNT)
return ::RegDeleteValueW(_object, name);
return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name));
@@ -117,7 +133,7 @@ LONG CKey::DeleteValue(LPCWSTR name)
LONG CKey::SetValue(LPCTSTR name, UInt32 value) throw()
{
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
return RegSetValueEx(_object, name, 0, REG_DWORD,
(const BYTE *)&value, sizeof(UInt32));
}
@@ -130,7 +146,7 @@ LONG CKey::SetValue(LPCTSTR name, bool value) throw()
LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw()
{
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
return RegSetValueEx(_object, name, 0, REG_SZ,
(const BYTE *)value, ((DWORD)lstrlen(value) + 1) * sizeof(TCHAR));
}
@@ -139,7 +155,7 @@ LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw()
LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
{
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
return RegSetValueEx(_object, name, NULL, REG_SZ,
(const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR));
}
@@ -150,7 +166,7 @@ LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
{
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
if (g_IsNT)
return RegSetValueExW(_object, name, 0, REG_SZ,
(const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));
@@ -164,7 +180,7 @@ LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) throw()
{
MYASSERT(value != NULL);
MYASSERT(_object != NULL);
MY_ASSUME(_object != NULL);
return RegSetValueEx(_object, name, 0, REG_BINARY,
(const BYTE *)value, size);
}

View File

@@ -153,6 +153,10 @@ public:
{
return Semaphore_Create(&_object, initCount, maxCount);
}
WRes OptCreateInit(UInt32 initCount, UInt32 maxCount)
{
return Semaphore_OptCreateInit(&_object, initCount, maxCount);
}
WRes Release() { return Semaphore_Release1(&_object); }
WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
WRes Lock() { return Semaphore_Wait(&_object); }

View File

@@ -12,12 +12,12 @@
#else
#include <unistd.h>
#include <sys/utsname.h>
#ifdef __APPLE__
#include <sys/sysctl.h>
#elif !defined(_AIX)
#include <sys/auxv.h>
#ifdef MY_CPU_ARM_OR_ARM64
@@ -25,13 +25,56 @@
#endif
#endif
#ifdef __linux__
#include "../Windows/FileIO.h"
#endif
#endif // WIN32
#include "SystemInfo.h"
#include "System.h"
using namespace NWindows;
#ifdef __linux__
static bool ReadFile_to_Buffer(CFSTR fileName, CByteBuffer &buf)
{
NWindows::NFile::NIO::CInFile file;
if (!file.Open(fileName))
return false;
/*
UInt64 size;
if (!file.GetLength(size))
{
// GetLength() doesn't work "/proc/cpuinfo"
return false;
}
if (size >= ((UInt32)1 << 29))
return false;
*/
size_t size = 0;
size_t addSize = ((size_t)1 << 12);
for (;;)
{
// printf("\nsize = %d\n", (unsigned)size);
buf.ChangeSize_KeepData(size + addSize, size);
size_t processed;
if (!file.ReadFull(buf + size, addSize, processed))
return false;
if (processed == 0)
{
buf.ChangeSize_KeepData(size, size);
return true;
}
size += processed;
addSize *= 2;
}
}
#endif
#ifndef __APPLE__
static void PrintHex(AString &s, UInt64 v)
{
@@ -56,7 +99,7 @@ static void PrintCpuChars(AString &s, UInt32 v)
}
static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
static void x86cpuid_to_String(const Cx86cpuid &c, AString &s, AString &ver)
{
s.Empty();
@@ -87,13 +130,10 @@ static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
s.Trim();
}
s.Add_Space_if_NotEmpty();
{
char temp[32];
ConvertUInt32ToHex(c.ver, temp);
s += '(';
s += temp;
s += ')';
ver += temp;
}
}
@@ -402,18 +442,52 @@ void GetSysInfo(AString &s1, AString &s2)
void GetCpuName(AString &s);
void GetCpuName(AString &s)
static void AddBracedString(AString &dest, AString &src)
{
s.Empty();
if (!src.IsEmpty())
{
AString s;
s += '(';
s += src;
s += ')';
dest.Add_OptSpaced(s);
}
}
struct CCpuName
{
AString CpuName;
AString Revision;
AString Microcode;
AString LargePages;
void Fill();
void Get_Revision_Microcode_LargePages(AString &s)
{
s.Empty();
AddBracedString(s, Revision);
AddBracedString(s, Microcode);
s.Add_OptSpaced(LargePages);
}
};
void CCpuName::Fill()
{
CpuName.Empty();
Revision.Empty();
Microcode.Empty();
LargePages.Empty();
AString &s = CpuName;
#ifdef MY_CPU_X86_OR_AMD64
{
Cx86cpuid cpuid;
if (x86cpuid_CheckAndRead(&cpuid))
{
AString s2;
x86cpuid_to_String(cpuid, s2);
s += s2;
x86cpuid_to_String(cpuid, s, Revision);
}
else
{
@@ -484,11 +558,10 @@ void GetCpuName(AString &s)
}
if (res[0] == ERROR_SUCCESS || res[1] == ERROR_SUCCESS)
{
s.Add_OptSpaced("(");
for (int i = 0; i < 2; i++)
{
if (i == 1)
s += "->";
Microcode += "->";
if (res[i] != ERROR_SUCCESS)
continue;
const CByteBuffer &buf = bufs[i];
@@ -497,13 +570,12 @@ void GetCpuName(AString &s)
UInt32 high = GetUi32(buf);
if (high != 0)
{
PrintHex(s, high);
s += ".";
PrintHex(Microcode, high);
Microcode += ".";
}
PrintHex(s, GetUi32(buf + 4));
PrintHex(Microcode, GetUi32(buf + 4));
}
}
s += ")";
}
}
}
@@ -511,7 +583,7 @@ void GetCpuName(AString &s)
#ifdef _7ZIP_LARGE_PAGES
Add_LargePages_String(s);
Add_LargePages_String(LargePages);
#endif
}
@@ -532,13 +604,10 @@ void AddCpuFeatures(AString &s)
// s += TypeToString2(k_PF, ARRAY_SIZE(k_PF), i);
}
}
s.Add_Space_if_NotEmpty();
s += "f:";
s.Add_OptSpaced("f:");
PrintHex(s, flags);
#else // _WIN32
#ifdef __APPLE__
#elif defined(__APPLE__)
{
UInt32 v = 0;
if (My_sysctlbyname_Get_UInt32("hw.pagesize", &v) == 0)
@@ -549,10 +618,46 @@ void AddCpuFeatures(AString &s)
}
}
#elif !defined(_AIX)
#else
s.Add_Space_if_NotEmpty();
s += "hwcap:";
const long v = sysconf(_SC_PAGESIZE);
if (v != -1)
{
s.Add_Space_if_NotEmpty();
s += "PageSize:";
s.Add_UInt32((UInt32)(v >> 10));
s += "KB";
}
#if !defined(_AIX)
#ifdef __linux__
CByteBuffer buf;
if (ReadFile_to_Buffer("/sys/kernel/mm/transparent_hugepage/enabled", buf))
// if (ReadFile_to_Buffer("/proc/cpuinfo", buf))
{
s.Add_OptSpaced("THP:");
AString s2;
s2.SetFrom_CalcLen((const char *)(const void *)(const Byte *)buf, (unsigned)buf.Size());
const int pos = s2.Find('[');
if (pos >= 0)
{
const int pos2 = s2.Find(']', pos + 1);
if (pos2 >= 0)
{
s2.DeleteFrom(pos2);
s2.DeleteFrontal(pos + 1);
}
}
s += s2;
}
// else throw CSystemException(MY_SRes_HRESULT_FROM_WRes(errno));
#endif
s.Add_OptSpaced("hwcap:");
{
unsigned long h = getauxval(AT_HWCAP);
PrintHex(s, h);
@@ -561,6 +666,9 @@ void AddCpuFeatures(AString &s)
if (h & HWCAP_SHA1) s += ":SHA1";
if (h & HWCAP_SHA2) s += ":SHA2";
if (h & HWCAP_AES) s += ":AES";
if (h & HWCAP_ASIMD) s += ":ASIMD";
#elif defined(MY_CPU_ARM)
if (h & HWCAP_NEON) s += ":NEON";
#endif
}
@@ -580,9 +688,8 @@ void AddCpuFeatures(AString &s)
#endif
}
}
#endif
#endif // _WIN32
#endif // _AIX
#endif // _WIN32
}
@@ -609,11 +716,11 @@ static BOOL My_RtlGetVersion(OSVERSIONINFOEXW *vi)
#endif
void GetSystemInfoText(AString &sRes)
void GetOsInfoText(AString &sRes)
{
{
{
AString s;
sRes.Empty();
AString s;
#ifdef _WIN32
#ifndef UNDER_CE
// OSVERSIONINFO vi;
@@ -634,16 +741,16 @@ void GetSystemInfoText(AString &sRes)
s += " SP:"; s.Add_UInt32(vi.wServicePackMajor);
s += "."; s.Add_UInt32(vi.wServicePackMinor);
}
s += " Suite:"; PrintHex(s, vi.wSuiteMask);
s += " Type:"; s.Add_UInt32(vi.wProductType);
// s += " Suite:"; PrintHex(s, vi.wSuiteMask);
// s += " Type:"; s.Add_UInt32(vi.wProductType);
// s += " "; s += GetOemString(vi.szCSDVersion);
}
/*
{
s += " OEMCP:";
s.Add_UInt32(GetOEMCP());
s += " ACP:";
s.Add_UInt32(GetACP());
s += " OEMCP:"; s.Add_UInt32(GetOEMCP());
s += " ACP:"; s.Add_UInt32(GetACP());
}
*/
#endif
#else // _WIN32
@@ -666,8 +773,14 @@ void GetSystemInfoText(AString &sRes)
#endif // _WIN32
sRes += s;
sRes.Add_LF();
}
}
void GetSystemInfoText(AString &sRes)
{
GetOsInfoText(sRes);
sRes.Add_LF();
{
AString s, s1, s2;
@@ -712,5 +825,73 @@ void GetSystemInfoText(AString &sRes)
}
#endif
*/
}
void GetCpuName(AString &s);
void GetCpuName(AString &s)
{
CCpuName cpuName;
cpuName.Fill();
s = cpuName.CpuName;
AString s2;
cpuName.Get_Revision_Microcode_LargePages(s2);
s.Add_OptSpaced(s2);
}
void GetCpuName_MultiLine(AString &s);
void GetCpuName_MultiLine(AString &s)
{
CCpuName cpuName;
cpuName.Fill();
s = cpuName.CpuName;
AString s2;
cpuName.Get_Revision_Microcode_LargePages(s2);
if (!s2.IsEmpty())
{
s.Add_LF();
s += s2;
}
}
void GetCompiler(AString &s)
{
#ifdef __VERSION__
s += __VERSION__;
#endif
#ifdef __GNUC__
s += " GCC ";
s.Add_UInt32(__GNUC__);
s += '.';
s.Add_UInt32(__GNUC_MINOR__);
s += '.';
s.Add_UInt32(__GNUC_PATCHLEVEL__);
#endif
#ifdef __clang__
s += " CLANG ";
s.Add_UInt32(__clang_major__);
s += '.';
s.Add_UInt32(__clang_minor__);
#endif
#ifdef __xlC__
s += " XLC ";
s.Add_UInt32(__xlC__ >> 8);
s += '.';
s.Add_UInt32(__xlC__ & 0xFF);
#ifdef __xlC_ver__
s += '.';
s.Add_UInt32(__xlC_ver__ >> 8);
s += '.';
s.Add_UInt32(__xlC_ver__ & 0xFF);
#endif
#endif
#ifdef _MSC_VER
s += " MSC ";
s.Add_UInt32(_MSC_VER);
#endif
}

View File

@@ -5,8 +5,14 @@
#include "../Common/MyString.h"
void GetCpuName_MultiLine(AString &s);
void GetOsInfoText(AString &sRes);
void GetSystemInfoText(AString &s);
void PrintSize_KMGT_Or_Hex(AString &s, UInt64 v);
void Add_LargePages_String(AString &s);
void GetCompiler(AString &s);
#endif

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "21" ?>
<?define VerMinor = "02" ?>
<?define VerMinor = "03" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>

View File

@@ -1,4 +1,4 @@
7-Zip 21.02 Sources
7-Zip 21.03 Sources
-------------------
7-Zip is a file archiver for Windows.
@@ -42,11 +42,11 @@ You can download LZMA SDK from:
LZMA SDK is written and placed in the public domain by Igor Pavlov.
How to compile
--------------
How to compile in Windows
-------------------------
To compile the sources to Windows binaries you need Visual Studio compiler and/or Windows SDK.
You can use latest Windows Studio 2017 to compile binaries for x86, x64 and arm64 platforms.
You can use latest Windows Studio 2017/2019 to compile binaries for x86, x64 and arm64 platforms.
Also you can use old compilers for some platforms:
x86 : Visual C++ 6.0 with Platform SDK
x64 : Windows Server 2003 R2 Platform SDK
@@ -73,6 +73,7 @@ The dsp file compiling can be used for development and debug purposes.
The final 7-Zip binaries are compiled via makefiles, that provide best
optimization options.
How to compile with makefile
----------------------------
@@ -90,10 +91,78 @@ MY_DYNAMIC_LINK
Compiling under Unix/Linux
--------------------------
Check this site for Posix/Linux version:
http://sourceforge.net/projects/p7zip/
Compiling 7-Zip for Unix/Linux
------------------------------
There are several otpions to compile 7-Zip with different compilers: gcc and clang.
Also 7-Zip code contains two versions for some critical parts of code: in C and in Assembeler.
So if you compile the version with Assembeler code, you will get faster 7-Zip binary.
7-Zip's assembler code uses the following syntax for different platforms:
1) x86 and x86-64 (AMD64): MASM syntax.
There are 2 programs that supports MASM syntax in Linux.
' 'Asmc Macro Assembler and JWasm. But JWasm now doesn't support some
cpu instructions used in 7-Zip.
So you must install Asmc Macro Assembler in Linux, if you want to compile fastest version
of 7-Zip x86 and x86-64:
https://github.com/nidud/asmc
2) arm64: GNU assembler for ARM64 with preprocessor.
That systax of that arm64 assembler code in 7-Zip is supported by GCC and CLANG for ARM64.
There are different binaries that can be compiled from 7-Zip source.
There are 2 main files in folder for compiling:
makefile - that can be used for compiling Windows version of 7-Zip with nmake command
makefile.gcc - that can be used for compiling Linux/macOS versions of 7-Zip with make command
At first you must change the current folder to folder that contains `makefile.gcc`:
cd CPP/7zip/Bundles/Alone2
Then you can compile `makefile.gcc` with the command:
make -j -f makefile.gcc
Also there are additional "*.mak" files in folder "CPP/7zip/" that can be used to compile
7-Zip binaries with optimized code and optimzing options.
To compile with GCC without assembler:
cd CPP/7zip/Bundles/Alone2
make -j -f ../../cmpl_gcc.mak
To compile with CLANG without assembler:
make -j -f ../../cmpl_clang.mak
To compile 7-Zip for x86-64 with asmc assembler:
make -j -f ../../cmpl_gcc_x64.mak
To compile 7-Zip for arm64 with assembler:
make -j -f ../../cmpl_gcc_arm64.mak
To compile 7-Zip for arm64 for macOS:
make -j -f ../../cmpl_mac_arm64.mak
Also you can change some compiler options in the mak files:
cmpl_gcc.mak
var_gcc.mak
warn_gcc.mak
7-Zip and p7zip
===============
Now there are two different ports of 7-Zip for Linux/macOS:
1) p7zip - another port of 7-Zip for Linux, made by an independent developer.
The latest version of p7zip now is 16.02, and that p7zip 16.02 is outdated now.
http://sourceforge.net/projects/p7zip/
2) 7-Zip for Linux/macOS - this package - it's new code with all changes from latest 7-Zip for Windows.
These two ports are not identical.
Note also that some Linux specific things can be implemented better in p7zip than in new 7-Zip for Linux.
Notes:
@@ -127,7 +196,7 @@ DOC Documentation
7zip.wix - installer script for WIX
Asm - Source code in Assembler (optimized code for CRC calculation and Intel-AES encryption)
Asm - Source code in Assembler : optimized code for CRC, SHA, AES, LZMA decoding.
C - Source code in C
@@ -146,6 +215,7 @@ Windows common files for Windows related code
Bundle Modules that are bundles of other modules (files)
Alone 7za.exe: Standalone version of 7-Zip console that supports only 7z/xz/cab/zip/gzip/bzip2/tar.
Alone2 7zz.exe: Standalone version of 7-Zip console that supports all formats.
Alone7z 7zr.exe: Standalone version of 7-Zip console that supports only 7z (reduced version)
Fm Standalone version of 7-Zip File Manager
Format7z 7za.dll: .7z support