Compare commits

...

12 Commits
9.21 ... 15.11

Author SHA1 Message Date
Igor Pavlov
e24f7fba53 15.11 2016-05-28 00:16:57 +01:00
Igor Pavlov
7c8a265a15 15.10 2016-05-28 00:16:57 +01:00
Igor Pavlov
a663a6deb7 15.09 2016-05-28 00:16:56 +01:00
Igor Pavlov
6543c28020 15.08 2016-05-28 00:16:56 +01:00
Igor Pavlov
f6444c3256 15.07 2016-05-28 00:16:55 +01:00
Igor Pavlov
cba375916f 15.06 2016-05-28 00:16:55 +01:00
Igor Pavlov
54490d51d5 15.05 2016-05-28 00:16:54 +01:00
Igor Pavlov
0713a3ab80 9.38 2016-05-28 00:16:53 +01:00
Igor Pavlov
7e021179cd 9.36 2016-05-28 00:16:53 +01:00
Igor Pavlov
0dc16c691d 9.35 2016-05-28 00:16:53 +01:00
Igor Pavlov
f08f4dcc3c 9.34 2016-05-28 00:16:51 +01:00
Igor Pavlov
83f8ddcc5b 9.22 2016-05-28 00:16:06 +01:00
1217 changed files with 125630 additions and 50625 deletions

0
Asm/arm/7zCrcOpt.asm Executable file → Normal file
View File

28
Asm/x86/7zAsm.asm Executable file → Normal file
View File

@@ -1,5 +1,5 @@
; 7zAsm.asm -- ASM macros ; 7zAsm.asm -- ASM macros
; 2009-12-12 : Igor Pavlov : Public domain ; 2012-12-30 : Igor Pavlov : Public domain
MY_ASM_START macro MY_ASM_START macro
ifdef x64 ifdef x64
@@ -13,30 +13,34 @@ endm
MY_PROC macro name:req, numParams:req MY_PROC macro name:req, numParams:req
align 16 align 16
proc_numParams equ numParams proc_numParams = numParams
ifdef x64 ifdef x64
proc_name equ name proc_name equ name
name PROC
else else
proc_fastcall_name equ @CatStr(@,name,@, %numParams * 4) proc_name equ @CatStr(@,name,@, %numParams * 4)
public proc_fastcall_name
proc_fastcall_name:
endif endif
proc_name PROC
endm endm
MY_ENDP macro MY_ENDP macro
ifdef x64 ifdef x64
ret ret
proc_name ENDP
else else
ret (proc_numParams - 2) * 4 if proc_numParams LT 3
ret
else
ret (proc_numParams - 2) * 4
endif
endif endif
proc_name ENDP
endm endm
ifdef x64 ifdef x64
REG_SIZE equ 8 REG_SIZE equ 8
REG_LOGAR_SIZE equ 3
else else
REG_SIZE equ 4 REG_SIZE equ 4
REG_LOGAR_SIZE equ 2
endif endif
x0 equ EAX x0 equ EAX
@@ -67,6 +71,14 @@ ifdef x64
r5 equ RBP r5 equ RBP
r6 equ RSI r6 equ RSI
r7 equ RDI r7 equ RDI
x8 equ r8d
x9 equ r9d
x10 equ r10d
x11 equ r11d
x12 equ r12d
x13 equ r13d
x14 equ r14d
x15 equ r15d
else else
r0 equ x0 r0 equ x0
r1 equ x1 r1 equ x1

0
Asm/x86/7zCrcOpt.asm Executable file → Normal file
View File

0
Asm/x86/AesOpt.asm Executable file → Normal file
View File

205
Asm/x86/XzCrc64Opt.asm Normal file
View File

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

181
C/7z.h Executable file → Normal file
View File

@@ -1,89 +1,68 @@
/* 7z.h -- 7z interface /* 7z.h -- 7z interface
2010-03-11 : Igor Pavlov : Public domain */ 2014-02-08 : Igor Pavlov : Public domain */
#ifndef __7Z_H #ifndef __7Z_H
#define __7Z_H #define __7Z_H
#include "7zBuf.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20 #define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6 #define k7zSignatureSize 6
extern Byte k7zSignature[k7zSignatureSize];
#define k7zMajorVersion 0
enum EIdEnum extern const Byte k7zSignature[k7zSignatureSize];
{
k7zIdEnd,
k7zIdHeader,
k7zIdArchiveProperties,
k7zIdAdditionalStreamsInfo,
k7zIdMainStreamsInfo,
k7zIdFilesInfo,
k7zIdPackInfo,
k7zIdUnpackInfo,
k7zIdSubStreamsInfo,
k7zIdSize,
k7zIdCRC,
k7zIdFolder,
k7zIdCodersUnpackSize,
k7zIdNumUnpackStream,
k7zIdEmptyStream,
k7zIdEmptyFile,
k7zIdAnti,
k7zIdName,
k7zIdCTime,
k7zIdATime,
k7zIdMTime,
k7zIdWinAttributes,
k7zIdComment,
k7zIdEncodedHeader,
k7zIdStartPos,
k7zIdDummy
};
typedef struct typedef struct
{ {
UInt32 NumInStreams; const Byte *Data;
UInt32 NumOutStreams; size_t Size;
UInt64 MethodID; } CSzData;
CBuf Props;
} CSzCoderInfo;
void SzCoderInfo_Init(CSzCoderInfo *p); /* CSzCoderInfo & CSzFolder support only default methods */
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
typedef struct
{
size_t PropsOffset;
UInt32 MethodID;
Byte NumStreams;
Byte PropsSize;
} CSzCoderInfo;
typedef struct typedef struct
{ {
UInt32 InIndex; UInt32 InIndex;
UInt32 OutIndex; UInt32 OutIndex;
} CSzBindPair; } CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
typedef struct typedef struct
{ {
CSzCoderInfo *Coders;
CSzBindPair *BindPairs;
UInt32 *PackStreams;
UInt64 *UnpackSizes;
UInt32 NumCoders; UInt32 NumCoders;
UInt32 NumBindPairs; UInt32 NumBonds;
UInt32 NumPackStreams; UInt32 NumPackStreams;
int UnpackCRCDefined; UInt32 UnpackStream;
UInt32 UnpackCRC; UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
UInt32 NumUnpackStreams; CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder; } CSzFolder;
void SzFolder_Init(CSzFolder *p); /*
UInt64 SzFolder_GetUnpackSize(CSzFolder *p); typedef struct
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); {
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); size_t CodersDataOffset;
UInt64 SzFolder_GetUnpackSize(CSzFolder *p); size_t UnpackSizeDataOffset;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 StartPackStreamIndex;
// UInt32 IndexOfMainOutStream;
} CSzFolder2;
*/
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes);
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
typedef struct typedef struct
{ {
@@ -93,35 +72,46 @@ typedef struct
typedef struct typedef struct
{ {
CNtfsFileTime MTime; Byte *Defs; /* MSB 0 bit numbering */
UInt64 Size; UInt32 *Vals;
UInt32 Crc; } CSzBitUi32s;
UInt32 Attrib;
Byte HasStream; typedef struct
Byte IsDir; {
Byte IsAnti; Byte *Defs; /* MSB 0 bit numbering */
Byte CrcDefined; // UInt64 *Vals;
Byte MTimeDefined; CNtfsFileTime *Vals;
Byte AttribDefined; } CSzBitUi64s;
} CSzFileItem;
#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
void SzFile_Init(CSzFileItem *p);
#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
typedef struct typedef struct
{ {
UInt64 *PackSizes;
Byte *PackCRCsDefined;
UInt32 *PackCRCs;
CSzFolder *Folders;
CSzFileItem *Files;
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 NumFolders; UInt32 NumFolders;
UInt32 NumFiles;
UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs;
size_t *FoCodersOffsets;
size_t *FoSizesOffsets;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 *FoStartPackStreamIndex;
// CSzFolder2 *Folders; // +1 item for sum values
Byte *CodersData;
Byte *UnpackSizesData;
size_t UnpackSizesDataSize;
// UInt64 *CoderUnpackSizes;
} CSzAr; } CSzAr;
void SzAr_Init(CSzAr *p);
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain);
/* /*
SzExtract extracts file from archive SzExtract extracts file from archive
@@ -146,19 +136,34 @@ void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
typedef struct typedef struct
{ {
CSzAr db; CSzAr db;
UInt64 startPosAfterHeader; UInt64 startPosAfterHeader;
UInt64 dataPos; UInt64 dataPos;
UInt32 NumFiles;
UInt32 *FolderStartPackStreamIndex; UInt64 *UnpackPositions;
UInt64 *PackStreamStartPositions; // Byte *IsEmptyFiles;
UInt32 *FolderStartFileIndex; Byte *IsDirs;
CSzBitUi32s CRCs;
CSzBitUi32s Attribs;
// CSzBitUi32s Parents;
CSzBitUi64s MTime;
CSzBitUi64s CTime;
// UInt32 *FolderStartPackStreamIndex;
UInt32 *FolderStartFileIndex; // + 1
UInt32 *FileIndexToFolderIndexMap; UInt32 *FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */ size_t *FileNameOffsets; /* in 2-byte steps */
CBuf FileNames; /* UTF-16-LE */ Byte *FileNames; /* UTF-16-LE */
} CSzArEx; } CSzArEx;
#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p); void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
@@ -172,6 +177,11 @@ if dest != NULL, the return value specifies the number of 16-bit characters that
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/*
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/
SRes SzArEx_Extract( SRes SzArEx_Extract(
const CSzArEx *db, const CSzArEx *db,
ILookInStream *inStream, ILookInStream *inStream,
@@ -196,7 +206,8 @@ SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL SZ_ERROR_FAIL
*/ */
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp);
EXTERN_C_END EXTERN_C_END

16
C/7zAlloc.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* 7zAlloc.c -- Allocation functions /* 7zAlloc.c -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zAlloc.h" #include "7zAlloc.h"
@@ -20,11 +22,11 @@ int g_allocCountTemp = 0;
void *SzAlloc(void *p, size_t size) void *SzAlloc(void *p, size_t size)
{ {
p = p; UNUSED_VAR(p);
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount);
g_allocCount++; g_allocCount++;
#endif #endif
return malloc(size); return malloc(size);
@@ -32,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
void SzFree(void *p, void *address) void SzFree(void *p, void *address)
{ {
p = p; UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) if (address != 0)
{ {
@@ -45,11 +47,11 @@ void SzFree(void *p, void *address)
void *SzAllocTemp(void *p, size_t size) void *SzAllocTemp(void *p, size_t size)
{ {
p = p; UNUSED_VAR(p);
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp);
g_allocCountTemp++; g_allocCountTemp++;
#ifdef _WIN32 #ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size); return HeapAlloc(GetProcessHeap(), 0, size);
@@ -60,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
void SzFreeTemp(void *p, void *address) void SzFreeTemp(void *p, void *address)
{ {
p = p; UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) if (address != 0)
{ {

10
C/7zAlloc.h Executable file → Normal file
View File

@@ -1,15 +1,23 @@
/* 7zAlloc.h -- Allocation functions /* 7zAlloc.h -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */ 2013-03-25 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H #ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H #define __7Z_ALLOC_H
#include <stdlib.h> #include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void *SzAlloc(void *p, size_t size); void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address); void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size); void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address); void SzFreeTemp(void *p, void *address);
#ifdef __cplusplus
}
#endif
#endif #endif

1902
C/7zArcIn.c Normal file
View File

File diff suppressed because it is too large Load Diff

6
C/7zBuf.c Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/* 7zBuf.c -- Byte Buffer /* 7zBuf.c -- Byte Buffer
2008-03-28 2013-01-21 : Igor Pavlov : Public domain */
Igor Pavlov
Public domain */ #include "Precomp.h"
#include "7zBuf.h" #include "7zBuf.h"

12
C/7zBuf.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* 7zBuf.h -- Byte Buffer /* 7zBuf.h -- Byte Buffer
2009-02-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H #ifndef __7Z_BUF_H
#define __7Z_BUF_H #define __7Z_BUF_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
typedef struct typedef struct
{ {
@@ -32,8 +30,6 @@ void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

12
C/7zBuf2.c Executable file → Normal file
View File

@@ -1,7 +1,10 @@
/* 7zBuf2.c -- Byte Buffer /* 7zBuf2.c -- Byte Buffer
2008-10-04 : Igor Pavlov : Public domain */ 2014-08-22 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
#include "7zBuf.h" #include "7zBuf.h"
void DynBuf_Construct(CDynBuf *p) void DynBuf_Construct(CDynBuf *p)
@@ -31,8 +34,11 @@ int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
alloc->Free(alloc, p->data); alloc->Free(alloc, p->data);
p->data = data; p->data = data;
} }
memcpy(p->data + p->pos, buf, size); if (size != 0)
p->pos += size; {
memcpy(p->data + p->pos, buf, size);
p->pos += size;
}
return 1; return 1;
} }

73
C/7zCrc.c Executable file → Normal file
View File

@@ -1,29 +1,35 @@
/* 7zCrc.c -- CRC32 init /* 7zCrc.c -- CRC32 init
2010-12-01 : Igor Pavlov : Public domain */ 2015-03-10 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zCrc.h" #include "7zCrc.h"
#include "CpuArch.h" #include "CpuArch.h"
#define kCrcPoly 0xEDB88320 #define kCrcPoly 0xEDB88320
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8 #define CRC_NUM_TABLES 8
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#elif defined(MY_CPU_LE)
#define CRC_NUM_TABLES 4
#else #else
#define CRC_NUM_TABLES 5 #define CRC_NUM_TABLES 9
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif #endif
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif #endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
static CRC_FUNC g_CrcUpdate; CRC_FUNC g_CrcUpdateT4;
CRC_FUNC g_CrcUpdateT8;
CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
@@ -36,6 +42,17 @@ UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
} }
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
const Byte *pEnd = p + size;
for (; p != pEnd; p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
void MY_FAST_CALL CrcGenerateTable() void MY_FAST_CALL CrcGenerateTable()
{ {
UInt32 i; UInt32 i;
@@ -52,22 +69,43 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = g_CrcTable[i - 256]; UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
} }
#if CRC_NUM_TABLES < 4
g_CrcUpdate = CrcUpdateT1;
#else
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
g_CrcUpdate = CrcUpdateT4; g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
#if CRC_NUM_TABLES == 8 #ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder()) if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8; g_CrcUpdate = CrcUpdateT8;
#endif #endif
#endif
#else #else
{ {
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
UInt32 k = 1; UInt32 k = 0x01020304;
if (*(const Byte *)&k == 1) const Byte *p = (const Byte *)&k;
if (p[0] == 4 && p[1] == 3)
{
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4; g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
// g_CrcUpdate = CrcUpdateT8;
#endif
}
else if (p[0] != 1 || p[1] != 2)
g_CrcUpdate = CrcUpdateT1;
else else
#endif #endif
{ {
@@ -76,8 +114,15 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 x = g_CrcTable[i - 256]; UInt32 x = g_CrcTable[i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x); g_CrcTable[i] = CRC_UINT32_SWAP(x);
} }
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4; g_CrcUpdate = CrcUpdateT1_BeT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
// g_CrcUpdate = CrcUpdateT1_BeT8;
#endif
} }
} }
#endif #endif
#endif
} }

4
C/7zCrc.h Executable file → Normal file
View File

@@ -1,10 +1,10 @@
/* 7zCrc.h -- CRC32 calculation /* 7zCrc.h -- CRC32 calculation
2009-11-21 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H #ifndef __7Z_CRC_H
#define __7Z_CRC_H #define __7Z_CRC_H
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN

89
C/7zCrcOpt.c Executable file → Normal file
View File

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

319
C/7zDec.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2010-11-02 : Igor Pavlov : Public domain */ 2015-08-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -10,6 +12,7 @@
#include "Bcj2.h" #include "Bcj2.h"
#include "Bra.h" #include "Bra.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "Delta.h"
#include "LzmaDec.h" #include "LzmaDec.h"
#include "Lzma2Dec.h" #include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
@@ -17,14 +20,17 @@
#endif #endif
#define k_Copy 0 #define k_Copy 0
#define k_Delta 3
#define k_LZMA2 0x21 #define k_LZMA2 0x21
#define k_LZMA 0x30101 #define k_LZMA 0x30101
#define k_BCJ 0x03030103 #define k_BCJ 0x3030103
#define k_PPC 0x03030205 #define k_BCJ2 0x303011B
#define k_ARM 0x03030501 #define k_PPC 0x3030205
#define k_ARMT 0x03030701 #define k_IA64 0x3030401
#define k_SPARC 0x03030805 #define k_ARM 0x3030501
#define k_BCJ2 0x0303011B #define k_ARMT 0x3030701
#define k_SPARC 0x3030805
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
@@ -63,7 +69,7 @@ static Byte ReadByte(void *pp)
return 0; return 0;
} }
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{ {
CPpmd7 ppmd; CPpmd7 ppmd;
@@ -77,12 +83,12 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
s.res = SZ_OK; s.res = SZ_OK;
s.processed = 0; s.processed = 0;
if (coder->Props.size != 5) if (propsSize != 5)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
{ {
unsigned order = coder->Props.data[0]; unsigned order = props[0];
UInt32 memSize = GetUi32(coder->Props.data + 1); UInt32 memSize = GetUi32(props + 1);
if (order < PPMD7_MIN_ORDER || if (order < PPMD7_MIN_ORDER ||
order > PPMD7_MAX_ORDER || order > PPMD7_MAX_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE || memSize < PPMD7_MIN_MEM_SIZE ||
@@ -124,25 +130,25 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
#endif #endif
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{ {
CLzmaDec state; CLzmaDec state;
SRes res = SZ_OK; SRes res = SZ_OK;
LzmaDec_Construct(&state); LzmaDec_Construct(&state);
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
state.dic = outBuffer; state.dic = outBuffer;
state.dicBufSize = outSize; state.dicBufSize = outSize;
LzmaDec_Init(&state); LzmaDec_Init(&state);
for (;;) for (;;)
{ {
Byte *inBuf = NULL; const void *inBuf = NULL;
size_t lookahead = (1 << 18); size_t lookahead = (1 << 18);
if (lookahead > inSize) if (lookahead > inSize)
lookahead = (size_t)inSize; lookahead = (size_t)inSize;
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -172,27 +178,30 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
return res; return res;
} }
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
#ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{ {
CLzma2Dec state; CLzma2Dec state;
SRes res = SZ_OK; SRes res = SZ_OK;
Lzma2Dec_Construct(&state); Lzma2Dec_Construct(&state);
if (coder->Props.size != 1) if (propsSize != 1)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
state.decoder.dic = outBuffer; state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize; state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state); Lzma2Dec_Init(&state);
for (;;) for (;;)
{ {
Byte *inBuf = NULL; const void *inBuf = NULL;
size_t lookahead = (1 << 18); size_t lookahead = (1 << 18);
if (lookahead > inSize) if (lookahead > inSize)
lookahead = (size_t)inSize; lookahead = (size_t)inSize;
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -221,15 +230,18 @@ static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inS
return res; return res;
} }
#endif
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{ {
while (inSize > 0) while (inSize > 0)
{ {
void *inBuf; const void *inBuf;
size_t curSize = (1 << 18); size_t curSize = (1 << 18);
if (curSize > inSize) if (curSize > inSize)
curSize = (size_t)inSize; curSize = (size_t)inSize;
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); RINOK(inStream->Look(inStream, &inBuf, &curSize));
if (curSize == 0) if (curSize == 0)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize); memcpy(outBuffer, inBuf, curSize);
@@ -242,11 +254,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
static Bool IS_MAIN_METHOD(UInt32 m) static Bool IS_MAIN_METHOD(UInt32 m)
{ {
switch(m) switch (m)
{ {
case k_Copy: case k_Copy:
case k_LZMA: case k_LZMA:
#ifndef _7Z_NO_METHOD_LZMA2
case k_LZMA2: case k_LZMA2:
#endif
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
case k_PPMD: case k_PPMD:
#endif #endif
@@ -258,13 +272,12 @@ static Bool IS_MAIN_METHOD(UInt32 m)
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{ {
return return
c->NumInStreams == 1 && c->NumStreams == 1
c->NumOutStreams == 1 && /* && c->MethodID <= (UInt32)0xFFFFFFFF */
c->MethodID <= (UInt32)0xFFFFFFFF && && IS_MAIN_METHOD((UInt32)c->MethodID);
IS_MAIN_METHOD((UInt32)c->MethodID);
} }
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) #define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
static SRes CheckSupportedFolder(const CSzFolder *f) static SRes CheckSupportedFolder(const CSzFolder *f)
{ {
@@ -274,65 +287,73 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1) if (f->NumCoders == 1)
{ {
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
return SZ_OK; return SZ_OK;
} }
#ifndef _7Z_NO_METHODS_FILTERS
if (f->NumCoders == 2) if (f->NumCoders == 2)
{ {
CSzCoderInfo *c = &f->Coders[1]; const CSzCoderInfo *c = &f->Coders[1];
if (c->MethodID > (UInt32)0xFFFFFFFF || if (
c->NumInStreams != 1 || /* c->MethodID > (UInt32)0xFFFFFFFF || */
c->NumOutStreams != 1 || c->NumStreams != 1
f->NumPackStreams != 1 || || f->NumPackStreams != 1
f->PackStreams[0] != 0 || || f->PackStreams[0] != 0
f->NumBindPairs != 1 || || f->NumBonds != 1
f->BindPairs[0].InIndex != 1 || || f->Bonds[0].InIndex != 1
f->BindPairs[0].OutIndex != 0) || f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID) switch ((UInt32)c->MethodID)
{ {
case k_Delta:
case k_BCJ: case k_BCJ:
case k_PPC:
case k_IA64:
case k_SPARC:
case k_ARM: case k_ARM:
case k_ARMT:
break; break;
default: default:
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
return SZ_OK; return SZ_OK;
} }
#endif
if (f->NumCoders == 4) if (f->NumCoders == 4)
{ {
if (!IS_SUPPORTED_CODER(&f->Coders[1]) || if (!IS_SUPPORTED_CODER(&f->Coders[1])
!IS_SUPPORTED_CODER(&f->Coders[2]) || || !IS_SUPPORTED_CODER(&f->Coders[2])
!IS_BCJ2(&f->Coders[3])) || !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4 || if (f->NumPackStreams != 4
f->PackStreams[0] != 2 || || f->PackStreams[0] != 2
f->PackStreams[1] != 6 || || f->PackStreams[1] != 6
f->PackStreams[2] != 1 || || f->PackStreams[2] != 1
f->PackStreams[3] != 0 || || f->PackStreams[3] != 0
f->NumBindPairs != 3 || || f->NumBonds != 3
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
return SZ_OK; return SZ_OK;
} }
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
static UInt64 GetSum(const UInt64 *values, UInt32 index)
{
UInt64 sum = 0;
UInt32 i;
for (i = 0; i < index; i++)
sum += values[i];
return sum;
}
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; #define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, static SRes SzFolder_Decode2(const CSzFolder *folder,
const Byte *propsData,
const UInt64 *unpackSizes,
const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
Byte *tempBuf[]) Byte *tempBuf[])
@@ -346,7 +367,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
for (ci = 0; ci < folder->NumCoders; ci++) for (ci = 0; ci < folder->NumCoders; ci++)
{ {
CSzCoderInfo *coder = &folder->Coders[ci]; const CSzCoderInfo *coder = &folder->Coders[ci];
if (IS_MAIN_METHOD((UInt32)coder->MethodID)) if (IS_MAIN_METHOD((UInt32)coder->MethodID))
{ {
@@ -358,7 +379,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
if (folder->NumCoders == 4) if (folder->NumCoders == 4)
{ {
UInt32 indices[] = { 3, 2, 0 }; UInt32 indices[] = { 3, 2, 0 };
UInt64 unpackSize = folder->UnpackSizes[ci]; UInt64 unpackSize = unpackSizes[ci];
si = indices[ci]; si = indices[ci];
if (ci < 2) if (ci < 2)
{ {
@@ -367,7 +388,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
if (outSizeCur != unpackSize) if (outSizeCur != unpackSize)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
if (temp == 0 && outSizeCur != 0) if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp; outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur; tempSizes[1 - ci] = outSizeCur;
@@ -382,8 +403,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
else else
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
offset = GetSum(packSizes, si); offset = packPositions[si];
inSize = packSizes[si]; inSize = packPositions[si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset)); RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy) if (coder->MethodID == k_Copy)
@@ -394,77 +415,155 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
} }
else if (coder->MethodID == k_LZMA) else if (coder->MethodID == k_LZMA)
{ {
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
} }
#ifndef _7Z_NO_METHOD_LZMA2
else if (coder->MethodID == k_LZMA2) else if (coder->MethodID == k_LZMA2)
{ {
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
} }
else #endif
#ifdef _7ZIP_PPMD_SUPPPORT
else if (coder->MethodID == k_PPMD)
{ {
#ifdef _7ZIP_PPMD_SUPPPORT RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
#else
return SZ_ERROR_UNSUPPORTED;
#endif
} }
#endif
else
return SZ_ERROR_UNSUPPORTED;
} }
else if (coder->MethodID == k_BCJ2) else if (coder->MethodID == k_BCJ2)
{ {
UInt64 offset = GetSum(packSizes, 1); UInt64 offset = packPositions[1];
UInt64 s3Size = packSizes[1]; UInt64 s3Size = packPositions[2] - offset;
SRes res;
if (ci != 3) if (ci != 3)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
tempSizes[2] = (SizeT)s3Size; tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size) if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
if (tempBuf[2] == 0 && tempSizes[2] != 0) if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
RINOK(res) RINOK(LookInStream_SeekTo(inStream, startPos + offset));
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
if ((tempSizes[0] & 3) != 0 ||
(tempSizes[1] & 3) != 0 ||
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
return SZ_ERROR_DATA;
res = Bcj2_Decode(
tempBuf3, tempSize3,
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1],
tempBuf[2], tempSizes[2],
outBuffer, outSize);
RINOK(res)
}
else
{
if (ci != 1)
return SZ_ERROR_UNSUPPORTED;
switch(coder->MethodID)
{ {
case k_BCJ: CBcj2Dec p;
p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
p.dest = outBuffer;
p.destLim = outBuffer + outSize;
Bcj2Dec_Init(&p);
RINOK(Bcj2Dec_Decode(&p));
{ {
UInt32 state; unsigned i;
x86_Convert_Init(state); for (i = 0; i < 4; i++)
x86_Convert(outBuffer, outSize, 0, &state, 0); if (p.bufs[i] != p.lims[i])
break; return SZ_ERROR_DATA;
if (!Bcj2Dec_IsFinished(&p))
return SZ_ERROR_DATA;
if (p.dest != p.destLim
|| p.state != BCJ2_STREAM_MAIN)
return SZ_ERROR_DATA;
} }
CASE_BRA_CONV(ARM)
default:
return SZ_ERROR_UNSUPPORTED;
} }
} }
#ifndef _7Z_NO_METHODS_FILTERS
else if (ci == 1)
{
if (coder->MethodID == k_Delta)
{
if (coder->PropsSize != 1)
return SZ_ERROR_UNSUPPORTED;
{
Byte state[DELTA_STATE_SIZE];
Delta_Init(state);
Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
}
else
{
if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
switch (coder->MethodID)
{
case k_BCJ:
{
UInt32 state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
}
CASE_BRA_CONV(PPC)
CASE_BRA_CONV(IA64)
CASE_BRA_CONV(SPARC)
CASE_BRA_CONV(ARM)
CASE_BRA_CONV(ARMT)
default:
return SZ_ERROR_UNSUPPORTED;
}
}
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
} }
return SZ_OK; return SZ_OK;
} }
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain)
{ {
Byte *tempBuf[3] = { 0, 0, 0}; SRes res;
int i; CSzFolder folder;
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, CSzData sd;
outBuffer, (SizeT)outSize, allocMain, tempBuf); CSzData sdSizes;
for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
return res; sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex];
sdSizes.Size =
p->FoSizesOffsets[folderIndex + 1] -
p->FoSizesOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd, &sdSizes);
if (res != SZ_OK)
return res;
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.UnpackStream])
return SZ_ERROR_FAIL;
{
unsigned i;
Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]);
return res;
}
} }

2
C/7zFile.c Executable file → Normal file
View File

@@ -1,6 +1,8 @@
/* 7zFile.c -- File IO /* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */ 2009-11-24 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "7zFile.h" #include "7zFile.h"
#ifndef USE_WINDOWS_FILE #ifndef USE_WINDOWS_FILE

4
C/7zFile.h Executable file → Normal file
View File

@@ -1,5 +1,5 @@
/* 7zFile.h -- File IO /* 7zFile.h -- File IO
2009-11-24 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H #ifndef __7Z_FILE_H
#define __7Z_FILE_H #define __7Z_FILE_H
@@ -14,7 +14,7 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN

1402
C/7zIn.c
View File

File diff suppressed because it is too large Load Diff

6
C/7zStream.c Executable file → Normal file
View File

@@ -1,9 +1,11 @@
/* 7zStream.c -- 7z Stream functions /* 7zStream.c -- 7z Stream functions
2010-03-11 : Igor Pavlov : Public domain */ 2013-11-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
#include "Types.h" #include "7zTypes.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{ {

14
C/Types.h → C/7zTypes.h Executable file → Normal file
View File

@@ -1,15 +1,15 @@
/* Types.h -- Basic types /* 7zTypes.h -- Basic types
2010-10-09 : Igor Pavlov : Public domain */ 2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
#include <stddef.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> /* #include <windows.h> */
#endif #endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN #ifndef EXTERN_C_BEGIN
#ifdef __cplusplus #ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" { #define EXTERN_C_BEGIN extern "C" {
@@ -43,7 +43,8 @@ EXTERN_C_BEGIN
typedef int SRes; typedef int SRes;
#ifdef _WIN32 #ifdef _WIN32
typedef DWORD WRes; /* typedef DWORD WRes; */
typedef unsigned WRes;
#else #else
typedef int WRes; typedef int WRes;
#endif #endif
@@ -116,6 +117,7 @@ typedef int Bool;
#else #else
#define MY_NO_INLINE
#define MY_CDECL #define MY_CDECL
#define MY_FAST_CALL #define MY_FAST_CALL

26
C/7zVersion.h Executable file → Normal file
View File

@@ -1,7 +1,19 @@
#define MY_VER_MAJOR 9 #define MY_VER_MAJOR 15
#define MY_VER_MINOR 21 #define MY_VER_MINOR 11
#define MY_VER_BUILD 00 #define MY_VER_BUILD 0
#define MY_VERSION "9.21 beta" #define MY_VERSION_NUMBERS "15.11"
#define MY_DATE "2011-04-11" #define MY_VERSION "15.11 beta"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_DATE "2015-11-14"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
#else
#define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE

55
C/7zVersion.rc Normal file
View File

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

31
C/Aes.c Executable file → Normal file
View File

@@ -1,11 +1,13 @@
/* Aes.c -- AES encryption / decryption /* Aes.c -- AES encryption / decryption
2009-11-23 : Igor Pavlov : Public domain */ 2015-02-23 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Aes.h" #include "Aes.h"
#include "CpuArch.h" #include "CpuArch.h"
static UInt32 T[256 * 4]; static UInt32 T[256 * 4];
static Byte Sbox[256] = { static const Byte Sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
@@ -38,7 +40,7 @@ AES_CODE_FUNC g_AesCtr_Code;
static UInt32 D[256 * 4]; static UInt32 D[256 * 4];
static Byte InvS[256]; static Byte InvS[256];
static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) #define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
@@ -54,6 +56,7 @@ void AesGenTables(void)
unsigned i; unsigned i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
InvS[Sbox[i]] = (Byte)i; InvS[Sbox[i]] = (Byte)i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
{ {
@@ -80,9 +83,11 @@ void AesGenTables(void)
D[0x300 + i] = Ui32(a9, aD, aB, aE); D[0x300 + i] = Ui32(a9, aD, aB, aE);
} }
} }
g_AesCbc_Encode = AesCbc_Encode; g_AesCbc_Encode = AesCbc_Encode;
g_AesCbc_Decode = AesCbc_Decode; g_AesCbc_Decode = AesCbc_Decode;
g_AesCtr_Code = AesCtr_Code; g_AesCtr_Code = AesCtr_Code;
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported()) if (CPU_Is_Aes_Supported())
{ {
@@ -93,34 +98,38 @@ void AesGenTables(void)
#endif #endif
} }
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])] #define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
#define HT4(m, i, s, p) m[i] = \ #define HT4(m, i, s, p) m[i] = \
HT(i, 0, s) ^ \ HT(i, 0, s) ^ \
HT(i, 1, s) ^ \ HT(i, 1, s) ^ \
HT(i, 2, s) ^ \ HT(i, 2, s) ^ \
HT(i, 3, s) ^ w[p + i] HT(i, 3, s) ^ w[p + i]
/* such order (2031) in HT16 is for VC6/K8 speed optimization) */
#define HT16(m, s, p) \ #define HT16(m, s, p) \
HT4(m, 2, s, p); \
HT4(m, 0, s, p); \ HT4(m, 0, s, p); \
HT4(m, 3, s, p); \
HT4(m, 1, s, p); \ HT4(m, 1, s, p); \
HT4(m, 2, s, p); \
HT4(m, 3, s, p); \
#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])] #define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])]
#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; #define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])] #define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
#define HD4(m, i, s, p) m[i] = \ #define HD4(m, i, s, p) m[i] = \
HD(i, 0, s) ^ \ HD(i, 0, s) ^ \
HD(i, 1, s) ^ \ HD(i, 1, s) ^ \
HD(i, 2, s) ^ \ HD(i, 2, s) ^ \
HD(i, 3, s) ^ w[p + i]; HD(i, 3, s) ^ w[p + i];
/* such order (0231) in HD16 is for VC6/K8 speed optimization) */
#define HD16(m, s, p) \ #define HD16(m, s, p) \
HD4(m, 0, s, p); \ HD4(m, 0, s, p); \
HD4(m, 1, s, p); \
HD4(m, 2, s, p); \ HD4(m, 2, s, p); \
HD4(m, 3, s, p); \ HD4(m, 3, s, p); \
HD4(m, 1, s, p); \
#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])] #define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; #define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
@@ -167,7 +176,7 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
/* Aes_Encode and Aes_Decode functions work with little-endian words. /* Aes_Encode and Aes_Decode functions work with little-endian words.
src and dest are pointers to 4 UInt32 words. src and dest are pointers to 4 UInt32 words.
arc and dest can point to same block */ src and dest can point to same block */
static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
{ {
@@ -269,13 +278,17 @@ void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
UInt32 temp[4]; UInt32 temp[4];
Byte buf[16]; Byte buf[16];
int i; int i;
if (++p[0] == 0) if (++p[0] == 0)
p[1]++; p[1]++;
Aes_Encode(p + 4, temp, p); Aes_Encode(p + 4, temp, p);
SetUi32(buf, temp[0]); SetUi32(buf, temp[0]);
SetUi32(buf + 4, temp[1]); SetUi32(buf + 4, temp[1]);
SetUi32(buf + 8, temp[2]); SetUi32(buf + 8, temp[2]);
SetUi32(buf + 12, temp[3]); SetUi32(buf + 12, temp[3]);
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
*data++ ^= buf[i]; *data++ ^= buf[i];
} }

4
C/Aes.h Executable file → Normal file
View File

@@ -1,10 +1,10 @@
/* Aes.h -- AES encryption / decryption /* Aes.h -- AES encryption / decryption
2009-11-23 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __AES_H #ifndef __AES_H
#define __AES_H #define __AES_H
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN

4
C/AesOpt.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* AesOpt.c -- Intel's AES /* AesOpt.c -- Intel's AES
2009-11-23 : Igor Pavlov : Public domain */ 2013-11-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"

15
C/Alloc.c Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/* Alloc.c -- Memory allocation functions /* Alloc.c -- Memory allocation functions
2008-09-24 2015-02-21 : Igor Pavlov : Public domain */
Igor Pavlov
Public domain */ #include "Precomp.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@@ -125,3 +125,12 @@ void BigFree(void *address)
} }
#endif #endif
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };

15
C/Alloc.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* Alloc.h -- Memory allocation functions /* Alloc.h -- Memory allocation functions
2009-02-07 : Igor Pavlov : Public domain */ 2015-02-21 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H #ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H #define __COMMON_ALLOC_H
#include <stddef.h> #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
void *MyAlloc(size_t size); void *MyAlloc(size_t size);
void MyFree(void *address); void MyFree(void *address);
@@ -31,8 +29,9 @@ void BigFree(void *address);
#endif #endif
#ifdef __cplusplus extern ISzAlloc g_Alloc;
} extern ISzAlloc g_BigAlloc;
#endif
EXTERN_C_END
#endif #endif

334
C/Bcj2.c Executable file → Normal file
View File

@@ -1,132 +1,256 @@
/* Bcj2.c -- Converter for x86 code (BCJ2) /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2008-10-04 : Igor Pavlov : Public domain */ 2015-08-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "CpuArch.h"
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16 #define CProb UInt16
#endif
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) #define kTopValue ((UInt32)1 << 24)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) #define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits)
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5 #define kNumMoveBits 5
#define RC_READ_BYTE (*buffer++) #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } void Bcj2Dec_Init(CBcj2Dec *p)
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
int Bcj2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize)
{ {
CProb p[256 + 2]; unsigned i;
SizeT inPos = 0, outPos = 0;
const Byte *buffer, *bufferLim; p->state = BCJ2_DEC_STATE_OK;
UInt32 range, code; p->ip = 0;
Byte prevByte = 0; p->temp[3] = 0;
p->range = 0;
p->code = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1;
}
unsigned int i; SRes Bcj2Dec_Decode(CBcj2Dec *p)
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) {
p[i] = kBitModelTotal >> 1; if (p->range <= 5)
{
p->state = BCJ2_DEC_STATE_OK;
for (; p->range != 5; p->range++)
{
if (p->range == 1 && p->code != 0)
return SZ_ERROR_DATA;
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
buffer = buf3; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
bufferLim = buffer + size3; }
RC_INIT2
if (p->code == 0xFFFFFFFF)
return SZ_ERROR_DATA;
p->range = 0xFFFFFFFF;
}
else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{
while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{
Byte *dest = p->dest;
if (dest == p->destLim)
return SZ_OK;
*dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
p->dest = dest + 1;
}
}
if (outSize == 0) /*
return SZ_OK; if (BCJ2_IS_32BIT_STREAM(p->state))
{
const Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state])
return SZ_OK;
p->bufs[p->state] = cur + 4;
{
UInt32 val;
Byte *dest;
SizeT rem;
p->ip += 4;
val = GetBe32(cur) - p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
return SZ_OK;
}
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
p->state = BCJ2_DEC_STATE_OK;
}
}
*/
for (;;) for (;;)
{ {
Byte b; if (BCJ2_IS_32BIT_STREAM(p->state))
CProb *prob; p->state = BCJ2_DEC_STATE_OK;
UInt32 bound;
UInt32 ttt;
SizeT limit = size0 - inPos;
if (outSize - outPos < limit)
limit = outSize - outPos;
while (limit != 0)
{
Byte b = buf0[inPos];
outBuf[outPos++] = b;
if (IsJ(prevByte, b))
break;
inPos++;
prevByte = b;
limit--;
}
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevByte;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
IF_BIT_0(prob)
{
UPDATE_0(prob)
prevByte = b;
}
else else
{ {
UInt32 dest; if (p->range < kTopValue)
const Byte *v;
UPDATE_1(prob)
if (b == 0xE8)
{ {
v = buf1; if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
if (size1 < 4) {
return SZ_ERROR_DATA; p->state = BCJ2_STREAM_RC;
buf1 += 4; return SZ_OK;
size1 -= 4; }
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
} }
else
{ {
v = buf2; const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
if (size2 < 4) const Byte *srcLim;
return SZ_ERROR_DATA; Byte *dest;
buf2 += 4; SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
size2 -= 4;
if (num == 0)
{
p->state = BCJ2_STREAM_MAIN;
return SZ_OK;
}
dest = p->dest;
if (num > (SizeT)(p->destLim - dest))
{
num = p->destLim - dest;
if (num == 0)
{
p->state = BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
}
srcLim = src + num;
if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0];
else for (;;)
{
Byte b = *src;
*dest = b;
if (b != 0x0F)
{
if ((b & 0xFE) == 0xE8)
break;
dest++;
if (++src != srcLim)
continue;
break;
}
dest++;
if (++src == srcLim)
break;
if ((*src & 0xF0) != 0x80)
continue;
*dest = *src;
break;
}
num = src - p->bufs[BCJ2_STREAM_MAIN];
if (src == srcLim)
{
p->temp[3] = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = src;
p->ip += (UInt32)num;
p->dest += num;
p->state =
p->bufs[BCJ2_STREAM_MAIN] ==
p->lims[BCJ2_STREAM_MAIN] ?
(unsigned)BCJ2_STREAM_MAIN :
(unsigned)BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
{
UInt32 bound, ttt;
CProb *prob;
Byte b = src[0];
Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
p->temp[3] = b;
p->bufs[BCJ2_STREAM_MAIN] = src + 1;
num++;
p->ip += (UInt32)num;
p->dest += num;
prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
_IF_BIT_0
{
_UPDATE_0
continue;
}
_UPDATE_1
}
} }
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | }
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest; {
if (outPos == outSize) UInt32 val;
unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
const Byte *cur = p->bufs[cj];
Byte *dest;
SizeT rem;
if (cur == p->lims[cj])
{
p->state = cj;
break; break;
outBuf[outPos++] = (Byte)(dest >> 8); }
if (outPos == outSize)
val = GetBe32(cur);
p->bufs[cj] = cur + 4;
p->ip += 4;
val -= p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break; break;
outBuf[outPos++] = (Byte)(dest >> 16); }
if (outPos == outSize)
break; SetUi32(dest, val);
outBuf[outPos++] = prevByte = (Byte)(dest >> 24); p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
} }
} }
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
{
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
return SZ_OK;
} }

160
C/Bcj2.h Executable file → Normal file
View File

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

312
C/Bcj2Enc.c Normal file
View File

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

48
C/Blake2.h Normal file
View File

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

244
C/Blake2s.c Normal file
View File

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

2
C/Bra.c Executable file → Normal file
View File

@@ -1,6 +1,8 @@
/* Bra.c -- Converters for RISC code /* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */ 2010-04-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bra.h" #include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)

12
C/Bra.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* Bra.h -- Branch converters for executables /* Bra.h -- Branch converters for executables
2009-02-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BRA_H #ifndef __BRA_H
#define __BRA_H #define __BRA_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
/* /*
These functions convert relative addresses to absolute addresses These functions convert relative addresses to absolute addresses
@@ -61,8 +59,6 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

99
C/Bra86.c Executable file → Normal file
View File

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

4
C/BraIA64.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* BraIA64.c -- Converter for IA-64 code /* BraIA64.c -- Converter for IA-64 code
2008-10-04 : Igor Pavlov : Public domain */ 2013-11-12 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bra.h" #include "Bra.h"

7
C/BwtSort.c Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/* BwtSort.c -- BWT block sorting /* BwtSort.c -- BWT block sorting
2008-08-17 2013-11-12 : Igor Pavlov : Public domain */
Igor Pavlov
Public domain */ #include "Precomp.h"
#include "BwtSort.h" #include "BwtSort.h"
#include "Sort.h" #include "Sort.h"
@@ -513,4 +513,3 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
#endif #endif
return Groups[0]; return Groups[0];
} }

12
C/BwtSort.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* BwtSort.h -- BWT block sorting /* BwtSort.h -- BWT block sorting
2009-02-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BWT_SORT_H #ifndef __BWT_SORT_H
#define __BWT_SORT_H #define __BWT_SORT_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */ /* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */
/* #define BLOCK_SORT_EXTERNAL_FLAGS */ /* #define BLOCK_SORT_EXTERNAL_FLAGS */
@@ -23,8 +21,6 @@ extern "C" {
UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize); UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

32
C/Compiler.h Normal file
View File

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

37
C/CpuArch.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2010-10-26: Igor Pavlov : Public domain */ 2015-03-25: Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
@@ -9,6 +11,10 @@
#define USE_ASM #define USE_ASM
#endif #endif
#if !defined(USE_ASM) && _MSC_VER >= 1500
#include <intrin.h>
#endif
#if defined(USE_ASM) && !defined(MY_CPU_AMD64) #if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag) static UInt32 CheckFlag(UInt32 flag)
{ {
@@ -48,7 +54,7 @@ static UInt32 CheckFlag(UInt32 flag)
#define CHECK_CPUID_IS_SUPPORTED #define CHECK_CPUID_IS_SUPPORTED
#endif #endif
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{ {
#ifdef USE_ASM #ifdef USE_ASM
@@ -73,9 +79,17 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
#if defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;"
"cpuid;"
"xchgl %%ebx, %%edi;"
: "=a" (*a) ,
"=D" (*b) ,
#else
"cpuid" "cpuid"
: "=a" (*a) , : "=a" (*a) ,
"=b" (*b) , "=b" (*b) ,
#endif
"=c" (*c) , "=c" (*c) ,
"=d" (*d) "=d" (*d)
: "0" (function)) ; : "0" (function)) ;
@@ -102,7 +116,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
return True; return True;
} }
static UInt32 kVendors[][3] = static const UInt32 kVendors[][3] =
{ {
{ 0x756E6547, 0x49656E69, 0x6C65746E}, { 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163}, { 0x68747541, 0x69746E65, 0x444D4163},
@@ -130,12 +144,22 @@ Bool CPU_Is_InOrder()
UInt32 family, model; UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p)) if (!x86cpuid_CheckAndRead(&p))
return True; return True;
family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p); family = x86cpuid_GetFamily(p.ver);
model = x86cpuid_GetModel(p.ver);
firm = x86cpuid_GetFirm(&p); firm = x86cpuid_GetFirm(&p);
switch (firm) switch (firm)
{ {
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C)); case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* In-Order Atom CPU */
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x26 /* 45 nm, Z6xx */
|| model == 0x27 /* 32 nm, Z2460 */
|| model == 0x35 /* 32 nm, Z2760 */
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
)));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
} }
@@ -143,6 +167,7 @@ Bool CPU_Is_InOrder()
} }
#if !defined(MY_CPU_AMD64) && defined(_WIN32) #if !defined(MY_CPU_AMD64) && defined(_WIN32)
#include <windows.h>
static Bool CPU_Sys_Is_SSE_Supported() static Bool CPU_Sys_Is_SSE_Supported()
{ {
OSVERSIONINFO vi; OSVERSIONINFO vi;

147
C/CpuArch.h Executable file → Normal file
View File

@@ -1,27 +1,34 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2010-12-01: Igor Pavlov : Public domain */ 2015-10-31: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
/* /*
MY_CPU_LE means that CPU is LITTLE ENDIAN. MY_CPU_LE means that CPU is LITTLE ENDIAN.
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN). MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
*/ */
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) #if defined(_M_X64) \
#define MY_CPU_AMD64 || defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64
#endif #endif
#if defined(MY_CPU_AMD64) || defined(_M_IA64) #if defined(MY_CPU_AMD64) \
#define MY_CPU_64BIT || defined(_M_IA64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__)
#define MY_CPU_64BIT
#endif #endif
#if defined(_M_IX86) || defined(__i386__) #if defined(_M_IX86) || defined(__i386__)
@@ -32,8 +39,13 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_X86_OR_AMD64 #define MY_CPU_X86_OR_AMD64
#endif #endif
#if defined(MY_CPU_X86) || defined(_M_ARM) #if defined(MY_CPU_X86) \
#define MY_CPU_32BIT || defined(_M_ARM) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__)
#define MY_CPU_32BIT
#endif #endif
#if defined(_WIN32) && defined(_M_ARM) #if defined(_WIN32) && defined(_M_ARM)
@@ -44,34 +56,61 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_IA64_LE #define MY_CPU_IA64_LE
#endif #endif
#if defined(MY_CPU_X86_OR_AMD64) #if defined(MY_CPU_X86_OR_AMD64) \
#define MY_CPU_LE_UNALIGN || defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE
#endif #endif
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) #if defined(__BIG_ENDIAN__) \
#define MY_CPU_LE || defined(__ARMEB__) \
#endif || defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) || defined(__MIPSEB__) \
#define MY_CPU_BE || defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390x__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif #endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE) #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian Stop_Compiling_Bad_Endian
#endif #endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
/* || defined(__AARCH64EL__) */
#define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(p)) #define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(p)) #define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(p)) #define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d); #define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
#define SetUi64(p, d) *(UInt64 *)(p) = (d); #define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#else #else
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) #define GetUi16(p) ( (UInt16) ( \
((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \ #define GetUi32(p) ( \
((const Byte *)(p))[0] | \ ((const Byte *)(p))[0] | \
@@ -81,29 +120,43 @@ Stop_Compiling_Bad_Endian
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi16(p, d) { UInt32 _x_ = (d); \ #define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
((Byte *)(p))[0] = (Byte)_x_; \ _ppp_[0] = (Byte)_vvv_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); } _ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, d) { UInt32 _x_ = (d); \ #define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
((Byte *)(p))[0] = (Byte)_x_; \ _ppp_[0] = (Byte)_vvv_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ _ppp_[1] = (Byte)(_vvv_ >> 8); \
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ _ppp_[2] = (Byte)(_vvv_ >> 16); \
((Byte *)(p))[3] = (Byte)(_x_ >> 24); } _ppp_[3] = (Byte)(_vvv_ >> 24); }
#define SetUi64(p, d) { UInt64 _x64_ = (d); \ #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(p, (UInt32)_x64_); \ SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif #endif
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h>
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64) #pragma intrinsic(_byteswap_uint64)
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
#else #else
#define GetBe32(p) ( \ #define GetBe32(p) ( \
@@ -114,9 +167,19 @@ Stop_Compiling_Bad_Endian
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; }
#endif #endif
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
@@ -138,12 +201,14 @@ enum
CPU_FIRM_VIA CPU_FIRM_VIA
}; };
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
Bool x86cpuid_CheckAndRead(Cx86cpuid *p); Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p); int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) #define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) #define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF) #define x86cpuid_GetStepping(ver) (ver & 0xF)
Bool CPU_Is_InOrder(); Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported(); Bool CPU_Is_Aes_Supported();

2
C/Delta.c Executable file → Normal file
View File

@@ -1,6 +1,8 @@
/* Delta.c -- Delta converter /* Delta.c -- Delta converter
2009-05-26 : Igor Pavlov : Public domain */ 2009-05-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Delta.h" #include "Delta.h"
void Delta_Init(Byte *state) void Delta_Init(Byte *state)

12
C/Delta.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* Delta.h -- Delta converter /* Delta.h -- Delta converter
2009-04-15 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __DELTA_H #ifndef __DELTA_H
#define __DELTA_H #define __DELTA_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
#define DELTA_STATE_SIZE 256 #define DELTA_STATE_SIZE 256
@@ -16,8 +14,6 @@ void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size); void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size); void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

2
C/HuffEnc.c Executable file → Normal file
View File

@@ -1,6 +1,8 @@
/* HuffEnc.c -- functions for Huffman encoding /* HuffEnc.c -- functions for Huffman encoding
2009-09-02 : Igor Pavlov : Public domain */ 2009-09-02 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "HuffEnc.h" #include "HuffEnc.h"
#include "Sort.h" #include "Sort.h"

12
C/HuffEnc.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* HuffEnc.h -- Huffman encoding /* HuffEnc.h -- Huffman encoding
2009-02-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __HUFF_ENC_H #ifndef __HUFF_ENC_H
#define __HUFF_ENC_H #define __HUFF_ENC_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
/* /*
Conditions: Conditions:
@@ -20,8 +18,6 @@ Conditions:
void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen); void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

499
C/LzFind.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* LzFind.c -- Match finder for LZ algorithms /* LzFind.c -- Match finder for LZ algorithms
2009-04-22 : Igor Pavlov : Public domain */ 2015-10-15 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -9,8 +11,8 @@
#define kEmptyHashValue 0 #define kEmptyHashValue 0
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) #define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ #define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
#define kNormalizeMask (~(kNormalizeStepMin - 1)) #define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
#define kMaxHistorySize ((UInt32)3 << 30) #define kMaxHistorySize ((UInt32)7 << 29)
#define kStartMaxLen 3 #define kStartMaxLen 3
@@ -19,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
if (!p->directInput) if (!p->directInput)
{ {
alloc->Free(alloc, p->bufferBase); alloc->Free(alloc, p->bufferBase);
p->bufferBase = 0; p->bufferBase = NULL;
} }
} }
@@ -33,17 +35,16 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
p->blockSize = blockSize; p->blockSize = blockSize;
return 1; return 1;
} }
if (p->bufferBase == 0 || p->blockSize != blockSize) if (!p->bufferBase || p->blockSize != blockSize)
{ {
LzInWindow_Free(p, alloc); LzInWindow_Free(p, alloc);
p->blockSize = blockSize; p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
} }
return (p->bufferBase != 0); return (p->bufferBase != NULL);
} }
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
@@ -58,9 +59,12 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
{ {
if (p->streamEndWasReached || p->result != SZ_OK) if (p->streamEndWasReached || p->result != SZ_OK)
return; return;
/* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
if (p->directInput) if (p->directInput)
{ {
UInt32 curSize = 0xFFFFFFFF - p->streamPos; UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
if (curSize > p->directInputRem) if (curSize > p->directInputRem)
curSize = (UInt32)p->directInputRem; curSize = (UInt32)p->directInputRem;
p->directInputRem -= curSize; p->directInputRem -= curSize;
@@ -69,12 +73,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
p->streamEndWasReached = 1; p->streamEndWasReached = 1;
return; return;
} }
for (;;) for (;;)
{ {
Byte *dest = p->buffer + (p->streamPos - p->pos); Byte *dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest); size_t size = (p->bufferBase + p->blockSize - dest);
if (size == 0) if (size == 0)
return; return;
p->result = p->stream->Read(p->stream, dest, &size); p->result = p->stream->Read(p->stream, dest, &size);
if (p->result != SZ_OK) if (p->result != SZ_OK)
return; return;
@@ -92,8 +98,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
void MatchFinder_MoveBlock(CMatchFinder *p) void MatchFinder_MoveBlock(CMatchFinder *p)
{ {
memmove(p->bufferBase, memmove(p->bufferBase,
p->buffer - p->keepSizeBefore, p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore)); (size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
p->buffer = p->bufferBase + p->keepSizeBefore; p->buffer = p->bufferBase + p->keepSizeBefore;
} }
@@ -133,15 +139,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
void MatchFinder_Construct(CMatchFinder *p) void MatchFinder_Construct(CMatchFinder *p)
{ {
UInt32 i; UInt32 i;
p->bufferBase = 0; p->bufferBase = NULL;
p->directInput = 0; p->directInput = 0;
p->hash = 0; p->hash = NULL;
MatchFinder_SetDefaultSettings(p); MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
UInt32 r = i; UInt32 r = i;
int j; unsigned j;
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r; p->crc[i] = r;
@@ -151,7 +157,7 @@ void MatchFinder_Construct(CMatchFinder *p)
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->hash); alloc->Free(alloc, p->hash);
p->hash = 0; p->hash = NULL;
} }
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
@@ -160,11 +166,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
LzInWindow_Free(p, alloc); LzInWindow_Free(p, alloc);
} }
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
{ {
size_t sizeInBytes = (size_t)num * sizeof(CLzRef); size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num) if (sizeInBytes / sizeof(CLzRef) != num)
return 0; return NULL;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
} }
@@ -173,19 +179,24 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
ISzAlloc *alloc) ISzAlloc *alloc)
{ {
UInt32 sizeReserv; UInt32 sizeReserv;
if (historySize > kMaxHistorySize) if (historySize > kMaxHistorySize)
{ {
MatchFinder_Free(p, alloc); MatchFinder_Free(p, alloc);
return 0; return 0;
} }
sizeReserv = historySize >> 1; sizeReserv = historySize >> 1;
if (historySize > ((UInt32)2 << 30)) if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
sizeReserv = historySize >> 2; else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1; p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
if (LzInWindow_Create(p, sizeReserv, alloc)) if (LzInWindow_Create(p, sizeReserv, alloc))
{ {
UInt32 newCyclicBufferSize = historySize + 1; UInt32 newCyclicBufferSize = historySize + 1;
@@ -210,6 +221,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
hs = (1 << 24) - 1; hs = (1 << 24) - 1;
else else
hs >>= 1; hs >>= 1;
/* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
} }
} }
p->hashMask = hs; p->hashMask = hs;
@@ -221,24 +233,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
} }
{ {
UInt32 prevSize = p->hashSizeSum + p->numSons; size_t newSize;
UInt32 newSize; size_t numSons;
p->historySize = historySize; p->historySize = historySize;
p->hashSizeSum = hs; p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize; p->cyclicBufferSize = newCyclicBufferSize;
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
newSize = p->hashSizeSum + p->numSons; numSons = newCyclicBufferSize;
if (p->hash != 0 && prevSize == newSize) if (p->btMode)
numSons <<= 1;
newSize = hs + numSons;
if (p->hash && p->numRefs == newSize)
return 1; return 1;
MatchFinder_FreeThisClassMemory(p, alloc); MatchFinder_FreeThisClassMemory(p, alloc);
p->numRefs = newSize;
p->hash = AllocRefs(newSize, alloc); p->hash = AllocRefs(newSize, alloc);
if (p->hash != 0)
if (p->hash)
{ {
p->son = p->hash + p->hashSizeSum; p->son = p->hash + p->hashSizeSum;
return 1; return 1;
} }
} }
} }
MatchFinder_Free(p, alloc); MatchFinder_Free(p, alloc);
return 0; return 0;
} }
@@ -247,9 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
{ {
UInt32 limit = kMaxValForNormalize - p->pos; UInt32 limit = kMaxValForNormalize - p->pos;
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
if (limit2 < limit) if (limit2 < limit)
limit = limit2; limit = limit2;
limit2 = p->streamPos - p->pos; limit2 = p->streamPos - p->pos;
if (limit2 <= p->keepSizeAfter) if (limit2 <= p->keepSizeAfter)
{ {
if (limit2 > 0) if (limit2 > 0)
@@ -257,8 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
} }
else else
limit2 -= p->keepSizeAfter; limit2 -= p->keepSizeAfter;
if (limit2 < limit) if (limit2 < limit)
limit = limit2; limit = limit2;
{ {
UInt32 lenLimit = p->streamPos - p->pos; UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen) if (lenLimit > p->matchMaxLen)
@@ -268,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
p->posLimit = p->pos + limit; p->posLimit = p->pos + limit;
} }
void MatchFinder_Init(CMatchFinder *p) void MatchFinder_Init_2(CMatchFinder *p, int readData)
{ {
UInt32 i; UInt32 i;
for (i = 0; i < p->hashSizeSum; i++) UInt32 *hash = p->hash;
p->hash[i] = kEmptyHashValue; UInt32 num = p->hashSizeSum;
for (i = 0; i < num; i++)
hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0; p->cyclicBufferPos = 0;
p->buffer = p->bufferBase; p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize; p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK; p->result = SZ_OK;
p->streamEndWasReached = 0; p->streamEndWasReached = 0;
MatchFinder_ReadBlock(p);
if (readData)
MatchFinder_ReadBlock(p);
MatchFinder_SetLimits(p); MatchFinder_SetLimits(p);
} }
void MatchFinder_Init(CMatchFinder *p)
{
MatchFinder_Init_2(p, True);
}
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{ {
return (p->pos - p->historySize - 1) & kNormalizeMask; return (p->pos - p->historySize - 1) & kNormalizeMask;
} }
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems)
{ {
UInt32 i; size_t i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{ {
UInt32 value = items[i]; UInt32 value = items[i];
@@ -304,7 +339,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
static void MatchFinder_Normalize(CMatchFinder *p) static void MatchFinder_Normalize(CMatchFinder *p)
{ {
UInt32 subValue = MatchFinder_GetSubValue(p); UInt32 subValue = MatchFinder_GetSubValue(p);
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); MatchFinder_Normalize3(subValue, p->hash, p->numRefs);
MatchFinder_ReduceOffsets(p, subValue); MatchFinder_ReduceOffsets(p, subValue);
} }
@@ -465,7 +500,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \ #define GET_MATCHES_HEADER2(minLen, ret_op) \
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
cur = p->buffer; cur = p->buffer;
@@ -481,13 +516,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define SKIP_FOOTER \ #define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
#define UPDATE_maxLen { \
ptrdiff_t diff = (ptrdiff_t)0 - d2; \
const Byte *c = cur + maxLen; \
const Byte *lim = cur + lenLimit; \
for (; c != lim; c++) if (*(c + diff) != *c) break; \
maxLen = (UInt32)(c - cur); }
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{ {
UInt32 offset; UInt32 offset;
GET_MATCHES_HEADER(2) GET_MATCHES_HEADER(2)
HASH2_CALC; HASH2_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hv];
p->hash[hashValue] = p->pos; p->hash[hv] = p->pos;
offset = 0; offset = 0;
GET_MATCHES_FOOTER(offset, 1) GET_MATCHES_FOOTER(offset, 1)
} }
@@ -497,35 +539,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
UInt32 offset; UInt32 offset;
GET_MATCHES_HEADER(3) GET_MATCHES_HEADER(3)
HASH_ZIP_CALC; HASH_ZIP_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hv];
p->hash[hashValue] = p->pos; p->hash[hv] = p->pos;
offset = 0; offset = 0;
GET_MATCHES_FOOTER(offset, 2) GET_MATCHES_FOOTER(offset, 2)
} }
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{ {
UInt32 hash2Value, delta2, maxLen, offset; UInt32 h2, d2, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(3) GET_MATCHES_HEADER(3)
HASH3_CALC; HASH3_CALC;
delta2 = p->pos - p->hash[hash2Value]; hash = p->hash;
curMatch = p->hash[kFix3HashSize + hashValue]; pos = p->pos;
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
d2 = pos - hash[h2];
curMatch = hash[kFix3HashSize + hv];
hash[h2] = pos;
hash[kFix3HashSize + hv] = pos;
maxLen = 2; maxLen = 2;
offset = 0; offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{ {
for (; maxLen != lenLimit; maxLen++) UPDATE_maxLen
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[0] = maxLen; distances[0] = maxLen;
distances[1] = delta2 - 1; distances[1] = d2 - 1;
offset = 2; offset = 2;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
@@ -533,44 +578,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET; MOVE_POS_RET;
} }
} }
GET_MATCHES_FOOTER(offset, maxLen) GET_MATCHES_FOOTER(offset, maxLen)
} }
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{ {
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; UInt32 h2, h3, d2, d3, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(4) GET_MATCHES_HEADER(4)
HASH4_CALC; HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value]; hash = p->hash;
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; pos = p->pos;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
maxLen = 1; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
curMatch = hash[kFix4HashSize + hv];
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + hv] = pos;
maxLen = 0;
offset = 0; offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{ {
distances[0] = maxLen = 2; distances[0] = maxLen = 2;
distances[1] = delta2 - 1; distances[1] = d2 - 1;
offset = 2; offset = 2;
} }
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{ {
maxLen = 3; maxLen = 3;
distances[offset + 1] = delta3 - 1; distances[offset + 1] = d3 - 1;
offset += 2; offset += 2;
delta2 = delta3; d2 = d3;
} }
if (offset != 0) if (offset != 0)
{ {
for (; maxLen != lenLimit; maxLen++) UPDATE_maxLen
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[offset - 2] = maxLen; distances[offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
@@ -578,46 +630,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET; MOVE_POS_RET;
} }
} }
if (maxLen < 3) if (maxLen < 3)
maxLen = 3; maxLen = 3;
GET_MATCHES_FOOTER(offset, maxLen) GET_MATCHES_FOOTER(offset, maxLen)
} }
/*
static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(5)
HASH5_CALC;
hash = p->hash;
pos = p->pos;
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
d4 = pos - hash[kFix4HashSize + h4];
curMatch = hash[kFix5HashSize + hv];
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + h4] = pos;
hash[kFix5HashSize + hv] = pos;
maxLen = 0;
offset = 0;
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = d2 - 1;
offset = 2;
if (*(cur - d2 + 2) == cur[2])
distances[0] = maxLen = 3;
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[2] = maxLen = 3;
distances[3] = d3 - 1;
offset = 4;
d2 = d3;
}
}
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[0] = maxLen = 3;
distances[1] = d3 - 1;
offset = 2;
d2 = d3;
}
if (d2 != d4 && d4 < p->cyclicBufferSize
&& *(cur - d4) == *cur
&& *(cur - d4 + 3) == *(cur + 3))
{
maxLen = 4;
distances[offset + 1] = d4 - 1;
offset += 2;
d2 = d4;
}
if (offset != 0)
{
UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
MOVE_POS_RET;
}
}
if (maxLen < 4)
maxLen = 4;
GET_MATCHES_FOOTER(offset, maxLen)
}
*/
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{ {
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; UInt32 h2, h3, d2, d3, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(4) GET_MATCHES_HEADER(4)
HASH4_CALC; HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value]; hash = p->hash;
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; pos = p->pos;
curMatch = p->hash[kFix4HashSize + hashValue];
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
curMatch = hash[kFix4HashSize + hv];
p->hash[ hash2Value] = hash[ h2] = pos;
p->hash[kFix3HashSize + hash3Value] = hash[kFix3HashSize + h3] = pos;
p->hash[kFix4HashSize + hashValue] = p->pos; hash[kFix4HashSize + hv] = pos;
maxLen = 1; maxLen = 0;
offset = 0; offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{ {
distances[0] = maxLen = 2; distances[0] = maxLen = 2;
distances[1] = delta2 - 1; distances[1] = d2 - 1;
offset = 2; offset = 2;
} }
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{ {
maxLen = 3; maxLen = 3;
distances[offset + 1] = delta3 - 1; distances[offset + 1] = d3 - 1;
offset += 2; offset += 2;
delta2 = delta3; d2 = d3;
} }
if (offset != 0) if (offset != 0)
{ {
for (; maxLen != lenLimit; maxLen++) UPDATE_maxLen
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[offset - 2] = maxLen; distances[offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
@@ -625,22 +762,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET; MOVE_POS_RET;
} }
} }
if (maxLen < 3) if (maxLen < 3)
maxLen = 3; maxLen = 3;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances)); distances + offset, maxLen) - (distances));
MOVE_POS_RET MOVE_POS_RET
} }
/*
static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos
UInt32 *hash;
GET_MATCHES_HEADER(5)
HASH5_CALC;
hash = p->hash;
pos = p->pos;
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
d4 = pos - hash[kFix4HashSize + h4];
curMatch = hash[kFix5HashSize + hv];
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + h4] = pos;
hash[kFix5HashSize + hv] = pos;
maxLen = 0;
offset = 0;
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = d2 - 1;
offset = 2;
if (*(cur - d2 + 2) == cur[2])
distances[0] = maxLen = 3;
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[2] = maxLen = 3;
distances[3] = d3 - 1;
offset = 4;
d2 = d3;
}
}
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[0] = maxLen = 3;
distances[1] = d3 - 1;
offset = 2;
d2 = d3;
}
if (d2 != d4 && d4 < p->cyclicBufferSize
&& *(cur - d4) == *cur
&& *(cur - d4 + 3) == *(cur + 3))
{
maxLen = 4;
distances[offset + 1] = d4 - 1;
offset += 2;
d2 = d4;
}
if (offset != 0)
{
UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS_RET;
}
}
if (maxLen < 4)
maxLen = 4;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
*/
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{ {
UInt32 offset; UInt32 offset;
GET_MATCHES_HEADER(3) GET_MATCHES_HEADER(3)
HASH_ZIP_CALC; HASH_ZIP_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hv];
p->hash[hashValue] = p->pos; p->hash[hv] = p->pos;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances, 2) - (distances)); distances, 2) - (distances));
MOVE_POS_RET MOVE_POS_RET
} }
@@ -650,8 +868,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{ {
SKIP_HEADER(2) SKIP_HEADER(2)
HASH2_CALC; HASH2_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hv];
p->hash[hashValue] = p->pos; p->hash[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@@ -663,8 +881,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{ {
SKIP_HEADER(3) SKIP_HEADER(3)
HASH_ZIP_CALC; HASH_ZIP_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hv];
p->hash[hashValue] = p->pos; p->hash[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@@ -674,12 +892,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{ {
do do
{ {
UInt32 hash2Value; UInt32 h2;
UInt32 *hash;
SKIP_HEADER(3) SKIP_HEADER(3)
HASH3_CALC; HASH3_CALC;
curMatch = p->hash[kFix3HashSize + hashValue]; hash = p->hash;
p->hash[hash2Value] = curMatch = hash[kFix3HashSize + hv];
p->hash[kFix3HashSize + hashValue] = p->pos; hash[h2] =
hash[kFix3HashSize + hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@@ -689,43 +909,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{ {
do do
{ {
UInt32 hash2Value, hash3Value; UInt32 h2, h3;
UInt32 *hash;
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue]; hash = p->hash;
p->hash[ hash2Value] = curMatch = hash[kFix4HashSize + hv];
p->hash[kFix3HashSize + hash3Value] = p->pos; hash[ h2] =
p->hash[kFix4HashSize + hashValue] = p->pos; hash[kFix3HashSize + h3] =
hash[kFix4HashSize + hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
} }
/*
static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 h2, h3, h4;
UInt32 *hash;
SKIP_HEADER(5)
HASH5_CALC;
hash = p->hash;
curMatch = hash[kFix5HashSize + hv];
hash[ h2] =
hash[kFix3HashSize + h3] =
hash[kFix4HashSize + h4] =
hash[kFix5HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
*/
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{ {
do do
{ {
UInt32 hash2Value, hash3Value; UInt32 h2, h3;
UInt32 *hash;
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue]; hash = p->hash;
p->hash[ hash2Value] = curMatch = hash[kFix4HashSize + hv];
p->hash[kFix3HashSize + hash3Value] = hash[ h2] =
p->hash[kFix4HashSize + hashValue] = p->pos; hash[kFix3HashSize + h3] =
hash[kFix4HashSize + hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS MOVE_POS
} }
while (--num != 0); while (--num != 0);
} }
/*
static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 h2, h3, h4;
UInt32 *hash;
SKIP_HEADER(5)
HASH5_CALC;
hash = p->hash;
curMatch = p->hash[kFix5HashSize + hv];
hash[ h2] =
hash[kFix3HashSize + h3] =
hash[kFix4HashSize + h4] =
hash[kFix5HashSize + hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
*/
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{ {
do do
{ {
SKIP_HEADER(3) SKIP_HEADER(3)
HASH_ZIP_CALC; HASH_ZIP_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hv];
p->hash[hashValue] = p->pos; p->hash[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS MOVE_POS
} }
@@ -735,13 +1002,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
{ {
vTable->Init = (Mf_Init_Func)MatchFinder_Init; vTable->Init = (Mf_Init_Func)MatchFinder_Init;
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
if (!p->btMode) if (!p->btMode)
{ {
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; /* if (p->numHashBytes <= 4) */
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; {
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
}
/*
else
{
vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
}
*/
} }
else if (p->numHashBytes == 2) else if (p->numHashBytes == 2)
{ {
@@ -753,9 +1029,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
} }
else else /* if (p->numHashBytes == 4) */
{ {
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
} }
/*
else
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
}
*/
} }

38
C/LzFind.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2009-04-22 : Igor Pavlov : Public domain */ 2015-10-15 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
typedef UInt32 CLzRef; typedef UInt32 CLzRef;
@@ -23,6 +21,11 @@ typedef struct _CMatchFinder
UInt32 cyclicBufferPos; UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
Byte streamEndWasReached;
Byte btMode;
Byte bigHash;
Byte directInput;
UInt32 matchMaxLen; UInt32 matchMaxLen;
CLzRef *hash; CLzRef *hash;
CLzRef *son; CLzRef *son;
@@ -31,30 +34,30 @@ typedef struct _CMatchFinder
Byte *bufferBase; Byte *bufferBase;
ISeqInStream *stream; ISeqInStream *stream;
int streamEndWasReached;
UInt32 blockSize; UInt32 blockSize;
UInt32 keepSizeBefore; UInt32 keepSizeBefore;
UInt32 keepSizeAfter; UInt32 keepSizeAfter;
UInt32 numHashBytes; UInt32 numHashBytes;
int directInput;
size_t directInputRem; size_t directInputRem;
int btMode;
int bigHash;
UInt32 historySize; UInt32 historySize;
UInt32 fixedHashSize; UInt32 fixedHashSize;
UInt32 hashSizeSum; UInt32 hashSizeSum;
UInt32 numSons;
SRes result; SRes result;
UInt32 crc[256]; UInt32 crc[256];
size_t numRefs;
} CMatchFinder; } CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) #define Inline_MatchFinder_GetNumAvailableBytes(p) ((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); int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p); void MatchFinder_MoveBlock(CMatchFinder *p);
@@ -70,7 +73,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc); ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
@@ -84,7 +87,6 @@ Conditions:
*/ */
typedef void (*Mf_Init_Func)(void *object); typedef void (*Mf_Init_Func)(void *object);
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
@@ -93,7 +95,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder typedef struct _IMatchFinder
{ {
Mf_Init_Func Init; Mf_Init_Func Init;
Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches; Mf_GetMatches_Func GetMatches;
@@ -102,14 +103,15 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_2(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p); void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

190
C/LzFindMt.c Executable file → Normal file
View File

@@ -1,11 +1,13 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2009-09-20 : Igor Pavlov : Public domain */ 2015-10-15 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "LzHash.h" #include "LzHash.h"
#include "LzFindMt.h" #include "LzFindMt.h"
void MtSync_Construct(CMtSync *p) static void MtSync_Construct(CMtSync *p)
{ {
p->wasCreated = False; p->wasCreated = False;
p->csWasInitialized = False; p->csWasInitialized = False;
@@ -18,7 +20,7 @@ void MtSync_Construct(CMtSync *p)
Semaphore_Construct(&p->filledSemaphore); Semaphore_Construct(&p->filledSemaphore);
} }
void MtSync_GetNextBlock(CMtSync *p) static void MtSync_GetNextBlock(CMtSync *p)
{ {
if (p->needStart) if (p->needStart)
{ {
@@ -46,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p)
/* MtSync_StopWriting must be called if Writing was started */ /* MtSync_StopWriting must be called if Writing was started */
void MtSync_StopWriting(CMtSync *p) static void MtSync_StopWriting(CMtSync *p)
{ {
UInt32 myNumBlocks = p->numProcessedBlocks; UInt32 myNumBlocks = p->numProcessedBlocks;
if (!Thread_WasCreated(&p->thread) || p->needStart) if (!Thread_WasCreated(&p->thread) || p->needStart)
@@ -69,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p)
p->needStart = True; p->needStart = True;
} }
void MtSync_Destruct(CMtSync *p) static void MtSync_Destruct(CMtSync *p)
{ {
if (Thread_WasCreated(&p->thread)) if (Thread_WasCreated(&p->thread))
{ {
@@ -97,7 +99,7 @@ void MtSync_Destruct(CMtSync *p)
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
{ {
if (p->wasCreated) if (p->wasCreated)
return SZ_OK; return SZ_OK;
@@ -119,7 +121,7 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void
return SZ_OK; return SZ_OK;
} }
static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks)
{ {
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
if (res != SZ_OK) if (res != SZ_OK)
@@ -132,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; }
#define kMtMaxValForNormalize 0xFFFFFFFF #define kMtMaxValForNormalize 0xFFFFFFFF
#define DEF_GetHeads2(name, v, action) \ #define DEF_GetHeads2(name, v, action) \
static void GetHeads ## name(const Byte *p, UInt32 pos, \ static void GetHeads ## name(const Byte *p, UInt32 pos, \
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
{ action; for (; numHeads != 0; numHeads--) { \ { action; for (; numHeads != 0; numHeads--) { \
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } } const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) #define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; ) DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), UNUSED_VAR(hashMask); UNUSED_VAR(crc); )
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */ /* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
void HashThreadFunc(CMatchFinderMt *mt) static void HashThreadFunc(CMatchFinderMt *mt)
{ {
CMtSync *p = &mt->hashSync; CMtSync *p = &mt->hashSync;
for (;;) for (;;)
@@ -171,12 +173,12 @@ void HashThreadFunc(CMatchFinderMt *mt)
CriticalSection_Enter(&mt->btSync.cs); CriticalSection_Enter(&mt->btSync.cs);
CriticalSection_Enter(&mt->hashSync.cs); CriticalSection_Enter(&mt->hashSync.cs);
{ {
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf); const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
const Byte *afterPtr; ptrdiff_t offset;
MatchFinder_MoveBlock(mf); MatchFinder_MoveBlock(mf);
afterPtr = MatchFinder_GetPointerToCurrentPos(mf); offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
mt->pointerToCurPos -= beforePtr - afterPtr; mt->pointerToCurPos -= offset;
mt->buffer -= beforePtr - afterPtr; mt->buffer -= offset;
} }
CriticalSection_Leave(&mt->btSync.cs); CriticalSection_Leave(&mt->btSync.cs);
CriticalSection_Leave(&mt->hashSync.cs); CriticalSection_Leave(&mt->hashSync.cs);
@@ -190,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
{ {
UInt32 subValue = (mf->pos - mf->historySize - 1); UInt32 subValue = (mf->pos - mf->historySize - 1);
MatchFinder_ReduceOffsets(mf, subValue); MatchFinder_ReduceOffsets(mf, subValue);
MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1); MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1);
} }
{ {
UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize; UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -215,7 +217,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
} }
} }
void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
{ {
MtSync_GetNextBlock(&p->hashSync); MtSync_GetNextBlock(&p->hashSync);
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize; p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -231,7 +233,7 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
#define NO_INLINE MY_FAST_CALL #define NO_INLINE MY_FAST_CALL
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes) UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
{ {
@@ -308,12 +310,14 @@ Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CL
#endif #endif
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{ {
UInt32 numProcessed = 0; UInt32 numProcessed = 0;
UInt32 curPos = 2; UInt32 curPos = 2;
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
distances[1] = p->hashNumAvail; distances[1] = p->hashNumAvail;
while (curPos < limit) while (curPos < limit)
{ {
if (p->hashBufPos == p->hashBufPosLimit) if (p->hashBufPos == p->hashBufPosLimit)
@@ -322,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
distances[1] = numProcessed + p->hashNumAvail; distances[1] = numProcessed + p->hashNumAvail;
if (p->hashNumAvail >= p->numHashBytes) if (p->hashNumAvail >= p->numHashBytes)
continue; continue;
distances[0] = curPos + p->hashNumAvail;
distances += curPos;
for (; p->hashNumAvail != 0; p->hashNumAvail--) for (; p->hashNumAvail != 0; p->hashNumAvail--)
distances[curPos++] = 0; *distances++ = 0;
break; return;
} }
{ {
UInt32 size = p->hashBufPosLimit - p->hashBufPos; UInt32 size = p->hashBufPosLimit - p->hashBufPos;
@@ -341,13 +347,14 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
if (size2 < size) if (size2 < size)
size = size2; size = size2;
} }
#ifndef MFMT_GM_INLINE #ifndef MFMT_GM_INLINE
while (curPos < limit && size-- != 0) while (curPos < limit && size-- != 0)
{ {
UInt32 *startDistances = distances + curPos; UInt32 *startDistances = distances + curPos;
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
startDistances + 1, p->numHashBytes - 1) - startDistances); startDistances + 1, p->numHashBytes - 1) - startDistances);
*startDistances = num - 1; *startDistances = num - 1;
curPos += num; curPos += num;
cyclicBufferPos++; cyclicBufferPos++;
@@ -358,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{ {
UInt32 posRes; UInt32 posRes;
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes); distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes);
p->hashBufPos += posRes - pos; p->hashBufPos += posRes - pos;
cyclicBufferPos += posRes - pos; cyclicBufferPos += posRes - pos;
p->buffer += posRes - pos; p->buffer += posRes - pos;
@@ -374,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
p->cyclicBufferPos = cyclicBufferPos; p->cyclicBufferPos = cyclicBufferPos;
} }
} }
distances[0] = curPos; distances[0] = curPos;
} }
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
{ {
CMtSync *sync = &p->hashSync; CMtSync *sync = &p->hashSync;
if (!sync->needStart) if (!sync->needStart)
@@ -391,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize) if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
{ {
UInt32 subValue = p->pos - p->cyclicBufferSize; UInt32 subValue = p->pos - p->cyclicBufferSize;
MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2); MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2);
p->pos -= subValue; p->pos -= subValue;
} }
@@ -430,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt)
void MatchFinderMt_Construct(CMatchFinderMt *p) void MatchFinderMt_Construct(CMatchFinderMt *p)
{ {
p->hashBuf = 0; p->hashBuf = NULL;
MtSync_Construct(&p->hashSync); MtSync_Construct(&p->hashSync);
MtSync_Construct(&p->btSync); MtSync_Construct(&p->btSync);
} }
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->hashBuf); alloc->Free(alloc, p->hashBuf);
p->hashBuf = 0; p->hashBuf = NULL;
} }
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
@@ -451,14 +459,15 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) #define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) #define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; } static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
static unsigned MY_STD_CALL BtThreadFunc2(void *p) static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
{ {
Byte allocaDummy[0x180]; Byte allocaDummy[0x180];
int i = 0; unsigned i = 0;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
allocaDummy[i] = (Byte)i; allocaDummy[i] = (Byte)0;
BtThreadFunc((CMatchFinderMt *)p); if (allocaDummy[0] == 0)
BtThreadFunc((CMatchFinderMt *)p);
return 0; return 0;
} }
@@ -469,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
p->historySize = historySize; p->historySize = historySize;
if (kMtBtBlockSize <= matchMaxLen * 4) if (kMtBtBlockSize <= matchMaxLen * 4)
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
if (p->hashBuf == 0) if (!p->hashBuf)
{ {
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
if (p->hashBuf == 0) if (!p->hashBuf)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
p->btBuf = p->hashBuf + kHashBufferSize; p->btBuf = p->hashBuf + kHashBufferSize;
} }
@@ -492,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
CMatchFinder *mf = p->MatchFinder; CMatchFinder *mf = p->MatchFinder;
p->btBufPos = p->btBufPosLimit = 0; p->btBufPos = p->btBufPosLimit = 0;
p->hashBufPos = p->hashBufPosLimit = 0; p->hashBufPos = p->hashBufPosLimit = 0;
MatchFinder_Init(mf);
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf); /* Init without data reading. We don't want to read data in this thread */
MatchFinder_Init_2(mf, False);
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
p->btNumAvailBytes = 0; p->btNumAvailBytes = 0;
p->lzPos = p->historySize + 1; p->lzPos = p->historySize + 1;
@@ -518,13 +530,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
/* p->MatchFinder->ReleaseStream(); */ /* p->MatchFinder->ReleaseStream(); */
} }
void MatchFinderMt_Normalize(CMatchFinderMt *p) static void MatchFinderMt_Normalize(CMatchFinderMt *p)
{ {
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize); MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
p->lzPos = p->historySize + 1; p->lzPos = p->historySize + 1;
} }
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
{ {
UInt32 blockIndex; UInt32 blockIndex;
MtSync_GetNextBlock(&p->btSync); MtSync_GetNextBlock(&p->btSync);
@@ -536,34 +548,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
MatchFinderMt_Normalize(p); MatchFinderMt_Normalize(p);
} }
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
{ {
return p->pointerToCurPos; return p->pointerToCurPos;
} }
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); #define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
{ {
GET_NEXT_BLOCK_IF_REQUIRED; GET_NEXT_BLOCK_IF_REQUIRED;
return p->btNumAvailBytes; return p->btNumAvailBytes;
} }
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index) static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{ {
return p->pointerToCurPos[index]; UInt32 h2, curMatch2;
}
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
UInt32 hash2Value, curMatch2;
UInt32 *hash = p->hash; UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos; const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos; UInt32 lzPos = p->lzPos;
MT_HASH2_CALC MT_HASH2_CALC
curMatch2 = hash[hash2Value]; curMatch2 = hash[h2];
hash[hash2Value] = lzPos; hash[h2] = lzPos;
if (curMatch2 >= matchMinPos) if (curMatch2 >= matchMinPos)
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
@@ -571,23 +578,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 2; *distances++ = 2;
*distances++ = lzPos - curMatch2 - 1; *distances++ = lzPos - curMatch2 - 1;
} }
return distances; return distances;
} }
UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{ {
UInt32 hash2Value, hash3Value, curMatch2, curMatch3; UInt32 h2, h3, curMatch2, curMatch3;
UInt32 *hash = p->hash; UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos; const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos; UInt32 lzPos = p->lzPos;
MT_HASH3_CALC MT_HASH3_CALC
curMatch2 = hash[ hash2Value]; curMatch2 = hash[ h2];
curMatch3 = hash[kFix3HashSize + hash3Value]; curMatch3 = hash[kFix3HashSize + h3];
hash[ hash2Value] = hash[ h2] = lzPos;
hash[kFix3HashSize + hash3Value] = hash[kFix3HashSize + h3] = lzPos;
lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{ {
@@ -600,43 +607,45 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
distances[0] = 2; distances[0] = 2;
distances += 2; distances += 2;
} }
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{ {
*distances++ = 3; *distances++ = 3;
*distances++ = lzPos - curMatch3 - 1; *distances++ = lzPos - curMatch3 - 1;
} }
return distances; return distances;
} }
/* /*
UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{ {
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4; UInt32 h2, h3, h4, curMatch2, curMatch3, curMatch4;
UInt32 *hash = p->hash; UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos; const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos; UInt32 lzPos = p->lzPos;
MT_HASH4_CALC MT_HASH4_CALC
curMatch2 = hash[ hash2Value]; curMatch2 = hash[ h2];
curMatch3 = hash[kFix3HashSize + hash3Value]; curMatch3 = hash[kFix3HashSize + h3];
curMatch4 = hash[kFix4HashSize + hash4Value]; curMatch4 = hash[kFix4HashSize + h4];
hash[ hash2Value] = hash[ h2] = lzPos;
hash[kFix3HashSize + hash3Value] = hash[kFix3HashSize + h3] = lzPos;
hash[kFix4HashSize + hash4Value] = hash[kFix4HashSize + h4] = lzPos;
lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{ {
distances[1] = lzPos - curMatch2 - 1; distances[1] = lzPos - curMatch2 - 1;
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
{ {
distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3; distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
return distances + 2; return distances + 2;
} }
distances[0] = 2; distances[0] = 2;
distances += 2; distances += 2;
} }
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{ {
distances[1] = lzPos - curMatch3 - 1; distances[1] = lzPos - curMatch3 - 1;
@@ -658,13 +667,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 4; *distances++ = 4;
*distances++ = lzPos - curMatch4 - 1; *distances++ = lzPos - curMatch4 - 1;
} }
return distances; return distances;
} }
*/ */
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++; #define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{ {
const UInt32 *btBuf = p->btBuf + p->btBufPos; const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++; UInt32 len = *btBuf++;
@@ -682,7 +692,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
return len; return len;
} }
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{ {
const UInt32 *btBuf = p->btBuf + p->btBufPos; const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++; UInt32 len = *btBuf++;
@@ -690,6 +700,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
if (len == 0) if (len == 0)
{ {
/* change for bt5 ! */
if (p->btNumAvailBytes-- >= 4) if (p->btNumAvailBytes-- >= 4)
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances)); len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
} }
@@ -705,7 +716,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
*distances2++ = *btBuf++; *distances2++ = *btBuf++;
} }
while ((len -= 2) != 0); while ((len -= 2) != 0);
len = (UInt32)(distances2 - (distances)); len = (UInt32)(distances2 - (distances));
} }
INCREASE_LZ_POS INCREASE_LZ_POS
return len; return len;
@@ -715,41 +726,41 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; #define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); #define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
{ {
SKIP_HEADER2_MT { p->btNumAvailBytes--; SKIP_HEADER2_MT { p->btNumAvailBytes--;
SKIP_FOOTER_MT SKIP_FOOTER_MT
} }
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
{ {
SKIP_HEADER_MT(2) SKIP_HEADER_MT(2)
UInt32 hash2Value; UInt32 h2;
MT_HASH2_CALC MT_HASH2_CALC
hash[hash2Value] = p->lzPos; hash[h2] = p->lzPos;
SKIP_FOOTER_MT SKIP_FOOTER_MT
} }
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
{ {
SKIP_HEADER_MT(3) SKIP_HEADER_MT(3)
UInt32 hash2Value, hash3Value; UInt32 h2, h3;
MT_HASH3_CALC MT_HASH3_CALC
hash[kFix3HashSize + hash3Value] = hash[kFix3HashSize + h3] =
hash[ hash2Value] = hash[ h2] =
p->lzPos; p->lzPos;
SKIP_FOOTER_MT SKIP_FOOTER_MT
} }
/* /*
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
{ {
SKIP_HEADER_MT(4) SKIP_HEADER_MT(4)
UInt32 hash2Value, hash3Value, hash4Value; UInt32 h2, h3, h4;
MT_HASH4_CALC MT_HASH4_CALC
hash[kFix4HashSize + hash4Value] = hash[kFix4HashSize + h4] =
hash[kFix3HashSize + hash3Value] = hash[kFix3HashSize + h3] =
hash[ hash2Value] = hash[ h2] =
p->lzPos; p->lzPos;
SKIP_FOOTER_MT SKIP_FOOTER_MT
} }
@@ -758,11 +769,11 @@ void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
{ {
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init; vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes; vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos; vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches; vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
switch(p->MatchFinder->numHashBytes)
switch (p->MatchFinder->numHashBytes)
{ {
case 2: case 2:
p->GetHeadsFunc = GetHeads2; p->GetHeadsFunc = GetHeads2;
@@ -778,7 +789,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
default: default:
/* case 4: */ /* case 4: */
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4; p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
/* p->GetHeadsFunc = GetHeads4; */
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3; p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip; vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
break; break;

12
C/LzFindMt.h Executable file → Normal file
View File

@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2009-02-07 : Igor Pavlov : Public domain */ 2015-05-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H #ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H #define __LZ_FIND_MT_H
@@ -7,9 +7,7 @@
#include "LzFind.h" #include "LzFind.h"
#include "Threads.h" #include "Threads.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
#define kMtHashBlockSize (1 << 13) #define kMtHashBlockSize (1 << 13)
#define kMtHashNumBlocks (1 << 3) #define kMtHashNumBlocks (1 << 3)
@@ -77,7 +75,7 @@ typedef struct _CMatchFinderMt
UInt32 matchMaxLen; UInt32 matchMaxLen;
UInt32 numHashBytes; UInt32 numHashBytes;
UInt32 pos; UInt32 pos;
Byte *buffer; const Byte *buffer;
UInt32 cyclicBufferPos; UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be historySize + 1 */ UInt32 cyclicBufferSize; /* it must be historySize + 1 */
UInt32 cutValue; UInt32 cutValue;
@@ -98,8 +96,6 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

43
C/LzHash.h Executable file → Normal file
View File

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

50
C/Lzma2Dec.c Executable file → Normal file
View File

@@ -1,8 +1,10 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2010-12-15 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
#include "Precomp.h"
#ifdef SHOW_DEBUG_INFO #ifdef SHOW_DEBUG_INFO
#include <stdio.h> #include <stdio.h>
#endif #endif
@@ -97,12 +99,12 @@ void Lzma2Dec_Init(CLzma2Dec *p)
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{ {
switch(p->state) switch (p->state)
{ {
case LZMA2_STATE_CONTROL: case LZMA2_STATE_CONTROL:
p->control = b; p->control = b;
PRF(printf("\n %4X ", p->decoder.dicPos)); PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", b)); PRF(printf(" %2X", (unsigned)b));
if (p->control == 0) if (p->control == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
@@ -122,7 +124,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1: case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b; p->unpackSize |= (UInt32)b;
p->unpackSize++; p->unpackSize++;
PRF(printf(" %8d", p->unpackSize)); PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
@@ -132,13 +134,13 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1: case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b; p->packSize |= (UInt32)b;
p->packSize++; p->packSize++;
PRF(printf(" %8d", p->packSize)); PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP: case LZMA2_STATE_PROP:
{ {
int lc, lp; unsigned lc, lp;
if (b >= (9 * 5 * 5)) if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
lc = b % 9; lc = b % 9;
@@ -177,13 +179,16 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
while (p->state != LZMA2_STATE_FINISHED) while (p->state != LZMA2_STATE_FINISHED)
{ {
SizeT dicPos = p->decoder.dicPos; SizeT dicPos = p->decoder.dicPos;
if (p->state == LZMA2_STATE_ERROR) if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK; return SZ_OK;
} }
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{ {
if (*srcLen == inSize) if (*srcLen == inSize)
@@ -193,8 +198,15 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
} }
(*srcLen)++; (*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++); p->state = Lzma2Dec_UpdateState(p, *src++);
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
continue; continue;
} }
{ {
SizeT destSizeCur = dicLimit - dicPos; SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen; SizeT srcSizeCur = inSize - *srcLen;
@@ -220,7 +232,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (initDic) if (initDic)
p->needInitProp = p->needInitState = True; p->needInitProp = p->needInitState = True;
else if (p->needInitDic) else if (p->needInitDic)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
}
p->needInitDic = False; p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False); LzmaDec_InitDicAndState(&p->decoder, initDic, False);
} }
@@ -229,7 +244,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
srcSizeCur = destSizeCur; srcSizeCur = destSizeCur;
if (srcSizeCur == 0) if (srcSizeCur == 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
}
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
@@ -245,17 +263,21 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
int mode = LZMA2_GET_LZMA_MODE(p); unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3); Bool initDic = (mode == 3);
Bool initState = (mode > 0); Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
}
LzmaDec_InitDicAndState(&p->decoder, initDic, initState); LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False; p->needInitDic = False;
p->needInitState = False; p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT; p->state = LZMA2_STATE_DATA_CONT;
} }
if (srcSizeCur > p->packSize) if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize; srcSizeCur = (SizeT)p->packSize;
@@ -274,16 +296,22 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (srcSizeCur == 0 && outSizeProcessed == 0) if (srcSizeCur == 0 && outSizeProcessed == 0)
{ {
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
p->unpackSize != 0 || p->packSize != 0) || p->unpackSize != 0
|| p->packSize != 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
}
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
} }
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
} }
} }
} }
*status = LZMA_STATUS_FINISHED_WITH_MARK; *status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK; return SZ_OK;
} }

12
C/Lzma2Dec.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* Lzma2Dec.h -- LZMA2 Decoder /* Lzma2Dec.h -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */ 2015-05-13 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H #ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H #define __LZMA2_DEC_H
#include "LzmaDec.h" #include "LzmaDec.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
/* ---------- State Interface ---------- */ /* ---------- State Interface ---------- */
@@ -17,7 +15,7 @@ typedef struct
CLzmaDec decoder; CLzmaDec decoder;
UInt32 packSize; UInt32 packSize;
UInt32 unpackSize; UInt32 unpackSize;
int state; unsigned state;
Byte control; Byte control;
Bool needInitDic; Bool needInitDic;
Bool needInitState; Bool needInitState;
@@ -77,8 +75,6 @@ Returns:
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

73
C/Lzma2Enc.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* Lzma2Enc.c -- LZMA2 Encoder /* Lzma2Enc.c -- LZMA2 Encoder
2010-09-24 : Igor Pavlov : Public domain */ 2015-10-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
/* #include <stdio.h> */ /* #include <stdio.h> */
#include <string.h> #include <string.h>
@@ -107,6 +109,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
{ {
size_t destPos = 0; size_t destPos = 0;
PRF(printf("################# COPY ")); PRF(printf("################# COPY "));
while (unpackSize > 0) while (unpackSize > 0)
{ {
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
@@ -119,6 +122,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
unpackSize -= u; unpackSize -= u;
destPos += u; destPos += u;
p->srcPos += u; p->srcPos += u;
if (outStream) if (outStream)
{ {
*packSizeRes += destPos; *packSizeRes += destPos;
@@ -130,9 +134,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
*packSizeRes = destPos; *packSizeRes = destPos;
/* needInitState = True; */ /* needInitState = True; */
} }
LzmaEnc_RestoreState(p->enc); LzmaEnc_RestoreState(p->enc);
return SZ_OK; return SZ_OK;
} }
{ {
size_t destPos = 0; size_t destPos = 0;
UInt32 u = unpackSize - 1; UInt32 u = unpackSize - 1;
@@ -158,11 +164,13 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
if (outStream) if (outStream)
if (outStream->Write(outStream, outBuf, destPos) != destPos) if (outStream->Write(outStream, outBuf, destPos) != destPos)
return SZ_ERROR_WRITE; return SZ_ERROR_WRITE;
*packSizeRes = destPos; *packSizeRes = destPos;
return SZ_OK; return SZ_OK;
} }
} }
/* ---------- Lzma2 Props ---------- */ /* ---------- Lzma2 Props ---------- */
void Lzma2EncProps_Init(CLzma2EncProps *p) void Lzma2EncProps_Init(CLzma2EncProps *p)
@@ -216,10 +224,11 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
t3 = t1n * t2; t3 = t1n * t2;
p->lzmaProps.numThreads = t1; p->lzmaProps.numThreads = t1;
p->numBlockThreads = t2;
p->numTotalThreads = t3;
LzmaEncProps_Normalize(&p->lzmaProps); LzmaEncProps_Normalize(&p->lzmaProps);
t1 = p->lzmaProps.numThreads;
if (p->blockSize == 0) if (p->blockSize == 0)
{ {
UInt32 dictSize = p->lzmaProps.dictSize; UInt32 dictSize = p->lzmaProps.dictSize;
@@ -231,13 +240,34 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
if (blockSize < dictSize) blockSize = dictSize; if (blockSize < dictSize) blockSize = dictSize;
p->blockSize = (size_t)blockSize; p->blockSize = (size_t)blockSize;
} }
if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1)
{
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
if (temp > p->lzmaProps.reduceSize)
{
UInt64 numBlocks = temp / p->blockSize;
if (numBlocks < (unsigned)t2)
{
t2 = (unsigned)numBlocks;
if (t2 == 0)
t2 = 1;
t3 = t1 * t2;
}
}
}
p->numBlockThreads = t2;
p->numTotalThreads = t3;
} }
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize) static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{ {
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
} }
/* ---------- Lzma2 ---------- */ /* ---------- Lzma2 ---------- */
typedef struct typedef struct
@@ -267,15 +297,17 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
UInt64 packTotal = 0; UInt64 packTotal = 0;
SRes res = SZ_OK; SRes res = SZ_OK;
if (mainEncoder->outBuf == 0) if (!mainEncoder->outBuf)
{ {
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
if (mainEncoder->outBuf == 0) if (!mainEncoder->outBuf)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
} }
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props)); RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE, RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
mainEncoder->alloc, mainEncoder->allocBig)); mainEncoder->alloc, mainEncoder->allocBig));
for (;;) for (;;)
{ {
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
@@ -289,16 +321,20 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
if (packSize == 0) if (packSize == 0)
break; break;
} }
LzmaEnc_Finish(p->enc); LzmaEnc_Finish(p->enc);
if (res == SZ_OK) if (res == SZ_OK)
{ {
Byte b = 0; Byte b = 0;
if (outStream->Write(outStream, &b, 1) != 1) if (outStream->Write(outStream, &b, 1) != 1)
return SZ_ERROR_WRITE; return SZ_ERROR_WRITE;
} }
return res; return res;
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
typedef struct typedef struct
@@ -346,10 +382,12 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
break; break;
} }
} }
LzmaEnc_Finish(p->enc); LzmaEnc_Finish(p->enc);
if (res != SZ_OK) if (res != SZ_OK)
return res; return res;
} }
if (finished) if (finished)
{ {
if (*destSize == destLim) if (*destSize == destLim)
@@ -362,12 +400,13 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
#endif #endif
/* ---------- Lzma2Enc ---------- */ /* ---------- Lzma2Enc ---------- */
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig) CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc)); CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
if (p == 0) if (!p)
return NULL; return NULL;
Lzma2EncProps_Init(&p->props); Lzma2EncProps_Init(&p->props);
Lzma2EncProps_Normalize(&p->props); Lzma2EncProps_Normalize(&p->props);
@@ -379,6 +418,7 @@ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
p->coders[i].enc = 0; p->coders[i].enc = 0;
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MtCoder_Construct(&p->mtCoder); MtCoder_Construct(&p->mtCoder);
#endif #endif
@@ -439,22 +479,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
for (i = 0; i < p->props.numBlockThreads; i++) for (i = 0; i < p->props.numBlockThreads; i++)
{ {
CLzma2EncInt *t = &p->coders[i]; CLzma2EncInt *t = &p->coders[(unsigned)i];
if (t->enc == NULL) if (!t->enc)
{ {
t->enc = LzmaEnc_Create(p->alloc); t->enc = LzmaEnc_Create(p->alloc);
if (t->enc == NULL) if (!t->enc)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
} }
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
if (p->props.numBlockThreads <= 1) if (p->props.numBlockThreads > 1)
#endif
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
#ifndef _7ZIP_ST
{ {
CMtCallbackImp mtCallback; CMtCallbackImp mtCallback;
@@ -469,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
p->mtCoder.blockSize = p->props.blockSize; p->mtCoder.blockSize = p->props.blockSize;
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
if (p->mtCoder.destBlockSize < p->props.blockSize)
{
p->mtCoder.destBlockSize = (size_t)0 - 1;
if (p->mtCoder.destBlockSize < p->props.blockSize)
return SZ_ERROR_FAIL;
}
p->mtCoder.numThreads = p->props.numBlockThreads; p->mtCoder.numThreads = p->props.numBlockThreads;
return MtCoder_Code(&p->mtCoder); return MtCoder_Code(&p->mtCoder);
} }
#endif #endif
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
} }

10
C/Lzma2Enc.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* Lzma2Enc.h -- LZMA2 Encoder /* Lzma2Enc.h -- LZMA2 Encoder
2009-02-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA2_ENC_H #ifndef __LZMA2_ENC_H
#define __LZMA2_ENC_H #define __LZMA2_ENC_H
#include "LzmaEnc.h" #include "LzmaEnc.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
typedef struct typedef struct
{ {
@@ -59,8 +57,6 @@ SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
*/ */
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

4
C/Lzma86.h Executable file → Normal file
View File

@@ -1,10 +1,10 @@
/* Lzma86.h -- LZMA + x86 (BCJ) Filter /* Lzma86.h -- LZMA + x86 (BCJ) Filter
2009-08-14 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA86_H #ifndef __LZMA86_H
#define __LZMA86_H #define __LZMA86_H
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN

8
C/Lzma86Dec.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder /* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
2009-08-14 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Lzma86.h" #include "Lzma86.h"
@@ -7,8 +9,8 @@
#include "Bra.h" #include "Bra.h"
#include "LzmaDec.h" #include "LzmaDec.h"
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); } static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
{ {

10
C/Lzma86Enc.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2009-08-14 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -11,8 +13,8 @@
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); } static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode) int level, UInt32 dictSize, int filterMode)
@@ -99,7 +101,7 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
} }
} }
} }
dest[0] = (bestIsFiltered ? 1 : 0); dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
*destLen = LZMA86_HEADER_SIZE + minSize; *destLen = LZMA86_HEADER_SIZE + minSize;
} }
if (useFilter) if (useFilter)

229
C/LzmaDec.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* LzmaDec.c -- LZMA Decoder /* LzmaDec.c -- LZMA Decoder
2010-12-15 : Igor Pavlov : Public domain */ 2015-06-23 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "LzmaDec.h" #include "LzmaDec.h"
@@ -44,6 +46,13 @@
i -= 0x40; } i -= 0x40; }
#endif #endif
#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
#define MATCHED_LITER_DEC \
matchByte <<= 1; \
bit = (matchByte & offs); \
probLit = prob + offs + bit + symbol; \
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
@@ -105,14 +114,14 @@
#define Literal (RepLenCoder + kNumLenProbs) #define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846 #define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768 #define LZMA_LIT_SIZE 0x300
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#if Literal != LZMA_BASE_SIZE #if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG StopCompilingDueBUG
#endif #endif
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define LZMA_DIC_MIN (1 << 12) #define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded. /* First LZMA-symbol is always decoded.
@@ -124,8 +133,8 @@ Out:
p->remainLen: p->remainLen:
< kMatchSpecLenStart : normal remain < kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished = kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker = kMatchSpecLenStart + 1 : Flush marker (unused now)
= kMatchSpecLenStart + 2 : State Init Marker = kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/ */
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
@@ -163,38 +172,62 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
unsigned symbol; unsigned symbol;
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + Literal; prob = probs + Literal;
if (checkDicSize != 0 || processedPos != 0) if (processedPos != 0 || checkDicSize != 0)
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
processedPos++;
if (state < kNumLitStates) if (state < kNumLitStates)
{ {
state -= (state < 4) ? state : 3; state -= (state < 4) ? state : 3;
symbol = 1; symbol = 1;
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); #ifdef _LZMA_SIZE_OPT
do { NORMAL_LITER_DEC } while (symbol < 0x100);
#else
NORMAL_LITER_DEC
NORMAL_LITER_DEC
NORMAL_LITER_DEC
NORMAL_LITER_DEC
NORMAL_LITER_DEC
NORMAL_LITER_DEC
NORMAL_LITER_DEC
NORMAL_LITER_DEC
#endif
} }
else else
{ {
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
unsigned offs = 0x100; unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6; state -= (state < 10) ? 3 : 6;
symbol = 1; symbol = 1;
#ifdef _LZMA_SIZE_OPT
do do
{ {
unsigned bit; unsigned bit;
CLzmaProb *probLit; CLzmaProb *probLit;
matchByte <<= 1; MATCHED_LITER_DEC
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
} }
while (symbol < 0x100); while (symbol < 0x100);
#else
{
unsigned bit;
CLzmaProb *probLit;
MATCHED_LITER_DEC
MATCHED_LITER_DEC
MATCHED_LITER_DEC
MATCHED_LITER_DEC
MATCHED_LITER_DEC
MATCHED_LITER_DEC
MATCHED_LITER_DEC
MATCHED_LITER_DEC
}
#endif
} }
dic[dicPos++] = (Byte)symbol; dic[dicPos++] = (Byte)symbol;
processedPos++;
continue; continue;
} }
else
{ {
UPDATE_1(prob); UPDATE_1(prob);
prob = probs + IsRep + state; prob = probs + IsRep + state;
@@ -217,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob); UPDATE_0(prob);
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++; dicPos++;
processedPos++; processedPos++;
state = state < kNumLitStates ? 9 : 11; state = state < kNumLitStates ? 9 : 11;
@@ -258,6 +291,8 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state = state < kNumLitStates ? 8 : 11; state = state < kNumLitStates ? 8 : 11;
prob = probs + RepLenCoder; prob = probs + RepLenCoder;
} }
#ifdef _LZMA_SIZE_OPT
{ {
unsigned limit, offset; unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice; CLzmaProb *probLen = prob + LenChoice;
@@ -290,6 +325,42 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
TREE_DECODE(probLen, limit, len); TREE_DECODE(probLen, limit, len);
len += offset; len += offset;
} }
#else
{
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
len -= 8;
}
else
{
UPDATE_1(probLen);
probLen = prob + LenChoice2;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
len += kLenNumLowSymbols + kLenNumMidSymbols;
}
}
}
#endif
if (state >= kNumStates) if (state >= kNumStates)
{ {
@@ -300,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (distance >= kStartPosModelIndex) if (distance >= kStartPosModelIndex)
{ {
unsigned posSlot = (unsigned)distance; unsigned posSlot = (unsigned)distance;
int numDirectBits = (int)(((distance >> 1) - 1)); unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
distance = (2 | (distance & 1)); distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex) if (posSlot < kEndPosModelIndex)
{ {
@@ -359,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
} }
} }
} }
rep3 = rep2; rep3 = rep2;
rep2 = rep1; rep2 = rep1;
rep1 = rep0; rep1 = rep0;
@@ -366,26 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (checkDicSize == 0) if (checkDicSize == 0)
{ {
if (distance >= processedPos) if (distance >= processedPos)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
}
} }
else if (distance >= checkDicSize) else if (distance >= checkDicSize)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
}
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
} }
len += kMatchMinLen; len += kMatchMinLen;
if (limit == dicPos)
return SZ_ERROR_DATA;
{ {
SizeT rem = limit - dicPos; SizeT rem;
unsigned curLen = ((rem < len) ? (unsigned)rem : len); unsigned curLen;
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); SizeT pos;
if ((rem = limit - dicPos) == 0)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
curLen = ((rem < len) ? (unsigned)rem : len);
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
processedPos += curLen; processedPos += curLen;
len -= curLen; len -= curLen;
if (pos + curLen <= dicBufSize) if (curLen <= dicBufSize - pos)
{ {
Byte *dest = dic + dicPos; Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
@@ -409,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
} }
} }
while (dicPos < limit && buf < bufLimit); while (dicPos < limit && buf < bufLimit);
NORMALIZE; NORMALIZE;
p->buf = buf; p->buf = buf;
p->range = range; p->range = range;
p->code = code; p->code = code;
@@ -433,9 +520,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
SizeT dicPos = p->dicPos; SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize; SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen; unsigned len = p->remainLen;
UInt32 rep0 = p->reps[0]; SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
if (limit - dicPos < len) SizeT rem = limit - dicPos;
len = (unsigned)(limit - dicPos); if (rem < len)
len = (unsigned)(rem);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
@@ -445,7 +533,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
while (len != 0) while (len != 0)
{ {
len--; len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++; dicPos++;
} }
p->dicPos = dicPos; p->dicPos = dicPos;
@@ -463,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
if (limit - p->dicPos > rem) if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem; limit2 = p->dicPos + rem;
} }
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
if (p->processedPos >= p->prop.dicSize)
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
LzmaDec_WriteRem(p, limit); LzmaDec_WriteRem(p, limit);
} }
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart) if (p->remainLen > kMatchSpecLenStart)
{
p->remainLen = kMatchSpecLenStart; p->remainLen = kMatchSpecLenStart;
}
return 0; return 0;
} }
@@ -490,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range; UInt32 range = p->range;
UInt32 code = p->code; UInt32 code = p->code;
const Byte *bufLimit = buf + inSize; const Byte *bufLimit = buf + inSize;
CLzmaProb *probs = p->probs; const CLzmaProb *probs = p->probs;
unsigned state = p->state; unsigned state = p->state;
ELzmaDummy res; ELzmaDummy res;
{ {
CLzmaProb *prob; const CLzmaProb *prob;
UInt32 bound; UInt32 bound;
unsigned ttt; unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
@@ -509,9 +599,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal; prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0) if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE * prob += ((UInt32)LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates) if (state < kNumLitStates)
{ {
@@ -521,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
else else
{ {
unsigned matchByte = p->dic[p->dicPos - p->reps[0] + unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
unsigned offs = 0x100; unsigned offs = 0x100;
unsigned symbol = 1; unsigned symbol = 1;
do do
{ {
unsigned bit; unsigned bit;
CLzmaProb *probLit; const CLzmaProb *probLit;
matchByte <<= 1; matchByte <<= 1;
bit = (matchByte & offs); bit = (matchByte & offs);
probLit = prob + offs + bit + symbol; probLit = prob + offs + bit + symbol;
@@ -597,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
} }
{ {
unsigned limit, offset; unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice; const CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
@@ -637,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex) if (posSlot >= kStartPosModelIndex)
{ {
int numDirectBits = ((posSlot >> 1) - 1); unsigned numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
@@ -676,13 +766,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
} }
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
{
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{ {
p->needFlush = 1; p->needFlush = 1;
@@ -707,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
static void LzmaDec_InitStateReal(CLzmaDec *p) static void LzmaDec_InitStateReal(CLzmaDec *p)
{ {
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
UInt32 i; SizeT i;
CLzmaProb *probs = p->probs; CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++) for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1; probs[i] = kBitModelTotal >> 1;
@@ -730,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{ {
int checkEndMarkNow; int checkEndMarkNow;
if (p->needFlush != 0) if (p->needFlush)
{ {
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++; p->tempBuf[p->tempBufSize++] = *src++;
@@ -741,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
} }
if (p->tempBuf[0] != 0) if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
p->code =
LzmaDec_InitRc(p, p->tempBuf); ((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
p->tempBufSize = 0; p->tempBufSize = 0;
} }
@@ -826,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->buf = p->tempBuf; p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
{
unsigned kkk = (unsigned)(p->buf - p->tempBuf);
if (rem < kkk)
return SZ_ERROR_FAIL; /* some internal error */
rem -= kkk;
if (lookAhead < rem)
return SZ_ERROR_FAIL; /* some internal error */
lookAhead -= rem;
}
(*srcLen) += lookAhead; (*srcLen) += lookAhead;
src += lookAhead; src += lookAhead;
inSize -= lookAhead; inSize -= lookAhead;
@@ -881,13 +978,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->probs); alloc->Free(alloc, p->probs);
p->probs = 0; p->probs = NULL;
} }
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->dic); alloc->Free(alloc, p->dic);
p->dic = 0; p->dic = NULL;
} }
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
@@ -925,12 +1022,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{ {
UInt32 numProbs = LzmaProps_GetNumProbs(propNew); UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (p->probs == 0 || numProbs != p->numProbs) if (!p->probs || numProbs != p->numProbs)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs; p->numProbs = numProbs;
if (p->probs == 0) if (!p->probs)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
} }
return SZ_OK; return SZ_OK;
@@ -951,12 +1048,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SizeT dicBufSize; SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize)); RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize) {
UInt32 dictSize = propNew.dicSize;
SizeT mask = ((UInt32)1 << 12) - 1;
if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
dicBufSize = ((SizeT)dictSize + mask) & ~mask;
if (dicBufSize < dictSize)
dicBufSize = dictSize;
}
if (!p->dic || dicBufSize != p->dicBufSize)
{ {
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
if (p->dic == 0) if (!p->dic)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM; return SZ_ERROR_MEM;

12
C/LzmaDec.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2009-02-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H #ifndef __LZMA_DEC_H
#define __LZMA_DEC_H #define __LZMA_DEC_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
/* #define _LZMA_PROB32 */ /* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs, /* _LZMA_PROB32 can increase the speed on some CPUs,
@@ -224,8 +222,6 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc); ELzmaStatus *status, ISzAlloc *alloc);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

344
C/LzmaEnc.c Executable file → Normal file
View File

@@ -1,5 +1,7 @@
/* LzmaEnc.c -- LZMA Encoder /* LzmaEnc.c -- LZMA Encoder
2011-01-27 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -18,9 +20,12 @@
#endif #endif
#ifdef SHOW_STAT #ifdef SHOW_STAT
static int ttt = 0; static unsigned g_STAT_OFFSET = 0;
#endif #endif
#define kMaxHistorySize ((UInt32)3 << 29)
/* #define kMaxHistorySize ((UInt32)7 << 29) */
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) #define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
#define kBlockSize (9 << 10) #define kBlockSize (9 << 10)
@@ -46,7 +51,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
{ {
p->level = 5; p->level = 5;
p->dictSize = p->mc = 0; p->dictSize = p->mc = 0;
p->reduceSize = (UInt32)(Int32)-1; p->reduceSize = (UInt64)(Int64)-1;
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
p->writeEndMark = 0; p->writeEndMark = 0;
} }
@@ -56,24 +61,28 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
int level = p->level; int level = p->level;
if (level < 0) level = 5; if (level < 0) level = 5;
p->level = level; p->level = level;
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
if (p->dictSize > p->reduceSize) if (p->dictSize > p->reduceSize)
{ {
unsigned i; unsigned i;
for (i = 15; i <= 30; i++) for (i = 11; i <= 30; i++)
{ {
if (p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
if (p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
} }
} }
if (p->lc < 0) p->lc = 3; if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0; if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2; if (p->pb < 0) p->pb = 2;
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
if (p->numHashBytes < 0) p->numHashBytes = 4; if (p->numHashBytes < 0) p->numHashBytes = 4;
if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
if (p->numThreads < 0) if (p->numThreads < 0)
p->numThreads = p->numThreads =
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
@@ -90,17 +99,18 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
return props.dictSize; return props.dictSize;
} }
#if (_MSC_VER >= 1400)
/* BSR code is fast for some new CPUs */
/* #define LZMA_LOG_BSR */ /* #define LZMA_LOG_BSR */
/* Define it for Intel's CPU */ #endif
#ifdef LZMA_LOG_BSR #ifdef LZMA_LOG_BSR
#define kDicLogSizeMaxCompress 30 #define kDicLogSizeMaxCompress 32
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
UInt32 GetPosSlot1(UInt32 pos) static UInt32 GetPosSlot1(UInt32 pos)
{ {
UInt32 res; UInt32 res;
BSR2_RET(pos, res); BSR2_RET(pos, res);
@@ -111,27 +121,44 @@ UInt32 GetPosSlot1(UInt32 pos)
#else #else
#define kNumLogBits (9 + (int)sizeof(size_t) / 2) #define kNumLogBits (9 + sizeof(size_t) / 2)
/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
void LzmaEnc_FastPosInit(Byte *g_FastPos) static void LzmaEnc_FastPosInit(Byte *g_FastPos)
{ {
int c = 2, slotFast; unsigned slot;
g_FastPos[0] = 0; g_FastPos[0] = 0;
g_FastPos[1] = 1; g_FastPos[1] = 1;
g_FastPos += 2;
for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) for (slot = 2; slot < kNumLogBits * 2; slot++)
{ {
UInt32 k = (1 << ((slotFast >> 1) - 1)); size_t k = ((size_t)1 << ((slot >> 1) - 1));
UInt32 j; size_t j;
for (j = 0; j < k; j++, c++) for (j = 0; j < k; j++)
g_FastPos[c] = (Byte)slotFast; g_FastPos[j] = (Byte)slot;
g_FastPos += k;
} }
} }
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
/*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ #define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 2); } res = p->g_FastPos[pos >> i] + (i * 2); }
*/
/*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 2); }
*/
#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
res = p->g_FastPos[pos >> i] + (i * 2); }
/* /*
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
p->g_FastPos[pos >> 6] + 12 : \ p->g_FastPos[pos >> 6] + 12 : \
@@ -211,6 +238,7 @@ typedef struct
#define kNumStates 12 #define kNumStates 12
typedef struct typedef struct
{ {
CLzmaProb choice; CLzmaProb choice;
@@ -220,14 +248,16 @@ typedef struct
CLzmaProb high[kLenNumHighSymbols]; CLzmaProb high[kLenNumHighSymbols];
} CLenEnc; } CLenEnc;
typedef struct typedef struct
{ {
CLenEnc p; CLenEnc p;
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 tableSize; UInt32 tableSize;
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 counters[LZMA_NUM_PB_STATES_MAX]; UInt32 counters[LZMA_NUM_PB_STATES_MAX];
} CLenPriceEnc; } CLenPriceEnc;
typedef struct typedef struct
{ {
UInt32 range; UInt32 range;
@@ -242,10 +272,14 @@ typedef struct
SRes res; SRes res;
} CRangeEnc; } CRangeEnc;
typedef struct typedef struct
{ {
CLzmaProb *litProbs; CLzmaProb *litProbs;
UInt32 state;
UInt32 reps[LZMA_NUM_REPS];
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates]; CLzmaProb isRep[kNumStates];
CLzmaProb isRepG0[kNumStates]; CLzmaProb isRepG0[kNumStates];
@@ -259,15 +293,49 @@ typedef struct
CLenPriceEnc lenEnc; CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc; CLenPriceEnc repLenEnc;
UInt32 reps[LZMA_NUM_REPS];
UInt32 state;
} CSaveState; } CSaveState;
typedef struct typedef struct
{ {
IMatchFinder matchFinder;
void *matchFinderObj; void *matchFinderObj;
IMatchFinder matchFinder;
UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex;
UInt32 longestMatchLength;
UInt32 numPairs;
UInt32 numAvail;
UInt32 numFastBytes;
UInt32 additionalOffset;
UInt32 reps[LZMA_NUM_REPS];
UInt32 state;
unsigned lc, lp, pb;
unsigned lpMask, pbMask;
unsigned lclp;
CLzmaProb *litProbs;
Bool fastMode;
Bool writeEndMark;
Bool finished;
Bool multiThread;
Bool needInit;
UInt64 nowPos64;
UInt32 matchPriceCount;
UInt32 alignPriceCount;
UInt32 distTableSize;
UInt32 dictSize;
SRes result;
CRangeEnc rc;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
Bool mtMode; Bool mtMode;
@@ -280,12 +348,6 @@ typedef struct
Byte pad[128]; Byte pad[128];
#endif #endif
UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex;
UInt32 longestMatchLength;
UInt32 numPairs;
UInt32 numAvail;
COptimal opt[kNumOpts]; COptimal opt[kNumOpts];
#ifndef LZMA_LOG_BSR #ifndef LZMA_LOG_BSR
@@ -294,22 +356,10 @@ typedef struct
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
UInt32 numFastBytes;
UInt32 additionalOffset;
UInt32 reps[LZMA_NUM_REPS];
UInt32 state;
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
UInt32 alignPrices[kAlignTableSize]; UInt32 alignPrices[kAlignTableSize];
UInt32 alignPriceCount;
UInt32 distTableSize;
unsigned lc, lp, pb;
unsigned lpMask, pbMask;
CLzmaProb *litProbs;
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates]; CLzmaProb isRep[kNumStates];
@@ -325,26 +375,14 @@ typedef struct
CLenPriceEnc lenEnc; CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc; CLenPriceEnc repLenEnc;
unsigned lclp;
Bool fastMode;
CRangeEnc rc;
Bool writeEndMark;
UInt64 nowPos64;
UInt32 matchPriceCount;
Bool finished;
Bool multiThread;
SRes result;
UInt32 dictSize;
int needInit;
CSaveState saveState; CSaveState saveState;
#ifndef _7ZIP_ST
Byte pad2[128];
#endif
} CLzmaEnc; } CLzmaEnc;
void LzmaEnc_SaveState(CLzmaEncHandle pp) void LzmaEnc_SaveState(CLzmaEncHandle pp)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -368,7 +406,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps)); memcpy(dest->reps, p->reps, sizeof(p->reps));
memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
} }
void LzmaEnc_RestoreState(CLzmaEncHandle pp) void LzmaEnc_RestoreState(CLzmaEncHandle pp)
@@ -394,7 +432,7 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps)); memcpy(dest->reps, p->reps, sizeof(p->reps));
memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
} }
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
@@ -403,9 +441,13 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
CLzmaEncProps props = *props2; CLzmaEncProps props = *props2;
LzmaEncProps_Normalize(&props); LzmaEncProps_Normalize(&props);
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || if (props.lc > LZMA_LC_MAX
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) || props.lp > LZMA_LP_MAX
|| props.pb > LZMA_PB_MAX
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|| props.dictSize > kMaxHistorySize)
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
p->dictSize = props.dictSize; p->dictSize = props.dictSize;
{ {
unsigned fb = props.fb; unsigned fb = props.fb;
@@ -419,7 +461,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->lp = props.lp; p->lp = props.lp;
p->pb = props.pb; p->pb = props.pb;
p->fastMode = (props.algo == 0); p->fastMode = (props.algo == 0);
p->matchFinderBase.btMode = props.btMode; p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
{ {
UInt32 numHashBytes = 4; UInt32 numHashBytes = 4;
if (props.btMode) if (props.btMode)
@@ -463,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11,
static void RangeEnc_Construct(CRangeEnc *p) static void RangeEnc_Construct(CRangeEnc *p)
{ {
p->outStream = 0; p->outStream = NULL;
p->bufBase = 0; p->bufBase = NULL;
} }
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) #define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
@@ -472,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p)
#define RC_BUF_SIZE (1 << 16) #define RC_BUF_SIZE (1 << 16)
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
{ {
if (p->bufBase == 0) if (!p->bufBase)
{ {
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
if (p->bufBase == 0) if (!p->bufBase)
return 0; return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE; p->bufLim = p->bufBase + RC_BUF_SIZE;
} }
@@ -516,7 +558,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
{ {
if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)
{ {
Byte temp = p->cache; Byte temp = p->cache;
do do
@@ -542,7 +584,7 @@ static void RangeEnc_FlushData(CRangeEnc *p)
RangeEnc_ShiftLow(p); RangeEnc_ShiftLow(p);
} }
static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)
{ {
do do
{ {
@@ -605,7 +647,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol,
while (symbol < 0x10000); while (symbol < 0x10000);
} }
void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
{ {
UInt32 i; UInt32 i;
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
@@ -641,7 +683,7 @@ void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] #define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] #define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)
{ {
UInt32 price = 0; UInt32 price = 0;
symbol |= 0x100; symbol |= 0x100;
@@ -654,7 +696,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro
return price; return price;
} }
static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)
{ {
UInt32 price = 0; UInt32 price = 0;
UInt32 offs = 0x100; UInt32 offs = 0x100;
@@ -698,7 +740,7 @@ static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLeve
} }
} }
static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{ {
UInt32 price = 0; UInt32 price = 0;
symbol |= (1 << numBitLevels); symbol |= (1 << numBitLevels);
@@ -710,7 +752,7 @@ static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 s
return price; return price;
} }
static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{ {
UInt32 price = 0; UInt32 price = 0;
UInt32 m = 1; UInt32 m = 1;
@@ -761,7 +803,7 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posSt
} }
} }
static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)
{ {
UInt32 a0 = GET_PRICE_0a(p->choice); UInt32 a0 = GET_PRICE_0a(p->choice);
UInt32 a1 = GET_PRICE_1a(p->choice); UInt32 a1 = GET_PRICE_1a(p->choice);
@@ -784,20 +826,20 @@ static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UIn
prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
} }
static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)
{ {
LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
p->counters[posState] = p->tableSize; p->counters[posState] = p->tableSize;
} }
static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)
{ {
UInt32 posState; UInt32 posState;
for (posState = 0; posState < numPosStates; posState++) for (posState = 0; posState < numPosStates; posState++)
LenPriceEnc_UpdateTable(p, posState, ProbPrices); LenPriceEnc_UpdateTable(p, posState, ProbPrices);
} }
static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)
{ {
LenEnc_Encode(&p->p, rc, symbol, posState); LenEnc_Encode(&p->p, rc, symbol, posState);
if (updatePrice) if (updatePrice)
@@ -811,9 +853,10 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32
static void MovePos(CLzmaEnc *p, UInt32 num) static void MovePos(CLzmaEnc *p, UInt32 num)
{ {
#ifdef SHOW_STAT #ifdef SHOW_STAT
ttt += num; g_STAT_OFFSET += num;
printf("\n MovePos %d", num); printf("\n MovePos %u", num);
#endif #endif
if (num != 0) if (num != 0)
{ {
p->additionalOffset += num; p->additionalOffset += num;
@@ -826,28 +869,32 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
UInt32 lenRes = 0, numPairs; UInt32 lenRes = 0, numPairs;
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
#ifdef SHOW_STAT #ifdef SHOW_STAT
printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
ttt++; g_STAT_OFFSET++;
{ {
UInt32 i; UInt32 i;
for (i = 0; i < numPairs; i += 2) for (i = 0; i < numPairs; i += 2)
printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
} }
#endif #endif
if (numPairs > 0) if (numPairs > 0)
{ {
lenRes = p->matches[numPairs - 2]; lenRes = p->matches[numPairs - 2];
if (lenRes == p->numFastBytes) if (lenRes == p->numFastBytes)
{ {
const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
UInt32 distance = p->matches[numPairs - 1] + 1;
UInt32 numAvail = p->numAvail; UInt32 numAvail = p->numAvail;
if (numAvail > LZMA_MATCH_LEN_MAX) if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX; numAvail = LZMA_MATCH_LEN_MAX;
{ {
const Byte *pby2 = pby - distance; const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); const Byte *pby = pbyCur + lenRes;
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
const Byte *pbyLim = pbyCur + numAvail;
for (; pby != pbyLim && *pby == pby[dif]; pby++);
lenRes = (UInt32)(pby - pbyCur);
} }
} }
} }
@@ -932,7 +979,7 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
return p->optimumCurrentIndex; return p->optimumCurrentIndex;
} }
#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) #define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{ {
@@ -976,7 +1023,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest; UInt32 lenTest;
const Byte *data2; const Byte *data2;
reps[i] = p->reps[i]; reps[i] = p->reps[i];
data2 = data - (reps[i] + 1); data2 = data - reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1]) if (data[0] != data2[0] || data[1] != data2[1])
{ {
repLens[i] = 0; repLens[i] = 0;
@@ -1120,12 +1167,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
cur = 0; cur = 0;
#ifdef SHOW_STAT2 #ifdef SHOW_STAT2
if (position >= 0) /* if (position >= 0) */
{ {
unsigned i; unsigned i;
printf("\n pos = %4X", position); printf("\n pos = %4X", position);
for (i = cur; i <= lenEnd; i++) for (i = cur; i <= lenEnd; i++)
printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
} }
#endif #endif
@@ -1277,7 +1324,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
/* try Literal + rep0 */ /* try Literal + rep0 */
UInt32 temp; UInt32 temp;
UInt32 lenTest2; UInt32 lenTest2;
const Byte *data2 = data - (reps[0] + 1); const Byte *data2 = data - reps[0] - 1;
UInt32 limit = p->numFastBytes + 1; UInt32 limit = p->numFastBytes + 1;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
@@ -1320,7 +1367,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest; UInt32 lenTest;
UInt32 lenTestTemp; UInt32 lenTestTemp;
UInt32 price; UInt32 price;
const Byte *data2 = data - (reps[repIndex] + 1); const Byte *data2 = data - reps[repIndex] - 1;
if (data[0] != data2[0] || data[1] != data2[1]) if (data[0] != data2[0] || data[1] != data2[1])
continue; continue;
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
@@ -1350,13 +1397,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{ {
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
{ {
UInt32 nextRepMatchPrice;
UInt32 state2 = kRepNextStates[state]; UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = UInt32 curAndLenCharPrice =
@@ -1437,16 +1484,16 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
if (/*_maxMode && */lenTest == matches[offs]) if (/*_maxMode && */lenTest == matches[offs])
{ {
/* Try Match + Literal + Rep0 */ /* Try Match + Literal + Rep0 */
const Byte *data2 = data - (curBack + 1); const Byte *data2 = data - curBack - 1;
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
{ {
UInt32 nextRepMatchPrice;
UInt32 state2 = kMatchNextStates[state]; UInt32 state2 = kMatchNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice + UInt32 curAndLenCharPrice = curAndLenPrice +
@@ -1520,7 +1567,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++) for (i = 0; i < LZMA_NUM_REPS; i++)
{ {
UInt32 len; UInt32 len;
const Byte *data2 = data - (p->reps[i] + 1); const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1]) if (data[0] != data2[0] || data[1] != data2[1])
continue; continue;
for (len = 2; len < numAvail && data[len] == data2[len]; len++); for (len = 2; len < numAvail && data[len] == data2[len]; len++);
@@ -1589,7 +1636,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++) for (i = 0; i < LZMA_NUM_REPS; i++)
{ {
UInt32 len, limit; UInt32 len, limit;
const Byte *data2 = data - (p->reps[i] + 1); const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1]) if (data[0] != data2[0] || data[1] != data2[1])
continue; continue;
limit = mainLen - 1; limit = mainLen - 1;
@@ -1685,6 +1732,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
{ {
RangeEnc_Construct(&p->rc); RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase); MatchFinder_Construct(&p->matchFinderBase);
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MatchFinderMt_Construct(&p->matchFinderMt); MatchFinderMt_Construct(&p->matchFinderMt);
p->matchFinderMt.MatchFinder = &p->matchFinderBase; p->matchFinderMt.MatchFinder = &p->matchFinderBase;
@@ -1701,15 +1749,15 @@ void LzmaEnc_Construct(CLzmaEnc *p)
#endif #endif
LzmaEnc_InitPriceTables(p->ProbPrices); LzmaEnc_InitPriceTables(p->ProbPrices);
p->litProbs = 0; p->litProbs = NULL;
p->saveState.litProbs = 0; p->saveState.litProbs = NULL;
} }
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
{ {
void *p; void *p;
p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
if (p != 0) if (p)
LzmaEnc_Construct((CLzmaEnc *)p); LzmaEnc_Construct((CLzmaEnc *)p);
return p; return p;
} }
@@ -1718,8 +1766,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->litProbs); alloc->Free(alloc, p->litProbs);
alloc->Free(alloc, p->saveState.litProbs); alloc->Free(alloc, p->saveState.litProbs);
p->litProbs = 0; p->litProbs = NULL;
p->saveState.litProbs = 0; p->saveState.litProbs = NULL;
} }
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
@@ -1727,6 +1775,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
#endif #endif
MatchFinder_Free(&p->matchFinderBase, allocBig); MatchFinder_Free(&p->matchFinderBase, allocBig);
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
RangeEnc_Free(&p->rc, alloc); RangeEnc_Free(&p->rc, alloc);
@@ -1763,7 +1812,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
ReadMatchDistances(p, &numPairs); ReadMatchDistances(p, &numPairs);
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
p->state = kLiteralNextStates[p->state]; p->state = kLiteralNextStates[p->state];
curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
LitEnc_Encode(&p->rc, p->litProbs, curByte); LitEnc_Encode(&p->rc, p->litProbs, curByte);
p->additionalOffset--; p->additionalOffset--;
nowPos32++; nowPos32++;
@@ -1780,7 +1829,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
len = GetOptimum(p, nowPos32, &pos); len = GetOptimum(p, nowPos32, &pos);
#ifdef SHOW_STAT2 #ifdef SHOW_STAT2
printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
#endif #endif
posState = nowPos32 & p->pbMask; posState = nowPos32 & p->pbMask;
@@ -1889,7 +1938,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
break; break;
} }
else if (processed >= (1 << 15)) else if (processed >= (1 << 17))
{ {
p->nowPos64 += nowPos32 - startPos32; p->nowPos64 += nowPos32 - startPos32;
return CheckErrors(p); return CheckErrors(p);
@@ -1905,22 +1954,21 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
UInt32 beforeSize = kNumOpts; UInt32 beforeSize = kNumOpts;
Bool btMode;
if (!RangeEnc_Alloc(&p->rc, alloc)) if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
btMode = (p->matchFinderBase.btMode != 0);
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
p->mtMode = (p->multiThread && !p->fastMode && btMode); p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
#endif #endif
{ {
unsigned lclp = p->lc + p->lp; unsigned lclp = p->lc + p->lp;
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{ {
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
if (p->litProbs == 0 || p->saveState.litProbs == 0) if (!p->litProbs || !p->saveState.litProbs)
{ {
LzmaEnc_FreeLits(p, alloc); LzmaEnc_FreeLits(p, alloc);
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
@@ -1929,7 +1977,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
} }
} }
p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
if (beforeSize + p->dictSize < keepWindowSize) if (beforeSize + p->dictSize < keepWindowSize)
beforeSize = keepWindowSize - p->dictSize; beforeSize = keepWindowSize - p->dictSize;
@@ -1949,6 +1997,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
p->matchFinderObj = &p->matchFinderBase; p->matchFinderObj = &p->matchFinderBase;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
} }
return SZ_OK; return SZ_OK;
} }
@@ -1977,9 +2026,10 @@ void LzmaEnc_Init(CLzmaEnc *p)
} }
{ {
UInt32 num = 0x300 << (p->lp + p->lc); UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
CLzmaProb *probs = p->litProbs;
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
p->litProbs[i] = kProbInitValue; probs[i] = kProbInitValue;
} }
{ {
@@ -2086,10 +2136,11 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
if (p->mtMode) if (p->mtMode)
MatchFinderMt_ReleaseStream(&p->matchFinderMt); MatchFinderMt_ReleaseStream(&p->matchFinderMt);
#else #else
pp = pp; UNUSED_VAR(pp);
#endif #endif
} }
typedef struct typedef struct
{ {
ISeqOutStream funcTable; ISeqOutStream funcTable;
@@ -2119,12 +2170,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
} }
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
{ {
const CLzmaEnc *p = (CLzmaEnc *)pp; const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
} }
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
{ {
@@ -2159,23 +2212,23 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
return res; return res;
} }
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
Byte allocaDummy[0x300]; Byte allocaDummy[0x300];
int i = 0; allocaDummy[0] = 0;
for (i = 0; i < 16; i++) allocaDummy[1] = allocaDummy[0];
allocaDummy[i] = (Byte)i;
#endif #endif
for (;;) for (;;)
{ {
res = LzmaEnc_CodeOneBlock(p, False, 0, 0); res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
if (res != SZ_OK || p->finished != 0) if (res != SZ_OK || p->finished)
break; break;
if (progress != 0) if (progress)
{ {
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK) if (res != SZ_OK)
@@ -2185,10 +2238,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
} }
} }
} }
LzmaEnc_Finish(p); LzmaEnc_Finish(p);
/*
if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
res = SZ_ERROR_FAIL;
}
*/
return res; return res;
} }
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
ISzAlloc *alloc, ISzAlloc *allocBig) ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
@@ -2196,28 +2258,27 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
} }
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{ {
CLzmaEnc *p = (CLzmaEnc *)pp; CLzmaEnc *p = (CLzmaEnc *)pp;
int i; unsigned i;
UInt32 dictSize = p->dictSize; UInt32 dictSize = p->dictSize;
if (*size < LZMA_PROPS_SIZE) if (*size < LZMA_PROPS_SIZE)
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
*size = LZMA_PROPS_SIZE; *size = LZMA_PROPS_SIZE;
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
for (i = 11; i <= 30; i++) if (dictSize >= ((UInt32)1 << 22))
{ {
if (dictSize <= ((UInt32)2 << i)) UInt32 kDictMask = ((UInt32)1 << 20) - 1;
{ if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
dictSize = (2 << i); dictSize = (dictSize + kDictMask) & ~kDictMask;
break; }
} else for (i = 11; i <= 30; i++)
if (dictSize <= ((UInt32)3 << i)) {
{ if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; }
dictSize = (3 << i); if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; }
break;
}
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@@ -2225,6 +2286,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
return SZ_OK; return SZ_OK;
} }
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
@@ -2233,19 +2295,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
CSeqOutStreamBuf outStream; CSeqOutStreamBuf outStream;
LzmaEnc_SetInputBuf(p, src, srcLen);
outStream.funcTable.Write = MyWrite; outStream.funcTable.Write = MyWrite;
outStream.data = dest; outStream.data = dest;
outStream.rem = *destLen; outStream.rem = *destLen;
outStream.overflow = False; outStream.overflow = False;
p->writeEndMark = writeEndMark; p->writeEndMark = writeEndMark;
p->rc.outStream = &outStream.funcTable; p->rc.outStream = &outStream.funcTable;
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
if (res == SZ_OK) if (res == SZ_OK)
{
res = LzmaEnc_Encode2(p, progress); res = LzmaEnc_Encode2(p, progress);
if (res == SZ_OK && p->nowPos64 != srcLen)
res = SZ_ERROR_FAIL;
}
*destLen -= outStream.rem; *destLen -= outStream.rem;
if (outStream.overflow) if (outStream.overflow)
@@ -2253,13 +2318,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
return res; return res;
} }
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{ {
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
SRes res; SRes res;
if (p == 0) if (!p)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
res = LzmaEnc_SetProps(p, props); res = LzmaEnc_SetProps(p, props);

6
C/LzmaEnc.h Executable file → Normal file
View File

@@ -1,10 +1,10 @@
/* LzmaEnc.h -- LZMA Encoder /* LzmaEnc.h -- LZMA Encoder
2011-01-27 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H #ifndef __LZMA_ENC_H
#define __LZMA_ENC_H #define __LZMA_ENC_H
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
@@ -16,7 +16,7 @@ typedef struct _CLzmaEncProps
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */ default = (1 << 24) */
UInt32 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
Encoder uses this value to reduce dictionary size */ Encoder uses this value to reduce dictionary size */
int lc; /* 0 <= lc <= 8, default = 3 */ int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */ int lp; /* 0 <= lp <= 4, default = 0 */

16
C/LzmaLib.c Executable file → Normal file
View File

@@ -1,18 +1,12 @@
/* LzmaLib.c -- LZMA library wrapper /* LzmaLib.c -- LZMA library wrapper
2008-08-05 2015-06-13 : Igor Pavlov : Public domain */
Igor Pavlov
Public domain */
#include "LzmaEnc.h"
#include "LzmaDec.h"
#include "Alloc.h" #include "Alloc.h"
#include "LzmaDec.h"
#include "LzmaEnc.h"
#include "LzmaLib.h" #include "LzmaLib.h"
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, unsigned char *outProps, size_t *outPropsSize,
int level, /* 0 <= level <= 9, default = 5 */ int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
@@ -38,7 +32,7 @@ MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned cha
} }
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize) const unsigned char *props, size_t propsSize)
{ {
ELzmaStatus status; ELzmaStatus status;

12
C/LzmaLib.h Executable file → Normal file
View File

@@ -1,14 +1,12 @@
/* LzmaLib.h -- LZMA library interface /* LzmaLib.h -- LZMA library interface
2009-04-07 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __LZMA_LIB_H #ifndef __LZMA_LIB_H
#define __LZMA_LIB_H #define __LZMA_LIB_H
#include "Types.h" #include "7zTypes.h"
#ifdef __cplusplus EXTERN_C_BEGIN
extern "C" {
#endif
#define MY_STDAPI int MY_STD_CALL #define MY_STDAPI int MY_STD_CALL
@@ -128,8 +126,6 @@ Returns:
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize); const unsigned char *props, size_t propsSize);
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

6
C/MtCoder.c Executable file → Normal file
View File

@@ -1,7 +1,7 @@
/* MtCoder.c -- Multi-thread Coder /* MtCoder.c -- Multi-thread Coder
2010-09-24 : Igor Pavlov : Public domain */ 2015-10-13 : Igor Pavlov : Public domain */
#include <stdio.h> #include "Precomp.h"
#include "MtCoder.h" #include "MtCoder.h"
@@ -118,7 +118,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
LoopThread_Construct(&p->thread); LoopThread_Construct(&p->thread);
} }
#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; } #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
static void CMtThread_CloseEvents(CMtThread *p) static void CMtThread_CloseEvents(CMtThread *p)
{ {

0
C/MtCoder.h Executable file → Normal file
View File

3
C/Ppmd.h Executable file → Normal file
View File

@@ -1,11 +1,10 @@
/* Ppmd.h -- PPMD codec common code /* Ppmd.h -- PPMD codec common code
2011-01-27 : Igor Pavlov : Public domain 2013-01-18 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
#define __PPMD_H #define __PPMD_H
#include "Types.h"
#include "CpuArch.h" #include "CpuArch.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN

10
C/Ppmd7.c Executable file → Normal file
View File

@@ -1,8 +1,10 @@
/* Ppmd7.c -- PPMdH codec /* Ppmd7.c -- PPMdH codec
2010-03-12 : Igor Pavlov : Public domain 2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include <memory.h> #include "Precomp.h"
#include <string.h>
#include "Ppmd7.h" #include "Ppmd7.h"
@@ -64,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{ {
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { p->Units2Indx[k++] = (Byte)i; } while(--step); do { p->Units2Indx[k++] = (Byte)i; } while (--step);
p->Indx2Units[i] = (Byte)k; p->Indx2Units[i] = (Byte)k;
} }
@@ -255,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
#define MyMem12Cpy(dest, src, num) \ #define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{ {

0
C/Ppmd7.h Executable file → Normal file
View File

2
C/Ppmd7Dec.c Executable file → Normal file
View File

@@ -2,6 +2,8 @@
2010-03-12 : Igor Pavlov : Public domain 2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
#include "Ppmd7.h" #include "Ppmd7.h"
#define kTopValue (1 << 24) #define kTopValue (1 << 24)

6
C/Ppmd7Enc.c Executable file → Normal file
View File

@@ -1,7 +1,9 @@
/* Ppmd7Enc.c -- PPMdH Encoder /* Ppmd7Enc.c -- PPMdH Encoder
2010-03-12 : Igor Pavlov : Public domain 2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
#include "Ppmd7.h" #include "Ppmd7.h"
#define kTopValue (1 << 24) #define kTopValue (1 << 24)
@@ -24,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF; temp = 0xFF;
} }
while(--p->CacheSize != 0); while (--p->CacheSize != 0);
p->Cache = (Byte)((UInt32)p->Low >> 24); p->Cache = (Byte)((UInt32)p->Low >> 24);
} }
p->CacheSize++; p->CacheSize++;

31
C/Ppmd8.c Executable file → Normal file
View File

@@ -1,8 +1,10 @@
/* Ppmd8.c -- PPMdI codec /* Ppmd8.c -- PPMdI codec
2010-03-24 : Igor Pavlov : Public domain 2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
#include <memory.h> #include "Precomp.h"
#include <string.h>
#include "Ppmd8.h" #include "Ppmd8.h"
@@ -65,7 +67,7 @@ void Ppmd8_Construct(CPpmd8 *p)
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{ {
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { p->Units2Indx[k++] = (Byte)i; } while(--step); do { p->Units2Indx[k++] = (Byte)i; } while (--step);
p->Indx2Units[i] = (Byte)k; p->Indx2Units[i] = (Byte)k;
} }
@@ -239,7 +241,7 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
#define MyMem12Cpy(dest, src, num) \ #define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU) static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{ {
@@ -483,10 +485,11 @@ static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order)
} }
if (i == 0) if (i == 0)
{ {
ctx->Flags = (ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40); ctx->Flags = (Byte)((ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
*ONE_STATE(ctx) = *s; *ONE_STATE(ctx) = *s;
FreeUnits(p, s, tmp); FreeUnits(p, s, tmp);
ONE_STATE(ctx)->Freq = (Byte)((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3; /* 9.31: the code was fixed. It's was not BUG, if Freq <= MAX_FREQ = 124 */
ONE_STATE(ctx)->Freq = (Byte)(((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3);
} }
else else
Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i); Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i);
@@ -554,17 +557,17 @@ static void RestoreModel(CPpmd8 *p, CTX_PTR c1
if (--(c->NumStats) == 0) if (--(c->NumStats) == 0)
{ {
s = STATS(c); s = STATS(c);
c->Flags = (c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40); c->Flags = (Byte)((c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40));
*ONE_STATE(c) = *s; *ONE_STATE(c) = *s;
SpecialFreeUnit(p, s); SpecialFreeUnit(p, s);
ONE_STATE(c)->Freq = (ONE_STATE(c)->Freq + 11) >> 3; ONE_STATE(c)->Freq = (Byte)(((unsigned)ONE_STATE(c)->Freq + 11) >> 3);
} }
else else
Refresh(p, c, (c->NumStats+3) >> 1, 0); Refresh(p, c, (c->NumStats+3) >> 1, 0);
for (; c != p->MinContext; c = SUFFIX(c)) for (; c != p->MinContext; c = SUFFIX(c))
if (!c->NumStats) if (!c->NumStats)
ONE_STATE(c)->Freq -= ONE_STATE(c)->Freq >> 1; ONE_STATE(c)->Freq = (Byte)(ONE_STATE(c)->Freq - (ONE_STATE(c)->Freq >> 1));
else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats) else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats)
Refresh(p, c, (c->NumStats + 2) >> 1, 1); Refresh(p, c, (c->NumStats + 2) >> 1, 1);
@@ -636,7 +639,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
else else
{ {
s = ONE_STATE(c); s = ONE_STATE(c);
s->Freq += (!SUFFIX(c)->NumStats & (s->Freq < 24)); s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24)));
} }
successor = SUCCESSOR(s); successor = SUCCESSOR(s);
if (successor != upBranch) if (successor != upBranch)
@@ -651,7 +654,7 @@ static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c
upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch); upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch);
SetSuccessor(&upState, upBranch + 1); SetSuccessor(&upState, upBranch + 1);
flags = 0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40); flags = (Byte)(0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40));
if (c->NumStats == 0) if (c->NumStats == 0)
upState.Freq = ONE_STATE(c)->Freq; upState.Freq = ONE_STATE(c)->Freq;
@@ -743,7 +746,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
else else
{ {
s = ONE_STATE(c); s = ONE_STATE(c);
s->Freq += (s->Freq < 32); s->Freq = (Byte)(s->Freq + (s->Freq < 32));
} }
} }
if (SUCCESSOR(s)) if (SUCCESSOR(s))
@@ -889,7 +892,7 @@ static void UpdateModel(CPpmd8 *p)
#endif #endif
s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq; s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq;
flag = 0x08 * (fSymbol >= 0x40); flag = (Byte)(0x08 * (fSymbol >= 0x40));
for (; c != p->MinContext; c = SUFFIX(c)) for (; c != p->MinContext; c = SUFFIX(c))
{ {
@@ -1012,7 +1015,7 @@ static void Rescale(CPpmd8 *p)
if (tmp.Freq > MAX_FREQ / 3) if (tmp.Freq > MAX_FREQ / 3)
tmp.Freq = MAX_FREQ / 3; tmp.Freq = MAX_FREQ / 3;
InsertNode(p, stats, U2I((numStats + 2) >> 1)); InsertNode(p, stats, U2I((numStats + 2) >> 1));
p->MinContext->Flags = (p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40); p->MinContext->Flags = (Byte)((p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40));
*(p->FoundState = ONE_STATE(p->MinContext)) = tmp; *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
return; return;
} }

0
C/Ppmd8.h Executable file → Normal file
View File

2
C/Ppmd8Dec.c Executable file → Normal file
View File

@@ -4,6 +4,8 @@ This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#include "Precomp.h"
#include "Ppmd8.h" #include "Ppmd8.h"
#define kTop (1 << 24) #define kTop (1 << 24)

2
C/Ppmd8Enc.c Executable file → Normal file
View File

@@ -4,6 +4,8 @@ This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#include "Precomp.h"
#include "Ppmd8.h" #include "Ppmd8.h"
#define kTop (1 << 24) #define kTop (1 << 24)

10
C/Precomp.h Normal file
View File

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

12
C/RotateDefs.h Executable file → Normal file
View File

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

334
C/Sha1.c Normal file
View File

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

38
C/Sha1.h Normal file
View File

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

170
C/Sha256.c Executable file → Normal file
View File

@@ -1,12 +1,21 @@
/* Crypto/Sha256.c -- SHA-256 Hash /* Crypto/Sha256.c -- SHA-256 Hash
2010-06-11 : Igor Pavlov : Public domain 2015-11-14 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */ This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h"
#include <string.h>
#include "CpuArch.h"
#include "RotateDefs.h" #include "RotateDefs.h"
#include "Sha256.h" #include "Sha256.h"
/* define it for speed optimization */ /* define it for speed optimization */
/* #define _SHA256_UNROLL */ #ifndef _SFX
#define _SHA256_UNROLL
#define _SHA256_UNROLL2
#endif
/* #define _SHA256_UNROLL2 */ /* #define _SHA256_UNROLL2 */
void Sha256_Init(CSha256 *p) void Sha256_Init(CSha256 *p)
@@ -27,26 +36,18 @@ void Sha256_Init(CSha256 *p)
#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) #define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) #define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
#define blk0(i) (W[i] = data[i]) #define blk0(i) (W[i])
#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15])) #define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z))) #define Ch(x,y,z) (z^(x&(y^z)))
#define Maj(x,y,z) ((x&y)|(z&(x|y))) #define Maj(x,y,z) ((x&y)|(z&(x|y)))
#define a(i) T[(0-(i))&7]
#define b(i) T[(1-(i))&7]
#define c(i) T[(2-(i))&7]
#define d(i) T[(3-(i))&7]
#define e(i) T[(4-(i))&7]
#define f(i) T[(5-(i))&7]
#define g(i) T[(6-(i))&7]
#define h(i) T[(7-(i))&7]
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\ #define R(a,b,c,d,e,f,g,h, i) \
d += h; h += S0(a) + Maj(a, b, c) h += S1(e) + Ch(e,f,g) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
d += h; \
h += S0(a) + Maj(a, b, c)
#define RX_8(i) \ #define RX_8(i) \
R(a,b,c,d,e,f,g,h, i); \ R(a,b,c,d,e,f,g,h, i); \
@@ -58,14 +59,32 @@ void Sha256_Init(CSha256 *p)
R(c,d,e,f,g,h,a,b, i+6); \ R(c,d,e,f,g,h,a,b, i+6); \
R(b,c,d,e,f,g,h,a, i+7) R(b,c,d,e,f,g,h,a, i+7)
#define RX_16 RX_8(0); RX_8(8);
#else #else
#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\ #define a(i) T[(0-(i))&7]
d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) #define b(i) T[(1-(i))&7]
#define c(i) T[(2-(i))&7]
#define d(i) T[(3-(i))&7]
#define e(i) T[(4-(i))&7]
#define f(i) T[(5-(i))&7]
#define g(i) T[(6-(i))&7]
#define h(i) T[(7-(i))&7]
#define R(i) \
h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
d(i) += h(i); \
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
#ifdef _SHA256_UNROLL #ifdef _SHA256_UNROLL
#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7); #define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
#define RX_16 RX_8(0); RX_8(8);
#else
#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); }
#endif #endif
@@ -90,12 +109,30 @@ static const UInt32 K[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
}; };
static void Sha256_Transform(UInt32 *state, const UInt32 *data) static void Sha256_WriteByteBlock(CSha256 *p)
{ {
UInt32 W[16]; UInt32 W[16];
unsigned j; unsigned j;
UInt32 *state;
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
UInt32 a,b,c,d,e,f,g,h; UInt32 a,b,c,d,e,f,g,h;
#else
UInt32 T[8];
#endif
for (j = 0; j < 16; j += 4)
{
const Byte *ccc = p->buffer + j * 4;
W[j ] = GetBe32(ccc);
W[j + 1] = GetBe32(ccc + 4);
W[j + 2] = GetBe32(ccc + 8);
W[j + 3] = GetBe32(ccc + 12);
}
state = p->state;
#ifdef _SHA256_UNROLL2
a = state[0]; a = state[0];
b = state[1]; b = state[1];
c = state[2]; c = state[2];
@@ -105,19 +142,13 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
g = state[6]; g = state[6];
h = state[7]; h = state[7];
#else #else
UInt32 T[8];
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
T[j] = state[j]; T[j] = state[j];
#endif #endif
for (j = 0; j < 64; j += 16) for (j = 0; j < 64; j += 16)
{ {
#if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2) RX_16
RX_8(0); RX_8(8);
#else
unsigned i;
for (i = 0; i < 16; i++) { R(i); }
#endif
} }
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
@@ -144,61 +175,74 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
#undef s0 #undef s0
#undef s1 #undef s1
static void Sha256_WriteByteBlock(CSha256 *p)
{
UInt32 data32[16];
unsigned i;
for (i = 0; i < 16; i++)
data32[i] =
((UInt32)(p->buffer[i * 4 ]) << 24) +
((UInt32)(p->buffer[i * 4 + 1]) << 16) +
((UInt32)(p->buffer[i * 4 + 2]) << 8) +
((UInt32)(p->buffer[i * 4 + 3]));
Sha256_Transform(p->state, data32);
}
void Sha256_Update(CSha256 *p, const Byte *data, size_t size) void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
{ {
UInt32 curBufferPos = (UInt32)p->count & 0x3F; if (size == 0)
while (size > 0) return;
{ {
p->buffer[curBufferPos++] = *data++; unsigned pos = (unsigned)p->count & 0x3F;
p->count++; unsigned num;
size--;
if (curBufferPos == 64) p->count += size;
num = 64 - pos;
if (num > size)
{ {
curBufferPos = 0; memcpy(p->buffer + pos, data, size);
Sha256_WriteByteBlock(p); return;
} }
size -= num;
memcpy(p->buffer + pos, data, num);
data += num;
} }
for (;;)
{
Sha256_WriteByteBlock(p);
if (size < 64)
break;
size -= 64;
memcpy(p->buffer, data, 64);
data += 64;
}
if (size != 0)
memcpy(p->buffer, data, size);
} }
void Sha256_Final(CSha256 *p, Byte *digest) void Sha256_Final(CSha256 *p, Byte *digest)
{ {
UInt64 lenInBits = (p->count << 3); unsigned pos = (unsigned)p->count & 0x3F;
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
unsigned i; unsigned i;
p->buffer[curBufferPos++] = 0x80;
while (curBufferPos != (64 - 8)) p->buffer[pos++] = 0x80;
while (pos != (64 - 8))
{ {
curBufferPos &= 0x3F; pos &= 0x3F;
if (curBufferPos == 0) if (pos == 0)
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
p->buffer[curBufferPos++] = 0; p->buffer[pos++] = 0;
} }
for (i = 0; i < 8; i++)
{ {
p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56); UInt64 numBits = (p->count << 3);
lenInBits <<= 8; SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
} }
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i += 2)
{ {
*digest++ = (Byte)(p->state[i] >> 24); UInt32 v0 = p->state[i];
*digest++ = (Byte)(p->state[i] >> 16); UInt32 v1 = p->state[i + 1];
*digest++ = (Byte)(p->state[i] >> 8); SetBe32(digest , v0);
*digest++ = (Byte)(p->state[i]); SetBe32(digest + 4, v1);
digest += 8;
} }
Sha256_Init(p); Sha256_Init(p);
} }

4
C/Sha256.h Executable file → Normal file
View File

@@ -1,10 +1,10 @@
/* Sha256.h -- SHA-256 Hash /* Sha256.h -- SHA-256 Hash
2010-06-11 : Igor Pavlov : Public domain */ 2013-01-18 : Igor Pavlov : Public domain */
#ifndef __CRYPTO_SHA256_H #ifndef __CRYPTO_SHA256_H
#define __CRYPTO_SHA256_H #define __CRYPTO_SHA256_H
#include "Types.h" #include "7zTypes.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN

70
C/Sort.c Executable file → Normal file
View File

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

18
C/Sort.h Executable file → Normal file
View File

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

29
C/Threads.c Executable file → Normal file
View File

@@ -1,7 +1,9 @@
/* Threads.c -- multithreading library /* Threads.c -- multithreading library
2009-09-20 : Igor Pavlov : Public domain */ 2014-09-21 : Igor Pavlov : Public domain */
#ifndef _WIN32_WCE #include "Precomp.h"
#ifndef UNDER_CE
#include <process.h> #include <process.h>
#endif #endif
@@ -29,14 +31,21 @@ WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE)
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
{ {
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
*p =
#ifdef UNDER_CE #ifdef UNDER_CE
CreateThread(0, 0, func, param, 0, &threadId);
#else DWORD threadId;
(HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); *p = CreateThread(0, 0, func, param, 0, &threadId);
#endif
/* maybe we must use errno here, but probably GetLastError() is also OK. */ #else
unsigned threadId;
*p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
#endif
/* maybe we must use errno here, but probably GetLastError() is also OK. */
return HandleToWRes(*p); return HandleToWRes(*p);
} }

26
C/Threads.h Executable file → Normal file
View File

@@ -1,15 +1,17 @@
/* Threads.h -- multithreading library /* Threads.h -- multithreading library
2009-03-27 : Igor Pavlov : Public domain */ 2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H #ifndef __7Z_THREADS_H
#define __7Z_THREADS_H #define __7Z_THREADS_H
#include "Types.h" #ifdef _WIN32
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif #endif
#include "7zTypes.h"
EXTERN_C_BEGIN
WRes HandlePtr_Close(HANDLE *h); WRes HandlePtr_Close(HANDLE *h);
WRes Handle_WaitObject(HANDLE h); WRes Handle_WaitObject(HANDLE h);
@@ -18,7 +20,15 @@ typedef HANDLE CThread;
#define Thread_WasCreated(p) (*(p) != NULL) #define Thread_WasCreated(p) (*(p) != NULL)
#define Thread_Close(p) HandlePtr_Close(p) #define Thread_Close(p) HandlePtr_Close(p)
#define Thread_Wait(p) Handle_WaitObject(*(p)) #define Thread_Wait(p) Handle_WaitObject(*(p))
typedef unsigned THREAD_FUNC_RET_TYPE;
typedef
#ifdef UNDER_CE
DWORD
#else
unsigned
#endif
THREAD_FUNC_RET_TYPE;
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL #define THREAD_FUNC_CALL_TYPE MY_STD_CALL
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
@@ -52,8 +62,6 @@ WRes CriticalSection_Init(CCriticalSection *p);
#define CriticalSection_Enter(p) EnterCriticalSection(p) #define CriticalSection_Enter(p) EnterCriticalSection(p)
#define CriticalSection_Leave(p) LeaveCriticalSection(p) #define CriticalSection_Leave(p) LeaveCriticalSection(p)
#ifdef __cplusplus EXTERN_C_END
}
#endif
#endif #endif

45
C/Util/7z/7z.dsp Executable file → Normal file
View File

@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /YX /FD /c # ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG" # ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG" # ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\util\7zDec.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none # SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "7z - Win32 Debug" !ELSEIF "$(CFG)" == "7z - Win32 Debug"
@@ -67,7 +67,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c # ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "_SZ_ALLOC_DEBUG2" /D "_SZ_NO_INT_64_A" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG" # ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG" # ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -75,7 +75,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\util\7zDec.exe" /pdbtype:sept
!ENDIF !ENDIF
@@ -100,6 +100,10 @@ SOURCE=..\..\7zAlloc.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zArcIn.c
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.c SOURCE=..\..\7zBuf.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -133,11 +137,11 @@ SOURCE=..\..\7zFile.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zIn.c SOURCE=..\..\7zStream.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\7zStream.c SOURCE=..\..\7zTypes.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -161,6 +165,10 @@ SOURCE=..\..\Bra86.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\BraIA64.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.c SOURCE=..\..\CpuArch.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -169,6 +177,14 @@ SOURCE=..\..\CpuArch.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Delta.c
# End Source File
# Begin Source File
SOURCE=..\..\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.c SOURCE=..\..\Lzma2Dec.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -190,7 +206,6 @@ SOURCE=..\..\Ppmd.h
# Begin Source File # Begin Source File
SOURCE=..\..\Ppmd7.c SOURCE=..\..\Ppmd7.c
# SUBTRACT CPP /YX
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -199,11 +214,23 @@ SOURCE=..\..\Ppmd7.h
# Begin Source File # Begin Source File
SOURCE=..\..\Ppmd7Dec.c SOURCE=..\..\Ppmd7Dec.c
# SUBTRACT CPP /YX # End Source File
# End Group
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compiler.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\Types.h SOURCE=.\Precomp.c
# ADD CPP /Yc"Precomp.h"
# End Source File
# Begin Source File
SOURCE=.\Precomp.h
# End Source File # End Source File
# End Group # End Group
# Begin Source File # Begin Source File

0
C/Util/7z/7z.dsw Executable file → Normal file
View File

323
C/Util/7z/7zMain.c Executable file → Normal file
View File

@@ -1,11 +1,14 @@
/* 7zMain.c - Test application for 7z Decoder /* 7zMain.c - Test application for 7z Decoder
2010-10-28 : Igor Pavlov : Public domain */ 2015-08-02 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../../7z.h" #include "../../7z.h"
#include "../../7zAlloc.h" #include "../../7zAlloc.h"
#include "../../7zBuf.h"
#include "../../7zCrc.h" #include "../../7zCrc.h"
#include "../../7zFile.h" #include "../../7zFile.h"
#include "../../7zVersion.h" #include "../../7zVersion.h"
@@ -31,106 +34,158 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
} }
#ifndef _WIN32 #ifndef _WIN32
#define _USE_UTF8
#endif
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; /* #define _USE_UTF8 */
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen) #ifdef _USE_UTF8
#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
#define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n)))))
#define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
{ {
size_t destPos = 0, srcPos = 0; size_t size = 0;
for (;;) for (;;)
{ {
unsigned numAdds; UInt32 val;
UInt32 value; if (src == srcLim)
if (srcPos == srcLen) return size;
size++;
val = *src++;
if (val < 0x80)
continue;
if (val < _UTF8_RANGE(1))
{ {
*destLen = destPos; size++;
return True;
}
value = src[srcPos++];
if (value < 0x80)
{
if (dest)
dest[destPos] = (char)value;
destPos++;
continue; continue;
} }
if (value >= 0xD800 && value < 0xE000)
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{ {
UInt32 c2; UInt32 c2 = *src;
if (value >= 0xDC00 || srcPos == srcLen) if (c2 >= 0xDC00 && c2 < 0xE000)
break; {
c2 = src[srcPos++]; src++;
if (c2 < 0xDC00 || c2 >= 0xE000) size += 3;
break; continue;
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; }
} }
for (numAdds = 1; numAdds < 5; numAdds++)
if (value < (((UInt32)1) << (numAdds * 5 + 6))) size += 2;
break; }
if (dest) }
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
destPos++; static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
do {
{ for (;;)
numAdds--; {
if (dest) UInt32 val;
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); if (src == srcLim)
destPos++; return dest;
}
while (numAdds != 0); val = *src++;
if (val < 0x80)
{
*dest++ = (char)val;
continue;
}
if (val < _UTF8_RANGE(1))
{
dest[0] = _UTF8_HEAD(1, val);
dest[1] = _UTF8_CHAR(0, val);
dest += 2;
continue;
}
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
UInt32 c2 = *src;
if (c2 >= 0xDC00 && c2 < 0xE000)
{
src++;
val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
dest[0] = _UTF8_HEAD(3, val);
dest[1] = _UTF8_CHAR(2, val);
dest[2] = _UTF8_CHAR(1, val);
dest[3] = _UTF8_CHAR(0, val);
dest += 4;
continue;
}
}
dest[0] = _UTF8_HEAD(2, val);
dest[1] = _UTF8_CHAR(1, val);
dest[2] = _UTF8_CHAR(0, val);
dest += 3;
} }
*destLen = destPos;
return False;
} }
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen) static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
{ {
size_t destLen = 0; size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
Bool res;
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
destLen += 1; destLen += 1;
if (!Buf_EnsureSize(dest, destLen)) if (!Buf_EnsureSize(dest, destLen))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen); *Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
dest->data[destLen] = 0; return SZ_OK;
return res ? SZ_OK : SZ_ERROR_FAIL;
} }
#endif #endif
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode) static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
#ifndef _USE_UTF8
, UINT codePage
#endif
)
{ {
int len = 0; unsigned len = 0;
for (len = 0; s[len] != '\0'; len++); for (len = 0; s[len] != 0; len++);
#ifdef _WIN32 #ifndef _USE_UTF8
{ {
int size = len * 3 + 100; unsigned size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size)) if (!Buf_EnsureSize(buf, size))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
{ {
char defaultChar = '_'; buf->data[0] = 0;
BOOL defUsed; if (len != 0)
int numChars = WideCharToMultiByte(fileMode ? {
( char defaultChar = '_';
#ifdef UNDER_CE BOOL defUsed;
CP_ACP unsigned numChars = 0;
#else numChars = WideCharToMultiByte(codePage, 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
AreFileApisANSI() ? CP_ACP : CP_OEMCP if (numChars == 0 || numChars >= size)
#endif return SZ_ERROR_FAIL;
) : CP_OEMCP, buf->data[numChars] = 0;
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed); }
if (numChars == 0 || numChars >= size)
return SZ_ERROR_FAIL;
buf->data[numChars] = 0;
return SZ_OK; return SZ_OK;
} }
} }
#else #else
fileMode = fileMode;
return Utf16_To_Utf8Buf(buf, s, len); return Utf16_To_Utf8Buf(buf, s, len);
#endif #endif
} }
#ifdef _WIN32
#ifndef USE_WINDOWS_FILE
static UINT g_FileCodePage = CP_ACP;
#endif
#define MY_FILE_CODE_PAGE_PARAM ,g_FileCodePage
#else
#define MY_FILE_CODE_PAGE_PARAM
#endif
static WRes MyCreateDir(const UInt16 *name) static WRes MyCreateDir(const UInt16 *name)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
@@ -142,7 +197,7 @@ static WRes MyCreateDir(const UInt16 *name)
CBuf buf; CBuf buf;
WRes res; WRes res;
Buf_Init(&buf); Buf_Init(&buf);
RINOK(Utf16_To_Char(&buf, name, 1)); RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
res = res =
#ifdef _WIN32 #ifdef _WIN32
@@ -165,7 +220,7 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
CBuf buf; CBuf buf;
WRes res; WRes res;
Buf_Init(&buf); Buf_Init(&buf);
RINOK(Utf16_To_Char(&buf, name, 1)); RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
res = OutFile_Open(p, (const char *)buf.data); res = OutFile_Open(p, (const char *)buf.data);
Buf_Free(&buf, &g_Alloc); Buf_Free(&buf, &g_Alloc);
return res; return res;
@@ -177,7 +232,11 @@ static SRes PrintString(const UInt16 *s)
CBuf buf; CBuf buf;
SRes res; SRes res;
Buf_Init(&buf); Buf_Init(&buf);
res = Utf16_To_Char(&buf, s, 0); res = Utf16_To_Char(&buf, s
#ifndef _USE_UTF8
, CP_OEMCP
#endif
);
if (res == SZ_OK) if (res == SZ_OK)
fputs((const char *)buf.data, stdout); fputs((const char *)buf.data, stdout);
Buf_Free(&buf, &g_Alloc); Buf_Free(&buf, &g_Alloc);
@@ -216,17 +275,24 @@ static char *UIntToStr(char *s, unsigned value, int numDigits)
return s; return s;
} }
static void UIntToStr_2(char *s, unsigned value)
{
s[0] = (char)('0' + (value / 10));
s[1] = (char)('0' + (value % 10));
}
#define PERIOD_4 (4 * 365 + 1) #define PERIOD_4 (4 * 365 + 1)
#define PERIOD_100 (PERIOD_4 * 25 - 1) #define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1) #define PERIOD_400 (PERIOD_100 * 4 + 1)
static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s) static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
{ {
unsigned year, mon, day, hour, min, sec; unsigned year, mon, hour, min, sec;
UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000;
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned t; unsigned t;
UInt32 v; UInt32 v;
UInt64 v64 = nt->Low | ((UInt64)nt->High << 32);
v64 /= 10000000;
sec = (unsigned)(v64 % 60); v64 /= 60; sec = (unsigned)(v64 % 60); v64 /= 60;
min = (unsigned)(v64 % 60); v64 /= 60; min = (unsigned)(v64 % 60); v64 /= 60;
hour = (unsigned)(v64 % 24); v64 /= 24; hour = (unsigned)(v64 % 24); v64 /= 24;
@@ -242,20 +308,19 @@ static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
ms[1] = 29; ms[1] = 29;
for (mon = 1; mon <= 12; mon++) for (mon = 0;; mon++)
{ {
unsigned s = ms[mon - 1]; unsigned s = ms[mon];
if (v < s) if (v < s)
break; break;
v -= s; v -= s;
} }
day = (unsigned)v + 1;
s = UIntToStr(s, year, 4); *s++ = '-'; s = UIntToStr(s, year, 4); *s++ = '-';
s = UIntToStr(s, mon, 2); *s++ = '-'; UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
s = UIntToStr(s, day, 2); *s++ = ' '; UIntToStr_2(s, (unsigned)v + 1); s[2] = ' '; s += 3;
s = UIntToStr(s, hour, 2); *s++ = ':'; UIntToStr_2(s, hour); s[2] = ':'; s += 3;
s = UIntToStr(s, min, 2); *s++ = ':'; UIntToStr_2(s, min); s[2] = ':'; s += 3;
s = UIntToStr(s, sec, 2); UIntToStr_2(s, sec); s[2] = 0;
} }
void PrintError(char *sz) void PrintError(char *sz)
@@ -263,23 +328,22 @@ void PrintError(char *sz)
printf("\nERROR: %s\n", sz); printf("\nERROR: %s\n", sz);
} }
#ifdef USE_WINDOWS_FILE
#define kEmptyAttribChar '.'
static void GetAttribString(UInt32 wa, Bool isDir, char *s) static void GetAttribString(UInt32 wa, Bool isDir, char *s)
{ {
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar); #ifdef USE_WINDOWS_FILE
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar); s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar); s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar); s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar); s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
s[5] = '\0'; s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
s[5] = 0;
#else
s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.');
s[1] = 0;
#endif
} }
#else
static void GetAttribString(UInt32, Bool, char *s) // #define NUM_PARENTS_MAX 128
{
s[0] = '\0';
}
#endif
int MY_CDECL main(int numargs, char *args[]) int MY_CDECL main(int numargs, char *args[])
{ {
@@ -291,8 +355,10 @@ int MY_CDECL main(int numargs, char *args[])
ISzAlloc allocTempImp; ISzAlloc allocTempImp;
UInt16 *temp = NULL; UInt16 *temp = NULL;
size_t tempSize = 0; size_t tempSize = 0;
// UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
if (numargs == 1) if (numargs == 1)
{ {
printf( printf(
@@ -304,19 +370,28 @@ int MY_CDECL main(int numargs, char *args[])
" x: eXtract files with full paths\n"); " x: eXtract files with full paths\n");
return 0; return 0;
} }
if (numargs < 3) if (numargs < 3)
{ {
PrintError("incorrect command"); PrintError("incorrect command");
return 1; return 1;
} }
#if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE)
g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
allocImp.Alloc = SzAlloc; allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree; allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp; allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp; allocTempImp.Free = SzFreeTemp;
#ifdef UNDER_CE
if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
#else
if (InFile_Open(&archiveStream.file, args[2])) if (InFile_Open(&archiveStream.file, args[2]))
#endif
{ {
PrintError("can not open input file"); PrintError("can not open input file");
return 1; return 1;
@@ -331,15 +406,18 @@ int MY_CDECL main(int numargs, char *args[])
CrcGenerateTable(); CrcGenerateTable();
SzArEx_Init(&db); SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp); res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if (res == SZ_OK) if (res == SZ_OK)
{ {
char *command = args[1]; char *command = args[1];
int listCommand = 0, testCommand = 0, extractCommand = 0, fullPaths = 0; int listCommand = 0, testCommand = 0, fullPaths = 0;
if (strcmp(command, "l") == 0) listCommand = 1; if (strcmp(command, "l") == 0) listCommand = 1;
else if (strcmp(command, "t") == 0) testCommand = 1; else if (strcmp(command, "t") == 0) testCommand = 1;
else if (strcmp(command, "e") == 0) extractCommand = 1; else if (strcmp(command, "e") == 0) { }
else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; } else if (strcmp(command, "x") == 0) { fullPaths = 1; }
else else
{ {
PrintError("incorrect command"); PrintError("incorrect command");
@@ -358,22 +436,24 @@ int MY_CDECL main(int numargs, char *args[])
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */ Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */ size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
for (i = 0; i < db.db.NumFiles; i++) for (i = 0; i < db.NumFiles; i++)
{ {
size_t offset = 0; size_t offset = 0;
size_t outSizeProcessed = 0; size_t outSizeProcessed = 0;
const CSzFileItem *f = db.db.Files + i; // const CSzFileItem *f = db.Files + i;
size_t len; size_t len;
if (listCommand == 0 && f->IsDir && !fullPaths) unsigned isDir = SzArEx_IsDir(&db, i);
if (listCommand == 0 && isDir && !fullPaths)
continue; continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL); len = SzArEx_GetFileNameUtf16(&db, i, NULL);
// len = SzArEx_GetFullNameLen(&db, i);
if (len > tempSize) if (len > tempSize)
{ {
SzFree(NULL, temp); SzFree(NULL, temp);
tempSize = len; tempSize = len;
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0])); temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
if (temp == 0) if (!temp)
{ {
res = SZ_ERROR_MEM; res = SZ_ERROR_MEM;
break; break;
@@ -381,15 +461,26 @@ int MY_CDECL main(int numargs, char *args[])
} }
SzArEx_GetFileNameUtf16(&db, i, temp); SzArEx_GetFileNameUtf16(&db, i, temp);
/*
if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp)
{
res = SZ_ERROR_FAIL;
break;
}
*/
if (listCommand) if (listCommand)
{ {
char attr[8], s[32], t[32]; char attr[8], s[32], t[32];
UInt64 fileSize;
GetAttribString(f->AttribDefined ? f->Attrib : 0, f->IsDir, attr); GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
UInt64ToStr(f->Size, s); fileSize = SzArEx_GetFileSize(&db, i);
if (f->MTimeDefined) UInt64ToStr(fileSize, s);
ConvertFileTimeToString(&f->MTime, t);
if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t);
else else
{ {
size_t j; size_t j;
@@ -402,11 +493,12 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp); res = PrintString(temp);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (f->IsDir) if (isDir)
printf("/"); printf("/");
printf("\n"); printf("\n");
continue; continue;
} }
fputs(testCommand ? fputs(testCommand ?
"Testing ": "Testing ":
"Extracting ", "Extracting ",
@@ -414,7 +506,8 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp); res = PrintString(temp);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (f->IsDir)
if (isDir)
printf("/"); printf("/");
else else
{ {
@@ -425,6 +518,7 @@ int MY_CDECL main(int numargs, char *args[])
if (res != SZ_OK) if (res != SZ_OK)
break; break;
} }
if (!testCommand) if (!testCommand)
{ {
CSzFile outFile; CSzFile outFile;
@@ -432,6 +526,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t j; size_t j;
UInt16 *name = (UInt16 *)temp; UInt16 *name = (UInt16 *)temp;
const UInt16 *destPath = (const UInt16 *)name; const UInt16 *destPath = (const UInt16 *)name;
for (j = 0; name[j] != 0; j++) for (j = 0; name[j] != 0; j++)
if (name[j] == '/') if (name[j] == '/')
{ {
@@ -445,7 +540,7 @@ int MY_CDECL main(int numargs, char *args[])
destPath = name + j + 1; destPath = name + j + 1;
} }
if (f->IsDir) if (isDir)
{ {
MyCreateDir(destPath); MyCreateDir(destPath);
printf("\n"); printf("\n");
@@ -457,22 +552,26 @@ int MY_CDECL main(int numargs, char *args[])
res = SZ_ERROR_FAIL; res = SZ_ERROR_FAIL;
break; break;
} }
processedSize = outSizeProcessed; processedSize = outSizeProcessed;
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed) if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{ {
PrintError("can not write output file"); PrintError("can not write output file");
res = SZ_ERROR_FAIL; res = SZ_ERROR_FAIL;
break; break;
} }
if (File_Close(&outFile)) if (File_Close(&outFile))
{ {
PrintError("can not close output file"); PrintError("can not close output file");
res = SZ_ERROR_FAIL; res = SZ_ERROR_FAIL;
break; break;
} }
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
if (f->AttribDefined) if (SzBitWithVals_Check(&db.Attribs, i))
SetFileAttributesW(destPath, f->Attrib); SetFileAttributesW(destPath, db.Attribs.Vals[i]);
#endif #endif
} }
printf("\n"); printf("\n");
@@ -480,15 +579,18 @@ int MY_CDECL main(int numargs, char *args[])
IAlloc_Free(&allocImp, outBuffer); IAlloc_Free(&allocImp, outBuffer);
} }
} }
SzArEx_Free(&db, &allocImp); SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp); SzFree(NULL, temp);
File_Close(&archiveStream.file); File_Close(&archiveStream.file);
if (res == SZ_OK) if (res == SZ_OK)
{ {
printf("\nEverything is Ok\n"); printf("\nEverything is Ok\n");
return 0; return 0;
} }
if (res == SZ_ERROR_UNSUPPORTED) if (res == SZ_ERROR_UNSUPPORTED)
PrintError("decoder doesn't support this archive"); PrintError("decoder doesn't support this archive");
else if (res == SZ_ERROR_MEM) else if (res == SZ_ERROR_MEM)
@@ -497,5 +599,6 @@ int MY_CDECL main(int numargs, char *args[])
PrintError("CRC error"); PrintError("CRC error");
else else
printf("\nERROR #%d\n", res); printf("\nERROR #%d\n", res);
return 1; return 1;
} }

4
C/Util/7z/Precomp.c Normal file
View File

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

10
C/Util/7z/Precomp.h Normal file
View File

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

13
C/Util/7z/makefile Executable file → Normal file
View File

@@ -1,4 +1,3 @@
MY_STATIC_LINK=1
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe PROG = 7zDec.exe
@@ -6,17 +5,18 @@ PROG = 7zDec.exe
C_OBJS = \ C_OBJS = \
$O\7zAlloc.obj \ $O\7zAlloc.obj \
$O\7zBuf.obj \ $O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \ $O\7zCrc.obj \
$O\7zCrcOpt.obj \ $O\7zCrcOpt.obj \
$O\7zFile.obj \ $O\7zFile.obj \
$O\7zDec.obj \ $O\7zDec.obj \
$O\7zIn.obj \ $O\7zArcIn.obj \
$O\7zStream.obj \ $O\7zStream.obj \
$O\Bcj2.obj \ $O\Bcj2.obj \
$O\Bra.obj \ $O\Bra.obj \
$O\Bra86.obj \ $O\Bra86.obj \
$O\BraIA64.obj \
$O\CpuArch.obj \ $O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \ $O\Lzma2Dec.obj \
$O\LzmaDec.obj \ $O\LzmaDec.obj \
$O\Ppmd7.obj \ $O\Ppmd7.obj \
@@ -26,12 +26,15 @@ C_OBJS = \
$O\7zMain.obj \ $O\7zMain.obj \
OBJS = \ OBJS = \
$O\Precomp.obj \
$(7Z_OBJS) \ $(7Z_OBJS) \
$(C_OBJS) \ $(C_OBJS) \
!include "../../../CPP/Build.mak" !include "../../../CPP/Build.mak"
$(7Z_OBJS): $(*B).c $(7Z_OBJS): $(*B).c
$(COMPL_O1) $(CCOMPL_USE)
$(C_OBJS): ../../$(*B).c $(C_OBJS): ../../$(*B).c
$(COMPL_O2) $(CCOMPL_USE)
$O\Precomp.obj: Precomp.c
$(CCOMPL_PCH)

18
C/Util/7z/makefile.gcc Executable file → Normal file
View File

@@ -1,10 +1,10 @@
PROG = 7zDec PROG = 7zDec
CXX = g++ CXX = gcc
LIB = LIB =
RM = rm -f RM = rm -f
CFLAGS = -c -O2 -Wall CFLAGS = -c -O2 -Wall
OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o Delta.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o BraIA64.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
all: $(PROG) all: $(PROG)
@@ -14,9 +14,12 @@ $(PROG): $(OBJS)
7zMain.o: 7zMain.c 7zMain.o: 7zMain.c
$(CXX) $(CFLAGS) 7zMain.c $(CXX) $(CFLAGS) 7zMain.c
7zAlloc.o: 7zAlloc.c 7zAlloc.o: ../../7zAlloc.c
$(CXX) $(CFLAGS) ../../7zAlloc.c $(CXX) $(CFLAGS) ../../7zAlloc.c
7zArcIn.o: ../../7zArcIn.c
$(CXX) $(CFLAGS) ../../7zArcIn.c
7zBuf.o: ../../7zBuf.c 7zBuf.o: ../../7zBuf.c
$(CXX) $(CFLAGS) ../../7zBuf.c $(CXX) $(CFLAGS) ../../7zBuf.c
@@ -32,12 +35,12 @@ $(PROG): $(OBJS)
7zDec.o: ../../7zDec.c 7zDec.o: ../../7zDec.c
$(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c $(CXX) $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT ../../7zDec.c
7zIn.o: ../../7zIn.c
$(CXX) $(CFLAGS) ../../7zIn.c
CpuArch.o: ../../CpuArch.c CpuArch.o: ../../CpuArch.c
$(CXX) $(CFLAGS) ../../CpuArch.c $(CXX) $(CFLAGS) ../../CpuArch.c
Delta.o: ../../Delta.c
$(CXX) $(CFLAGS) ../../Delta.c
LzmaDec.o: ../../LzmaDec.c LzmaDec.o: ../../LzmaDec.c
$(CXX) $(CFLAGS) ../../LzmaDec.c $(CXX) $(CFLAGS) ../../LzmaDec.c
@@ -50,6 +53,9 @@ Bra.o: ../../Bra.c
Bra86.o: ../../Bra86.c Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c $(CXX) $(CFLAGS) ../../Bra86.c
BraIA64.o: ../../BraIA64.c
$(CXX) $(CFLAGS) ../../BraIA64.c
Bcj2.o: ../../Bcj2.c Bcj2.o: ../../Bcj2.c
$(CXX) $(CFLAGS) ../../Bcj2.c $(CXX) $(CFLAGS) ../../Bcj2.c

BIN
C/Util/7zipInstall/7zip.ico Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,231 @@
# Microsoft Developer Studio Project File - Name="7zipInstall" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=7zipInstall - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "7zipInstall.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "7zipInstall.mak" CFG="7zipInstall - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "7zipInstall - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "7zipInstall - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "7zipInstall - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "7zipInstall - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "7zipInstall - Win32 Release"
# Name "7zipInstall - Win32 Debug"
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\7z.h
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zArcIn.c
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.h
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zCrcOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\7zDec.c
# End Source File
# Begin Source File
SOURCE=..\..\7zFile.c
# End Source File
# Begin Source File
SOURCE=..\..\7zFile.h
# End Source File
# Begin Source File
SOURCE=..\..\7zStream.c
# End Source File
# Begin Source File
SOURCE=..\..\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\7zVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\Bcj2.c
# End Source File
# Begin Source File
SOURCE=..\..\Bcj2.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra.c
# End Source File
# Begin Source File
SOURCE=..\..\Bra.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
SOURCE=..\..\BraIA64.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\Delta.c
# End Source File
# Begin Source File
SOURCE=..\..\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.h
# End Source File
# End Group
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Precomp.c
# ADD CPP /Yc"Precomp.h"
# End Source File
# Begin Source File
SOURCE=.\Precomp.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\7zipInstall.c
# End Source File
# Begin Source File
SOURCE=.\resource.rc
# End Source File
# End Target
# End Project

View File

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

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7zipInstall" type="win32"/>
<description>7-Zip Installer</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges></security></trustInfo>
<dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
<asmv3:application><asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware></asmv3:windowsSettings></asmv3:application>
</assembly>

View File

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

View File

@@ -0,0 +1,11 @@
/* Precomp.h -- StdAfx
2015-05-24 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "../../Compiler.h"
#include "../../7zTypes.h"
#endif

View File

@@ -0,0 +1,40 @@
PROG = 7zipInstall.exe
!IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
!ENDIF
CFLAGS = $(CFLAGS) -D_LZMA_SIZE_OPT
CFLAGS = $(CFLAGS) \
-D_7Z_NO_METHOD_LZMA2 \
-D_7Z_NO_METHODS_FILTERS
MAIN_OBJS = \
$O\7zipInstall.obj \
C_OBJS = \
$O\7zAlloc.obj \
$O\7zArcIn.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\CpuArch.obj \
$O\LzmaDec.obj \
OBJS = \
$(MAIN_OBJS) \
$(C_OBJS) \
$O\resource.res
!include "../../../CPP/Build.mak"
$(MAIN_OBJS): $(*B).c
$(COMPL_O1)
$(C_OBJS): ../../$(*B).c
$(COMPL_O1)

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