Compare commits

...

39 Commits

Author SHA1 Message Date
glachancecmaisonneuve
e75ad3d355 19.0 2019-03-28 14:13:17 -04:00
Kornel Lesiński
ff14e3badb Github info 2019-03-12 07:42:06 -04:00
Igor Pavlov
5c10d25476 19.00 2019-03-12 07:31:25 -04:00
glachancecmaisonneuve
5d7485c7d9 Merge 18.06 in Easy7Zip 2019-02-21 08:47:28 -05:00
glachancecmaisonneuve
758c3790d3 v7 2019-02-18 14:00:27 -05:00
Kornel
50a695679a Merge pull request #2 from gongminmin/bug/FixRedefine
Fix the redefinition of ERROR_NEGATIVE_SEEK
2019-01-15 11:33:39 +00:00
Minmin Gong
04d04adea5 Fix the redefinition of ERROR_NEGATIVE_SEEK 2019-01-13 18:06:35 -08:00
Kornel
cb75c2b5bf Merge commit '5b2a99c548a6c9c90d4cc63cddca29af009c2479'
* commit '5b2a99c548a6c9c90d4cc63cddca29af009c2479':
  18.06
2018-12-30 14:02:42 +00:00
Igor Pavlov
5b2a99c548 18.06 2018-12-30 14:01:47 +00:00
glachancecmaisonneuve
f623539c73 v7 2018-12-22 19:18:21 -05:00
glachancecmaisonneuve
c287fb0519 for integrated debugging purposes 2018-11-24 13:35:02 -05:00
glachancecmaisonneuve
9b07a1847f fixes delete after extract 2018-11-24 13:31:40 -05:00
Guillaume Lachance
cc9036aad9 Update README.md 2018-09-05 01:21:44 -04:00
glachancecmaisonneuve
42fa923138 Jame's Easy7Zip changes, translocated from 16 to 18.05 2018-09-05 01:02:45 -04:00
glachancecmaisonneuve
b82b3e5533 Project files are not used in this branch for building.
build.cmd and makefiles are kept up-to-date with upstream instead.
2018-09-05 01:00:35 -04:00
Kornel
20e38032e6 Merge commit '18dc2b41613055f0daf7f6a1d4311368798ea12a'
* commit '18dc2b41613055f0daf7f6a1d4311368798ea12a':
  18.05
2018-05-02 22:32:18 +01:00
Igor Pavlov
18dc2b4161 18.05 2018-05-02 22:28:04 +01:00
Kornel
801aad2d7c Merge tag '18.03' 2018-03-12 11:20:57 +00:00
Igor Pavlov
f19b649c73 18.03 2018-03-12 11:19:46 +00:00
Kornel Lesiński
e3dc4878fe Github info 2018-01-30 00:35:28 +00:00
Igor Pavlov
866a06f5a0 18.01 2018-01-30 00:35:06 +00:00
Igor Pavlov
da28077952 18.00 2018-01-11 22:16:32 +01:00
Igor Pavlov
b5dc853b24 17.01 2017-08-29 20:49:43 +01:00
Igor Pavlov
2efa10565a 17.00 2017-05-05 18:56:20 +01:00
Igor Pavlov
603abd5528 16.04 2016-12-08 12:13:50 +00:00
Igor Pavlov
232ce79574 16.03 2016-12-08 12:12:54 +00:00
Igor Pavlov
1eddf527ca 16.02 2016-05-28 00:17:00 +01:00
Igor Pavlov
bec3b479dc 16.01 2016-05-28 00:16:59 +01:00
Igor Pavlov
66ac98bb02 16.00 2016-05-28 00:16:59 +01:00
Igor Pavlov
c20d013055 15.14 2016-05-28 00:16:58 +01:00
Igor Pavlov
9608215ad8 15.13 2016-05-28 00:16:58 +01:00
Igor Pavlov
5de23c1deb 15.12 2016-05-28 00:16:58 +01:00
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
883 changed files with 92134 additions and 53829 deletions

18
.gitignore vendored Normal file
View File

@@ -0,0 +1,18 @@
*.o
out/
7zAll/x64/
*.pdb
*.tlog
*.obj
*.user
*.log
*.pch
*.idb
x64/
*.exe
*.res
*.dll
*.lib
*.exp
*.sfx
*.txt

41
7zAll/7zAll.sln Normal file
View File

@@ -0,0 +1,41 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2048
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "7zFM", "..\CPP\7zip\UI\FileManager\FM.vcxproj", "{2628FF64-E1E1-4CB7-B588-08DE7145B630}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "7zG", "..\CPP\7zip\UI\GUI\GUI.vcxproj", "{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugU|Win32 = DebugU|Win32
DebugU|x64 = DebugU|x64
ReleaseU|Win32 = ReleaseU|Win32
ReleaseU|x64 = ReleaseU|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.DebugU|Win32.ActiveCfg = DebugU|Win32
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.DebugU|Win32.Build.0 = DebugU|Win32
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.DebugU|x64.ActiveCfg = DebugU|x64
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.DebugU|x64.Build.0 = DebugU|x64
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.ReleaseU|Win32.ActiveCfg = ReleaseU|Win32
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.ReleaseU|Win32.Build.0 = ReleaseU|Win32
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.ReleaseU|x64.ActiveCfg = ReleaseU|x64
{2628FF64-E1E1-4CB7-B588-08DE7145B630}.ReleaseU|x64.Build.0 = ReleaseU|x64
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.DebugU|Win32.ActiveCfg = DebugU|Win32
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.DebugU|Win32.Build.0 = DebugU|Win32
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.DebugU|x64.ActiveCfg = DebugU|x64
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.DebugU|x64.Build.0 = DebugU|x64
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.ReleaseU|Win32.ActiveCfg = ReleaseU|Win32
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.ReleaseU|Win32.Build.0 = ReleaseU|Win32
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.ReleaseU|x64.ActiveCfg = ReleaseU|x64
{D4BC12CF-49F2-474D-BAF6-EAC069DB7D6C}.ReleaseU|x64.Build.0 = ReleaseU|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BF7D9E83-83E0-4B40-B356-AA6A664D563E}
EndGlobalSection
EndGlobal

View File

@@ -1,5 +1,5 @@
; 7zAsm.asm -- ASM macros ; 7zAsm.asm -- ASM macros
; 2012-12-30 : Igor Pavlov : Public domain ; 2018-02-03 : Igor Pavlov : Public domain
MY_ASM_START macro MY_ASM_START macro
ifdef x64 ifdef x64
@@ -52,6 +52,15 @@ endif
x6 equ ESI x6 equ ESI
x7 equ EDI x7 equ EDI
x0_W equ AX
x1_W equ CX
x2_W equ DX
x3_W equ BX
x5_W equ BP
x6_W equ SI
x7_W equ DI
x0_L equ AL x0_L equ AL
x1_L equ CL x1_L equ CL
x2_L equ DL x2_L equ DL
@@ -63,6 +72,10 @@ endif
x3_H equ BH x3_H equ BH
ifdef x64 ifdef x64
x5_L equ BPL
x6_L equ SIL
x7_L equ DIL
r0 equ RAX r0 equ RAX
r1 equ RCX r1 equ RCX
r2 equ RDX r2 equ RDX
@@ -103,3 +116,32 @@ MY_POP_4_REGS macro
pop r5 pop r5
pop r3 pop r3
endm endm
ifdef x64
; for WIN64-x64 ABI:
REG_PARAM_0 equ r1
REG_PARAM_1 equ r2
REG_PARAM_2 equ r8
REG_PARAM_3 equ r9
MY_PUSH_PRESERVED_REGS macro
MY_PUSH_4_REGS
push r12
push r13
push r14
push r15
endm
MY_POP_PRESERVED_REGS macro
pop r15
pop r14
pop r13
pop r12
MY_POP_4_REGS
endm
endif

1258
Asm/x86/LzmaDecOpt.asm Normal file
View File

File diff suppressed because it is too large Load Diff

158
C/7z.h
View File

@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface /* 7z.h -- 7z interface
2013-01-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_H #ifndef __7Z_H
#define __7Z_H #define __7Z_H
@@ -11,7 +11,7 @@ EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20 #define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6 #define k7zSignatureSize 6
extern Byte k7zSignature[k7zSignatureSize]; extern const Byte k7zSignature[k7zSignatureSize];
typedef struct typedef struct
{ {
@@ -25,8 +25,7 @@ typedef struct
{ {
size_t PropsOffset; size_t PropsOffset;
UInt32 MethodID; UInt32 MethodID;
Byte NumInStreams; Byte NumStreams;
Byte NumOutStreams;
Byte PropsSize; Byte PropsSize;
} CSzCoderInfo; } CSzCoderInfo;
@@ -34,37 +33,25 @@ typedef struct
{ {
UInt32 InIndex; UInt32 InIndex;
UInt32 OutIndex; UInt32 OutIndex;
} CSzBindPair; } CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4 #define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BINDS_IN_FOLDER_MAX 3 #define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4 #define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
#define SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX 4
typedef struct typedef struct
{ {
UInt32 NumCoders; UInt32 NumCoders;
UInt32 NumBindPairs; UInt32 NumBonds;
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 MainOutStream; UInt32 UnpackStream;
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBindPair BindPairs[SZ_NUM_BINDS_IN_FOLDER_MAX]; CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
} CSzFolder; } CSzFolder;
/*
typedef struct
{
size_t CodersDataOffset;
size_t UnpackSizeDataOffset;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 StartPackStreamIndex;
// UInt32 IndexOfMainOutStream;
} CSzFolder2;
*/
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes); SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct typedef struct
{ {
@@ -94,29 +81,77 @@ typedef struct
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 NumFolders; UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1 UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs; CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets; size_t *FoCodersOffsets; // NumFolders + 1
size_t *FoSizesOffsets; UInt32 *FoStartPackStreamIndex; // NumFolders + 1
// UInt32 StartCoderUnpackSizesIndex; UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders
// CSzFolder2 *Folders; // +1 item for sum values
Byte *CodersData; Byte *CodersData;
Byte *UnpackSizesData;
size_t UnpackSizesDataSize;
// UInt64 *CoderUnpackSizes;
} CSzAr; } CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos, ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain); ISzAllocPtr allocMain);
typedef struct
{
CSzAr db;
UInt64 startPosAfterHeader;
UInt64 dataPos;
UInt32 NumFiles;
UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles;
Byte *IsDirs;
CSzBitUi32s CRCs;
CSzBitUi32s Attribs;
// CSzBitUi32s Parents;
CSzBitUi64s MTime;
CSzBitUi64s CTime;
UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
} 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_Free(CSzArEx *p, ISzAllocPtr alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/* /*
SzExtract extracts file from archive if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/*
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/
/*
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive. *outBuffer must be 0 before first call for each new archive.
@@ -135,55 +170,6 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
Free *outBuffer and set *outBuffer to 0, if you want to flush cache. Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/ */
typedef struct
{
CSzAr db;
UInt64 startPosAfterHeader;
UInt64 dataPos;
UInt32 NumFiles;
UInt64 *UnpackPositions;
// Byte *IsEmptyFiles;
Byte *IsDirs;
CSzBitUi32s CRCs;
CSzBitUi32s Attribs;
// CSzBitUi32s Parents;
CSzBitUi64s MTime;
CSzBitUi64s CTime;
// UInt32 *FolderStartPackStreamIndex;
UInt32 *FolderStartFileIndex; // + 1
UInt32 *FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
} 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_Free(CSzArEx *p, ISzAlloc *alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/*
if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/*
size_t SzArEx_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,
@@ -193,8 +179,8 @@ SRes SzArEx_Extract(
size_t *outBufferSize, /* buffer size for output buffer */ size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */ size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */ size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain, ISzAllocPtr allocMain,
ISzAlloc *allocTemp); ISzAllocPtr allocTemp);
/* /*
@@ -209,7 +195,7 @@ SZ_ERROR_FAIL
*/ */
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp); ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
EXTERN_C_END EXTERN_C_END

View File

@@ -1,8 +1,10 @@
/* 7zAlloc.c -- Allocation functions /* 7zAlloc.c -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdlib.h>
#include "7zAlloc.h" #include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */ /* #define _SZ_ALLOC_DEBUG */
@@ -20,21 +22,21 @@ int g_allocCountTemp = 0;
#endif #endif
void *SzAlloc(void *p, size_t size) void *SzAlloc(ISzAllocPtr 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);
} }
void SzFree(void *p, void *address) void SzFree(ISzAllocPtr p, void *address)
{ {
p = p; UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) if (address != 0)
{ {
@@ -45,13 +47,13 @@ void SzFree(void *p, void *address)
free(address); free(address);
} }
void *SzAllocTemp(void *p, size_t size) void *SzAllocTemp(ISzAllocPtr 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,9 +62,9 @@ void *SzAllocTemp(void *p, size_t size)
return malloc(size); return malloc(size);
} }
void SzFreeTemp(void *p, void *address) void SzFreeTemp(ISzAllocPtr p, void *address)
{ {
p = p; UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) if (address != 0)
{ {

View File

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

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* 7zBuf.c -- Byte Buffer /* 7zBuf.c -- Byte Buffer
2013-01-21 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -11,7 +11,7 @@ void Buf_Init(CBuf *p)
p->size = 0; p->size = 0;
} }
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
{ {
p->size = 0; p->size = 0;
if (size == 0) if (size == 0)
@@ -19,8 +19,8 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
p->data = 0; p->data = 0;
return 1; return 1;
} }
p->data = (Byte *)alloc->Alloc(alloc, size); p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
if (p->data != 0) if (p->data)
{ {
p->size = size; p->size = size;
return 1; return 1;
@@ -28,9 +28,9 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
return 0; return 0;
} }
void Buf_Free(CBuf *p, ISzAlloc *alloc) void Buf_Free(CBuf *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->data); ISzAlloc_Free(alloc, p->data);
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
} }

View File

@@ -1,5 +1,5 @@
/* 7zBuf.h -- Byte Buffer /* 7zBuf.h -- Byte Buffer
2013-01-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H #ifndef __7Z_BUF_H
#define __7Z_BUF_H #define __7Z_BUF_H
@@ -15,8 +15,8 @@ typedef struct
} CBuf; } CBuf;
void Buf_Init(CBuf *p); void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
void Buf_Free(CBuf *p, ISzAlloc *alloc); void Buf_Free(CBuf *p, ISzAllocPtr alloc);
typedef struct typedef struct
{ {
@@ -27,8 +27,8 @@ typedef struct
void DynBuf_Construct(CDynBuf *p); void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p); void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

View File

@@ -1,5 +1,5 @@
/* 7zBuf2.c -- Byte Buffer /* 7zBuf2.c -- Byte Buffer
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -19,29 +19,33 @@ void DynBuf_SeekToBeg(CDynBuf *p)
p->pos = 0; p->pos = 0;
} }
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc) int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
{ {
if (size > p->size - p->pos) if (size > p->size - p->pos)
{ {
size_t newSize = p->pos + size; size_t newSize = p->pos + size;
Byte *data; Byte *data;
newSize += newSize / 4; newSize += newSize / 4;
data = (Byte *)alloc->Alloc(alloc, newSize); data = (Byte *)ISzAlloc_Alloc(alloc, newSize);
if (data == 0) if (!data)
return 0; return 0;
p->size = newSize; p->size = newSize;
memcpy(data, p->data, p->pos); if (p->pos != 0)
alloc->Free(alloc, p->data); memcpy(data, p->data, p->pos);
ISzAlloc_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;
} }
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc) void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->data); ISzAlloc_Free(alloc, p->data);
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
p->pos = 0; p->pos = 0;

View File

@@ -1,5 +1,5 @@
/* 7zCrc.c -- CRC32 init /* 7zCrc.c -- CRC32 init
2013-11-12 : Igor Pavlov : Public domain */ 2017-06-06 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -8,24 +8,28 @@
#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);
CRC_FUNC g_CrcUpdateT4;
CRC_FUNC g_CrcUpdateT8;
CRC_FUNC g_CrcUpdate; CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
@@ -38,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;
@@ -46,40 +61,68 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = i; UInt32 r = i;
unsigned j; unsigned j;
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
g_CrcTable[i] = r; g_CrcTable[i] = r;
} }
for (; i < 256 * CRC_NUM_TABLES; i++) for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
{ {
UInt32 r = g_CrcTable[i - 256]; UInt32 r = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
} }
#if CRC_NUM_TABLES < 4
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 #if CRC_NUM_TABLES >= 8
if (!CPU_Is_InOrder()) g_CrcUpdateT8 = CrcUpdateT8;
g_CrcUpdate = CrcUpdateT8;
#endif #ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder())
#endif
g_CrcUpdate = CrcUpdateT8;
#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
{ {
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{ {
UInt32 x = g_CrcTable[i - 256]; UInt32 x = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x); g_CrcTable[i] = CRC_UINT32_SWAP(x);
} }
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4; g_CrcUpdate = CrcUpdateT1_BeT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
g_CrcUpdate = CrcUpdateT1_BeT8;
#endif
} }
} }
#endif #endif
#endif
} }

View File

@@ -1,14 +1,14 @@
/* 7zCrcOpt.c -- CRC32 calculation /* 7zCrcOpt.c -- CRC32 calculation
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #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;
@@ -18,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);
@@ -30,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
@@ -40,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

324
C/7zDec.c
View File

@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2014-06-16 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -8,10 +8,12 @@
/* #define _7ZIP_PPMD_SUPPPORT */ /* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h" #include "7z.h"
#include "7zCrc.h"
#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
@@ -19,14 +21,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
@@ -34,28 +39,28 @@
typedef struct typedef struct
{ {
IByteIn p; IByteIn vt;
const Byte *cur; const Byte *cur;
const Byte *end; const Byte *end;
const Byte *begin; const Byte *begin;
UInt64 processed; UInt64 processed;
Bool extra; BoolInt extra;
SRes res; SRes res;
ILookInStream *inStream; const ILookInStream *inStream;
} CByteInToLook; } CByteInToLook;
static Byte ReadByte(void *pp) static Byte ReadByte(const IByteIn *pp)
{ {
CByteInToLook *p = (CByteInToLook *)pp; CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
if (p->cur != p->end) if (p->cur != p->end)
return *p->cur++; return *p->cur++;
if (p->res == SZ_OK) if (p->res == SZ_OK)
{ {
size_t size = p->cur - p->begin; size_t size = p->cur - p->begin;
p->processed += size; p->processed += size;
p->res = p->inStream->Skip(p->inStream, size); p->res = ILookInStream_Skip(p->inStream, size);
size = (1 << 25); size = (1 << 25);
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
p->cur = p->begin; p->cur = p->begin;
p->end = p->begin + size; p->end = p->begin + size;
if (size != 0) if (size != 0)
@@ -65,14 +70,14 @@ static Byte ReadByte(void *pp)
return 0; return 0;
} }
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{ {
CPpmd7 ppmd; CPpmd7 ppmd;
CByteInToLook s; CByteInToLook s;
SRes res = SZ_OK; SRes res = SZ_OK;
s.p.Read = ReadByte; s.vt.Read = ReadByte;
s.inStream = inStream; s.inStream = inStream;
s.begin = s.end = s.cur = NULL; s.begin = s.end = s.cur = NULL;
s.extra = False; s.extra = False;
@@ -98,7 +103,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
{ {
CPpmd7z_RangeDec rc; CPpmd7z_RangeDec rc;
Ppmd7z_RangeDec_CreateVTable(&rc); Ppmd7z_RangeDec_CreateVTable(&rc);
rc.Stream = &s.p; rc.Stream = &s.vt;
if (!Ppmd7z_RangeDec_Init(&rc)) if (!Ppmd7z_RangeDec_Init(&rc))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
else if (s.extra) else if (s.extra)
@@ -108,7 +113,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
SizeT i; SizeT i;
for (i = 0; i < outSize; i++) for (i = 0; i < outSize; i++)
{ {
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
if (s.extra || sym < 0) if (s.extra || sym < 0)
break; break;
outBuffer[i] = (Byte)sym; outBuffer[i] = (Byte)sym;
@@ -127,7 +132,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, 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, ISzAllocPtr allocMain)
{ {
CLzmaDec state; CLzmaDec state;
SRes res = SZ_OK; SRes res = SZ_OK;
@@ -140,11 +145,11 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
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 = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -156,15 +161,24 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
inSize -= inProcessed; inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{ {
if (state.dicBufSize != outSize || lookahead != 0 || if (outSize != state.dicPos || inSize != 0)
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
res = inStream->Skip((void *)inStream, inProcessed);
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
} }
@@ -174,8 +188,11 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
return res; return res;
} }
#ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{ {
CLzma2Dec state; CLzma2Dec state;
SRes res = SZ_OK; SRes res = SZ_OK;
@@ -190,11 +207,11 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
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 = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -206,14 +223,21 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
inSize -= inProcessed; inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{ {
if (state.decoder.dicBufSize != outSize || lookahead != 0 || if (outSize != state.decoder.dicPos || inSize != 0)
(status != LZMA_STATUS_FINISHED_WITH_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
res = inStream->Skip((void *)inStream, inProcessed);
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
} }
@@ -223,32 +247,37 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
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(ILookInStream_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);
outBuffer += curSize; outBuffer += curSize;
inSize -= curSize; inSize -= curSize;
RINOK(inStream->Skip((void *)inStream, curSize)); RINOK(ILookInStream_Skip(inStream, curSize));
} }
return SZ_OK; return SZ_OK;
} }
static Bool IS_MAIN_METHOD(UInt32 m) static BoolInt 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
@@ -257,16 +286,15 @@ static Bool IS_MAIN_METHOD(UInt32 m)
return False; return False;
} }
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) static BoolInt 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)
{ {
@@ -276,51 +304,64 @@ 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)
{ {
const CSzCoderInfo *c = &f->Coders[1]; const CSzCoderInfo *c = &f->Coders[1];
if ( if (
/* c->MethodID > (UInt32)0xFFFFFFFF || */ /* c->MethodID > (UInt32)0xFFFFFFFF || */
c->NumInStreams != 1 || c->NumStreams != 1
c->NumOutStreams != 1 || || f->NumPackStreams != 1
f->NumPackStreams != 1 || || f->PackStreams[0] != 0
f->PackStreams[0] != 0 || || f->NumBonds != 1
f->NumBindPairs != 1 || || f->Bonds[0].InIndex != 1
f->BindPairs[0].InIndex != 1 || || f->Bonds[0].OutIndex != 0)
f->BindPairs[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;
} }
@@ -331,7 +372,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
const UInt64 *unpackSizes, const UInt64 *unpackSizes,
const UInt64 *packPositions, const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
Byte *tempBuf[]) Byte *tempBuf[])
{ {
UInt32 ci; UInt32 ci;
@@ -363,8 +404,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
outSizeCur = (SizeT)unpackSize; outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize) if (outSizeCur != unpackSize)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); temp = (Byte *)ISzAlloc_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;
@@ -380,7 +421,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
offset = packPositions[si]; offset = packPositions[si];
inSize = packPositions[si + 1] - offset; inSize = packPositions[(size_t)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)
@@ -393,101 +434,158 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
{ {
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, 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(propsData + coder->PropsOffset, coder->PropsSize, 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(propsData + coder->PropsOffset, coder->PropsSize, 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 = packPositions[1]; UInt64 offset = packPositions[1];
UInt64 s3Size = packPositions[2] - offset; 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 *)ISzAlloc_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)
res = Bcj2_Decode( RINOK(LookInStream_SeekTo(inStream, startPos + offset));
tempBuf3, tempSize3, RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1], if ((tempSizes[0] & 3) != 0 ||
tempBuf[2], tempSizes[2], (tempSizes[1] & 3) != 0 ||
outBuffer, outSize); tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
RINOK(res) return SZ_ERROR_DATA;
}
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 SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos, ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain) ISzAllocPtr allocMain)
{ {
SRes res; SRes res;
CSzFolder folder; CSzFolder folder;
CSzData sd; CSzData sd;
CSzData sdSizes;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data; sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex]; res = SzGetNextFolderItem(&folder, &sd);
sdSizes.Size =
p->FoSizesOffsets[folderIndex + 1] -
p->FoSizesOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd, &sdSizes);
if (res != SZ_OK) if (res != SZ_OK)
return res; return res;
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.MainOutStream]) if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
{ {
int i; unsigned i;
Byte *tempBuf[3] = { 0, 0, 0}; Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex], p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos, inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf); outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); ISzAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res; return res;
} }
} }

View File

@@ -1,5 +1,5 @@
/* 7zFile.c -- File IO /* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -238,49 +238,49 @@ WRes File_GetLength(CSzFile *p, UInt64 *length)
/* ---------- FileSeqInStream ---------- */ /* ---------- FileSeqInStream ---------- */
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CFileSeqInStream *p = (CFileSeqInStream *)pp; CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
} }
void FileSeqInStream_CreateVTable(CFileSeqInStream *p) void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
{ {
p->s.Read = FileSeqInStream_Read; p->vt.Read = FileSeqInStream_Read;
} }
/* ---------- FileInStream ---------- */ /* ---------- FileInStream ---------- */
static SRes FileInStream_Read(void *pp, void *buf, size_t *size) static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
{ {
CFileInStream *p = (CFileInStream *)pp; CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
} }
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin) static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
{ {
CFileInStream *p = (CFileInStream *)pp; CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return File_Seek(&p->file, pos, origin); return File_Seek(&p->file, pos, origin);
} }
void FileInStream_CreateVTable(CFileInStream *p) void FileInStream_CreateVTable(CFileInStream *p)
{ {
p->s.Read = FileInStream_Read; p->vt.Read = FileInStream_Read;
p->s.Seek = FileInStream_Seek; p->vt.Seek = FileInStream_Seek;
} }
/* ---------- FileOutStream ---------- */ /* ---------- FileOutStream ---------- */
static size_t FileOutStream_Write(void *pp, const void *data, size_t size) static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
{ {
CFileOutStream *p = (CFileOutStream *)pp; CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
File_Write(&p->file, data, &size); File_Write(&p->file, data, &size);
return size; return size;
} }
void FileOutStream_CreateVTable(CFileOutStream *p) void FileOutStream_CreateVTable(CFileOutStream *p)
{ {
p->s.Write = FileOutStream_Write; p->vt.Write = FileOutStream_Write;
} }

View File

@@ -1,5 +1,5 @@
/* 7zFile.h -- File IO /* 7zFile.h -- File IO
2013-01-18 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H #ifndef __7Z_FILE_H
#define __7Z_FILE_H #define __7Z_FILE_H
@@ -54,7 +54,7 @@ WRes File_GetLength(CSzFile *p, UInt64 *length);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
CSzFile file; CSzFile file;
} CFileSeqInStream; } CFileSeqInStream;
@@ -63,7 +63,7 @@ void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct typedef struct
{ {
ISeekInStream s; ISeekInStream vt;
CSzFile file; CSzFile file;
} CFileInStream; } CFileInStream;
@@ -72,7 +72,7 @@ void FileInStream_CreateVTable(CFileInStream *p);
typedef struct typedef struct
{ {
ISeqOutStream s; ISeqOutStream vt;
CSzFile file; CSzFile file;
} CFileOutStream; } CFileOutStream;

View File

@@ -1,5 +1,5 @@
/* 7zStream.c -- 7z Stream functions /* 7zStream.c -- 7z Stream functions
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -7,12 +7,12 @@
#include "7zTypes.h" #include "7zTypes.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); RINOK(ISeqInStream_Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((Byte *)buf + processed); buf = (void *)((Byte *)buf + processed);
@@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT
return SZ_OK; return SZ_OK;
} }
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
{ {
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
{ {
size_t processed = 1; size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed)); RINOK(ISeqInStream_Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
} }
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
{ {
Int64 t = offset; Int64 t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET); return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
} }
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
{ {
const void *lookBuf; const void *lookBuf;
if (*size == 0) if (*size == 0)
return SZ_OK; return SZ_OK;
RINOK(stream->Look(stream, &lookBuf, size)); RINOK(ILookInStream_Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size); memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size); return ILookInStream_Skip(stream, *size);
} }
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); RINOK(ILookInStream_Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((Byte *)buf + processed); buf = (void *)((Byte *)buf + processed);
@@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro
return SZ_OK; return SZ_OK;
} }
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
{ {
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) if (size2 == 0 && *size != 0)
{ {
p->pos = 0; p->pos = 0;
size2 = LookToRead_BUF_SIZE; p->size = 0;
res = p->realStream->Read(p->realStream, p->buf, &size2); size2 = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, &size2);
p->size = size2; p->size = size2;
} }
if (size2 < *size) if (*size > size2)
*size = size2; *size = size2;
*buf = p->buf + p->pos; *buf = p->buf + p->pos;
return res; return res;
} }
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) if (size2 == 0 && *size != 0)
{ {
p->pos = 0; p->pos = 0;
if (*size > LookToRead_BUF_SIZE) p->size = 0;
*size = LookToRead_BUF_SIZE; if (*size > p->bufSize)
res = p->realStream->Read(p->realStream, p->buf, size); *size = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, size);
size2 = p->size = *size; size2 = p->size = *size;
} }
if (size2 < *size) if (*size > size2)
*size = size2; *size = size2;
*buf = p->buf + p->pos; *buf = p->buf + p->pos;
return res; return res;
} }
static SRes LookToRead_Skip(void *pp, size_t offset) static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
{ {
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
p->pos += offset; p->pos += offset;
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead_Read(void *pp, void *buf, size_t *size) static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
{ {
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
size_t rem = p->size - p->pos; size_t rem = p->size - p->pos;
if (rem == 0) if (rem == 0)
return p->realStream->Read(p->realStream, buf, size); return ISeekInStream_Read(p->realStream, buf, size);
if (rem > *size) if (rem > *size)
rem = *size; rem = *size;
memcpy(buf, p->buf + p->pos, rem); memcpy(buf, p->buf + p->pos, rem);
@@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
{ {
CLookToRead *p = (CLookToRead *)pp; GET_LookToRead2
p->pos = p->size = 0; p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin); return ISeekInStream_Seek(p->realStream, pos, origin);
} }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead) void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
{ {
p->s.Look = lookahead ? p->vt.Look = lookahead ?
LookToRead_Look_Lookahead : LookToRead2_Look_Lookahead :
LookToRead_Look_Exact; LookToRead2_Look_Exact;
p->s.Skip = LookToRead_Skip; p->vt.Skip = LookToRead2_Skip;
p->s.Read = LookToRead_Read; p->vt.Read = LookToRead2_Read;
p->s.Seek = LookToRead_Seek; p->vt.Seek = LookToRead2_Seek;
} }
void LookToRead_Init(CLookToRead *p)
{
p->pos = p->size = 0;
}
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CSecToLook *p = (CSecToLook *)pp; CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
return LookInStream_LookRead(p->realStream, buf, size); return LookInStream_LookRead(p->realStream, buf, size);
} }
void SecToLook_CreateVTable(CSecToLook *p) void SecToLook_CreateVTable(CSecToLook *p)
{ {
p->s.Read = SecToLook_Read; p->vt.Read = SecToLook_Read;
} }
static SRes SecToRead_Read(void *pp, void *buf, size_t *size) static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
{ {
CSecToRead *p = (CSecToRead *)pp; CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
return p->realStream->Read(p->realStream, buf, size); return ILookInStream_Read(p->realStream, buf, size);
} }
void SecToRead_CreateVTable(CSecToRead *p) void SecToRead_CreateVTable(CSecToRead *p)
{ {
p->s.Read = SecToRead_Read; p->vt.Read = SecToRead_Read;
} }

View File

@@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types /* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */ 2018-08-04 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
@@ -42,13 +42,23 @@ EXTERN_C_BEGIN
typedef int SRes; typedef int SRes;
#ifdef _WIN32 #ifdef _WIN32
/* typedef DWORD WRes; */ /* typedef DWORD WRes; */
typedef unsigned WRes; typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else #else
typedef int WRes; typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif #endif
@@ -93,7 +103,8 @@ typedef UInt32 SizeT;
typedef size_t SizeT; typedef size_t SizeT;
#endif #endif
typedef int Bool; typedef int BoolInt;
/* typedef BoolInt Bool; */
#define True 1 #define True 1
#define False 0 #define False 0
@@ -112,48 +123,72 @@ typedef int Bool;
#define MY_NO_INLINE #define MY_NO_INLINE
#endif #endif
#define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl #define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall #define MY_FAST_CALL __fastcall
#else #else
#define MY_NO_INLINE #define MY_NO_INLINE
#define MY_FORCE_INLINE
#define MY_CDECL #define MY_CDECL
#define MY_FAST_CALL #define MY_FAST_CALL
/* inline keyword : for C++ / C99 */
/* GCC, clang: */
/*
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline))
#endif
*/
#endif #endif
/* The following interfaces use first parameter as pointer to structure */ /* The following interfaces use first parameter as pointer to structure */
typedef struct typedef struct IByteIn IByteIn;
struct IByteIn
{ {
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn; };
#define IByteIn_Read(p) (p)->Read(p)
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct typedef struct IByteOut IByteOut;
struct IByteOut
{ {
SRes (*Read)(void *p, void *buf, size_t *size); void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
} ISeqInStream; };
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */ /* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct
typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{ {
size_t (*Write)(void *p, const void *buf, size_t size); size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes. /* Returns: result - the number of actually written bytes.
(result < size) means error */ (result < size) means error */
} ISeqOutStream; };
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum typedef enum
{ {
@@ -162,78 +197,162 @@ typedef enum
SZ_SEEK_END = 2 SZ_SEEK_END = 2
} ESzSeek; } ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{ {
SRes (*Look)(void *p, const void **buf, size_t *size); SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed (output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset); SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */ /* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size); SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */ /* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
} ILookInStream; };
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); #define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); #define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */ /* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct typedef struct
{ {
ILookInStream s; ILookInStream vt;
ISeekInStream *realStream; const ISeekInStream *realStream;
size_t pos; size_t pos;
size_t size; size_t size; /* it's data size */
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead; /* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
ILookInStream *realStream; const ILookInStream *realStream;
} CSecToLook; } CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p); void SecToLook_CreateVTable(CSecToLook *p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
ILookInStream *realStream; const ILookInStream *realStream;
} CSecToRead; } CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p); void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
typedef struct ICompressProgress ICompressProgress;
struct ICompressProgress
{ {
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break. /* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */ Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress; };
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{ {
void *(*Alloc)(void *p, size_t size); void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */ void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
} ISzAlloc; };
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef MY_container_of
/*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32 #ifdef _WIN32

View File

@@ -1,10 +1,27 @@
#define MY_VER_MAJOR 9 #define MY_VER_MAJOR 19
#define MY_VER_MINOR 38 #define MY_VER_MINOR 00
#define MY_VER_BUILD 00 #define MY_VER_BUILD 0
#define MY_VERSION "9.38 beta" #define MY_VERSION_NUMBERS "19.00"
// #define MY_7ZIP_VERSION "9.38" #define MY_VERSION MY_VERSION_NUMBERS
#define MY_DATE "2015-01-03"
#ifdef MY_CPU_NAME
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
#else
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2019-02-21"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_COPYRIGHT ": Igor Pavlov : Public domain" #define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
#else
#define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif
#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE

98
C/Aes.c
View File

@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption /* Aes.c -- AES encryption / decryption
2013-11-12 : Igor Pavlov : Public domain */ 2017-01-24 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -7,7 +7,7 @@
#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,
@@ -40,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)
@@ -49,23 +49,30 @@ static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0
#define gb0(x) ( (x) & 0xFF) #define gb0(x) ( (x) & 0xFF)
#define gb1(x) (((x) >> ( 8)) & 0xFF) #define gb1(x) (((x) >> ( 8)) & 0xFF)
#define gb2(x) (((x) >> (16)) & 0xFF) #define gb2(x) (((x) >> (16)) & 0xFF)
#define gb3(x) (((x) >> (24)) & 0xFF) #define gb3(x) (((x) >> (24)))
#define gb(n, x) gb ## n(x)
#define TT(x) (T + (x << 8))
#define DD(x) (D + (x << 8))
void AesGenTables(void) void AesGenTables(void)
{ {
unsigned i; unsigned i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
InvS[Sbox[i]] = (Byte)i; InvS[Sbox[i]] = (Byte)i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
{ {
UInt32 a1 = Sbox[i]; UInt32 a1 = Sbox[i];
UInt32 a2 = xtime(a1); UInt32 a2 = xtime(a1);
UInt32 a3 = a2 ^ a1; UInt32 a3 = a2 ^ a1;
T[ i] = Ui32(a2, a1, a1, a3); TT(0)[i] = Ui32(a2, a1, a1, a3);
T[0x100 + i] = Ui32(a3, a2, a1, a1); TT(1)[i] = Ui32(a3, a2, a1, a1);
T[0x200 + i] = Ui32(a1, a3, a2, a1); TT(2)[i] = Ui32(a1, a3, a2, a1);
T[0x300 + i] = Ui32(a1, a1, a3, a2); TT(3)[i] = Ui32(a1, a1, a3, a2);
} }
{ {
UInt32 a1 = InvS[i]; UInt32 a1 = InvS[i];
@@ -76,15 +83,17 @@ void AesGenTables(void)
UInt32 aB = a8 ^ a2 ^ a1; UInt32 aB = a8 ^ a2 ^ a1;
UInt32 aD = a8 ^ a4 ^ a1; UInt32 aD = a8 ^ a4 ^ a1;
UInt32 aE = a8 ^ a4 ^ a2; UInt32 aE = a8 ^ a4 ^ a2;
D[ i] = Ui32(aE, a9, aD, aB); DD(0)[i] = Ui32(aE, a9, aD, aB);
D[0x100 + i] = Ui32(aB, aE, a9, aD); DD(1)[i] = Ui32(aB, aE, a9, aD);
D[0x200 + i] = Ui32(aD, aB, aE, a9); DD(2)[i] = Ui32(aD, aB, aE, a9);
D[0x300 + i] = Ui32(a9, aD, aB, aE); DD(3)[i] = Ui32(a9, aD, aB, aE);
} }
} }
g_AesCbc_Encode = AesCbc_Encode; g_AesCbc_Encode = AesCbc_Encode;
g_AesCbc_Decode = AesCbc_Decode; g_AesCbc_Decode = AesCbc_Decode;
g_AesCtr_Code = AesCtr_Code; g_AesCtr_Code = AesCtr_Code;
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported()) if (CPU_Is_Aes_Supported())
{ {
@@ -95,36 +104,40 @@ void AesGenTables(void)
#endif #endif
} }
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])]
#define HT4(m, i, s, p) m[i] = \ #define HT4(m, i, s, p) m[i] = \
HT(i, 0, s) ^ \ HT(i, 0, s) ^ \
HT(i, 1, s) ^ \ HT(i, 1, s) ^ \
HT(i, 2, s) ^ \ HT(i, 2, s) ^ \
HT(i, 3, s) ^ w[p + i] HT(i, 3, s) ^ w[p + i]
/* such order (2031) in HT16 is for VC6/K8 speed optimization) */
#define HT16(m, s, p) \
HT4(m, 2, s, p); \
HT4(m, 0, s, p); \
HT4(m, 3, s, p); \
HT4(m, 1, s, p); \
#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])] #define HT16(m, s, p) \
HT4(m, 0, 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 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) DD(x)[gb(x, s[(i - x) & 3])]
#define HD4(m, i, s, p) m[i] = \ #define HD4(m, i, s, p) m[i] = \
HD(i, 0, s) ^ \ HD(i, 0, s) ^ \
HD(i, 1, s) ^ \ HD(i, 1, s) ^ \
HD(i, 2, s) ^ \ HD(i, 2, s) ^ \
HD(i, 3, s) ^ w[p + i]; HD(i, 3, s) ^ w[p + i];
/* 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];
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
@@ -140,7 +153,7 @@ void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
for (; i < wSize; i++) for (; i < wSize; i++)
{ {
UInt32 t = w[i - 1]; UInt32 t = w[(size_t)i - 1];
unsigned rem = i % keySize; unsigned rem = i % keySize;
if (rem == 0) if (rem == 0)
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
@@ -160,16 +173,16 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
{ {
UInt32 r = w[i]; UInt32 r = w[i];
w[i] = w[i] =
D[ Sbox[gb0(r)]] ^ DD(0)[Sbox[gb0(r)]] ^
D[0x100 + Sbox[gb1(r)]] ^ DD(1)[Sbox[gb1(r)]] ^
D[0x200 + Sbox[gb2(r)]] ^ DD(2)[Sbox[gb2(r)]] ^
D[0x300 + Sbox[gb3(r)]]; DD(3)[Sbox[gb3(r)]];
} }
} }
/* Aes_Encode and Aes_Decode functions work with little-endian words. /* Aes_Encode and Aes_Decode functions work with little-endian words.
src and dest are pointers to 4 UInt32 words. src and dest are pointers to 4 UInt32 words.
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,16 +282,25 @@ void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
for (; numBlocks != 0; numBlocks--) for (; numBlocks != 0; numBlocks--)
{ {
UInt32 temp[4]; UInt32 temp[4];
Byte buf[16]; unsigned 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 + 4, temp[1]); for (i = 0; i < 4; i++, data += 4)
SetUi32(buf + 8, temp[2]); {
SetUi32(buf + 12, temp[3]); UInt32 t = temp[i];
for (i = 0; i < 16; i++)
*data++ ^= buf[i]; #ifdef MY_CPU_LE_UNALIGN
*((UInt32 *)data) ^= t;
#else
data[0] ^= (t & 0xFF);
data[1] ^= ((t >> 8) & 0xFF);
data[2] ^= ((t >> 16) & 0xFF);
data[3] ^= ((t >> 24));
#endif
}
} }
} }

View File

@@ -1,12 +1,12 @@
/* AesOpt.c -- Intel's AES /* AesOpt.c -- Intel's AES
2013-11-12 : Igor Pavlov : Public domain */ 2017-06-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h" #include "CpuArch.h"
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
#if _MSC_VER >= 1500 #if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729)
#define USE_INTEL_AES #define USE_INTEL_AES
#endif #endif
#endif #endif

396
C/Alloc.c
View File

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

View File

@@ -1,14 +1,12 @@
/* Alloc.h -- Memory allocation functions /* Alloc.h -- Memory allocation functions
2009-02-07 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H #ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H #define __COMMON_ALLOC_H
#include <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,23 @@ void BigFree(void *address);
#endif #endif
#ifdef __cplusplus extern const ISzAlloc g_Alloc;
} extern const ISzAlloc g_BigAlloc;
#endif extern const ISzAlloc g_MidAlloc;
extern const ISzAlloc g_AlignedAlloc;
typedef struct
{
ISzAlloc vt;
ISzAllocPtr baseAlloc;
unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
} CAlignOffsetAlloc;
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
EXTERN_C_END
#endif #endif

333
C/Bcj2.c
View File

@@ -1,134 +1,257 @@
/* Bcj2.c -- Converter for x86 code (BCJ2) /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2008-10-04 : Igor Pavlov : Public domain */ 2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "CpuArch.h"
#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;
buffer = buf3; if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
bufferLim = buffer + size3; {
RC_INIT2 p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
if (outSize == 0) p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
return SZ_OK; }
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[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
p->state++;
p->dest = dest + 1;
}
}
/*
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)
{
p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
p->temp[3] = (Byte)val;
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;
} }

150
C/Bcj2.h
View File

@@ -1,5 +1,5 @@
/* Bcj2.h -- Converter for x86 code (BCJ2) /* Bcj2.h -- BCJ2 Converter for x86 code
2013-01-18 : Igor Pavlov : Public domain */ 2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H #ifndef __BCJ2_H
#define __BCJ2_H #define __BCJ2_H
@@ -8,26 +8,138 @@
EXTERN_C_BEGIN EXTERN_C_BEGIN
#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
*/
typedef struct
{
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 EXTERN_C_END

311
C/Bcj2Enc.c Normal file
View File

@@ -0,0 +1,311 @@
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
2019-02-02 : 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 <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 BoolInt 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]);
BoolInt 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;
EBcj2Enc_FinishMode 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[(size_t)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);
}

279
C/Bra.c
View File

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

View File

@@ -1,5 +1,5 @@
/* Bra86.c -- Converter for x86 code (BCJ) /* Bra86.c -- Converter for x86 code (BCJ)
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
else else
{ {
mask >>= (unsigned)d; mask >>= (unsigned)d;
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
{ {
mask = (mask >> 1) | 4; mask = (mask >> 1) | 4;
pos++; pos++;

View File

@@ -1,69 +1,53 @@
/* BraIA64.c -- Converter for IA-64 code /* BraIA64.c -- Converter for IA-64 code
2013-11-12 : Igor Pavlov : Public domain */ 2017-01-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include "CpuArch.h"
#include "Bra.h" #include "Bra.h"
static const Byte kBranchTable[32] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 6, 6, 0, 0, 7, 7,
4, 4, 0, 0, 4, 4, 0, 0
};
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; SizeT i;
if (size < 16) if (size < 16)
return 0; return 0;
size -= 16; size -= 16;
for (i = 0; i <= size; i += 16) i = 0;
do
{ {
UInt32 instrTemplate = data[i] & 0x1F; unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
UInt32 mask = kBranchTable[instrTemplate]; if (m)
UInt32 bitPos = 5;
int slot;
for (slot = 0; slot < 3; slot++, bitPos += 41)
{ {
UInt32 bytePos, bitRes; m++;
UInt64 instruction, instNorm; do
int j;
if (((mask >> slot) & 1) == 0)
continue;
bytePos = (bitPos >> 3);
bitRes = bitPos & 0x7;
instruction = 0;
for (j = 0; j < 6; j++)
instruction += (UInt64)data[i + j + bytePos] << (8 * j);
instNorm = instruction >> bitRes;
if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
{ {
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF); Byte *p = data + (i + (size_t)m * 5 - 8);
UInt32 dest; if (((p[3] >> m) & 15) == 5
src |= ((UInt32)(instNorm >> 36) & 1) << 20; && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
{
unsigned raw = GetUi32(p);
unsigned v = raw >> m;
v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
src <<= 4; v <<= 4;
if (encoding)
v += ip + (UInt32)i;
else
v -= ip + (UInt32)i;
v >>= 4;
if (encoding) v &= 0x1FFFFF;
dest = ip + (UInt32)i + src; v += 0x700000;
else v &= 0x8FFFFF;
dest = src - (ip + (UInt32)i); raw &= ~((UInt32)0x8FFFFF << m);
raw |= (v << m);
dest >>= 4; SetUi32(p, raw);
}
instNorm &= ~((UInt64)(0x8FFFFF) << 13);
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
instruction &= (1 << bitRes) - 1;
instruction |= (instNorm << bitRes);
for (j = 0; j < 6; j++)
data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
} }
while (++m <= 4);
} }
i += 16;
} }
while (i <= size);
return i; return i;
} }

View File

@@ -1,5 +1,5 @@
/* BwtSort.c -- BWT block sorting /* BwtSort.c -- BWT block sorting
2013-11-12 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -314,7 +314,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
#ifndef BLOCK_SORT_EXTERNAL_FLAGS #ifndef BLOCK_SORT_EXTERNAL_FLAGS
UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax); UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
if ((ind2[j] & 0x40000000) != 0) if ((ind2[j] & 0x40000000) != 0)
subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits); subGroupSize += ((ind2[(size_t)j + 1] >> kNumBitsMax) << kNumExtra0Bits);
subGroupSize++; subGroupSize++;
for (;;) for (;;)
{ {
@@ -362,7 +362,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
for (i = 0; i < kNumHashValues; i++) for (i = 0; i < kNumHashValues; i++)
counters[i] = 0; counters[i] = 0;
for (i = 0; i < blockSize - 1; i++) for (i = 0; i < blockSize - 1; i++)
counters[((UInt32)data[i] << 8) | data[i + 1]]++; counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++;
counters[((UInt32)data[i] << 8) | data[0]]++; counters[((UInt32)data[i] << 8) | data[0]]++;
Groups = counters + BS_TEMP_SIZE; Groups = counters + BS_TEMP_SIZE;
@@ -392,11 +392,11 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
} }
for (i = 0; i < blockSize - 1; i++) for (i = 0; i < blockSize - 1; i++)
Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]]; Groups[i] = counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]];
Groups[i] = counters[((UInt32)data[i] << 8) | data[0]]; Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
for (i = 0; i < blockSize - 1; i++) for (i = 0; i < blockSize - 1; i++)
Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i; Indices[counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++] = i;
Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i; Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
#ifndef BLOCK_SORT_EXTERNAL_FLAGS #ifndef BLOCK_SORT_EXTERNAL_FLAGS
@@ -448,11 +448,11 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
{ {
Bool finishedGroup = ((Indices[i] & 0x80000000) == 0); BoolInt finishedGroup = ((Indices[i] & 0x80000000) == 0);
if ((Indices[i] & 0x40000000) != 0) if ((Indices[i] & 0x40000000) != 0)
{ {
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits);
Indices[i + 1] &= kIndexMask; Indices[(size_t)i + 1] &= kIndexMask;
} }
Indices[i] &= kIndexMask; Indices[i] &= kIndexMask;
groupSize++; groupSize++;
@@ -460,7 +460,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
{ {
Indices[i - finishedGroupSize] &= kIndexMask; Indices[i - finishedGroupSize] &= kIndexMask;
if (finishedGroupSize > 1) if (finishedGroupSize > 1)
Indices[i - finishedGroupSize + 1] &= kIndexMask; Indices[(size_t)(i - finishedGroupSize) + 1] &= kIndexMask;
{ {
UInt32 newGroupSize = groupSize + finishedGroupSize; UInt32 newGroupSize = groupSize + finishedGroupSize;
SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize); SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
@@ -503,8 +503,8 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax); UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
if ((Indices[i] & 0x40000000) != 0) if ((Indices[i] & 0x40000000) != 0)
{ {
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits); groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits);
Indices[i + 1] &= kIndexMask; Indices[(size_t)i + 1] &= kIndexMask;
} }
Indices[i] &= kIndexMask; Indices[i] &= kIndexMask;
groupSize++; groupSize++;
@@ -513,4 +513,3 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
#endif #endif
return Groups[0]; return Groups[0];
} }

View File

@@ -1,5 +1,5 @@
/* Compiler.h -- Compiler ypes /* Compiler.h
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H #ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H #define __7Z_COMPILER_H
@@ -18,11 +18,16 @@
#else #else
#pragma warning(disable : 4511) // copy constructor could not be generated #pragma warning(disable : 4511) // copy constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated #pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined #pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif #endif
#endif #endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif #endif

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2012-05-29: Igor Pavlov : Public domain */ 2018-02-18: Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t": "andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag)); "=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif #endif
return flag; return flag;
} }
@@ -54,7 +55,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
@@ -79,7 +80,13 @@ 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__) #if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;" "mov %%ebx, %%edi;"
"cpuid;" "cpuid;"
"xchgl %%ebx, %%edi;" "xchgl %%ebx, %%edi;"
@@ -108,7 +115,7 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#endif #endif
} }
Bool x86cpuid_CheckAndRead(Cx86cpuid *p) BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
{ {
CHECK_CPUID_IS_SUPPORTED CHECK_CPUID_IS_SUPPORTED
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
@@ -116,7 +123,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},
@@ -137,25 +144,28 @@ int x86cpuid_GetFirm(const Cx86cpuid *p)
return -1; return -1;
} }
Bool CPU_Is_InOrder() BoolInt CPU_Is_InOrder()
{ {
Cx86cpuid p; Cx86cpuid p;
int firm; int firm;
UInt32 family, model; UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p)) if (!x86cpuid_CheckAndRead(&p))
return True; return True;
family = x86cpuid_GetFamily(&p);
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 && ( case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* Atom CPU */ /* In-Order Atom CPU */
model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x2006 /* 45 nm, Z6xx */ || model == 0x26 /* 45 nm, Z6xx */
|| model == 0x2007 /* 32 nm, Z2460 */ || model == 0x27 /* 32 nm, Z2460 */
|| model == 0x3005 /* 32 nm, Z2760 */ || model == 0x35 /* 32 nm, Z2760 */
|| model == 0x3006 /* 32 nm, N2xxx, D2xxx */ || model == 0x36 /* 32 nm, N2xxx, D2xxx */
))); )));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
@@ -165,7 +175,7 @@ Bool CPU_Is_InOrder()
#if !defined(MY_CPU_AMD64) && defined(_WIN32) #if !defined(MY_CPU_AMD64) && defined(_WIN32)
#include <windows.h> #include <windows.h>
static Bool CPU_Sys_Is_SSE_Supported() static BoolInt CPU_Sys_Is_SSE_Supported()
{ {
OSVERSIONINFO vi; OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi); vi.dwOSVersionInfoSize = sizeof(vi);
@@ -178,7 +188,7 @@ static Bool CPU_Sys_Is_SSE_Supported()
#define CHECK_SYS_SSE_SUPPORT #define CHECK_SYS_SSE_SUPPORT
#endif #endif
Bool CPU_Is_Aes_Supported() BoolInt CPU_Is_Aes_Supported()
{ {
Cx86cpuid p; Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT CHECK_SYS_SSE_SUPPORT
@@ -187,4 +197,22 @@ Bool CPU_Is_Aes_Supported()
return (p.c >> 25) & 1; return (p.c >> 25) & 1;
} }
BoolInt CPU_IsSupported_PageGB()
{
Cx86cpuid cpuid;
if (!x86cpuid_CheckAndRead(&cpuid))
return False;
{
UInt32 d[4] = { 0 };
MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
if (d[0] < 0x80000001)
return False;
}
{
UInt32 d[4] = { 0 };
MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
return (d[3] >> 26) & 1;
}
}
#endif #endif

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2013-11-12: Igor Pavlov : Public domain */ 2018-02-18 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@@ -10,68 +10,207 @@ 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
#ifdef __ILP32__
#define MY_CPU_NAME "x32"
#else
#define MY_CPU_NAME "x64"
#endif
#define MY_CPU_64BIT
#endif #endif
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT #if defined(_M_IX86) \
|| defined(__i386__)
#define MY_CPU_X86
#define MY_CPU_NAME "x86"
#define MY_CPU_32BIT
#endif #endif
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86 #if defined(_M_ARM64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
#define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT
#endif #endif
#if defined(_M_ARM) \
|| defined(_M_ARM_NT) \
|| defined(_M_ARMT) \
|| defined(__arm__) \
|| defined(__thumb__) \
|| defined(__ARMEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEL__) \
|| defined(__THUMBEB__)
#define MY_CPU_ARM
#define MY_CPU_NAME "arm"
#define MY_CPU_32BIT
#endif
#if defined(_M_IA64) \
|| defined(__ia64__)
#define MY_CPU_IA64
#define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT
#endif
#if defined(__mips64) \
|| defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT
#elif defined(__mips__)
#define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */
#endif
#if defined(__ppc64__) \
|| defined(__powerpc64__)
#ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32"
#else
#define MY_CPU_NAME "ppc64"
#endif
#define MY_CPU_64BIT
#elif defined(__ppc__) \
|| defined(__powerpc__)
#define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT
#endif
#if defined(__sparc64__)
#define MY_CPU_NAME "sparc64"
#define MY_CPU_64BIT
#elif defined(__sparc__)
#define MY_CPU_NAME "sparc"
/* #define MY_CPU_32BIT */
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64 #define MY_CPU_X86_OR_AMD64
#endif #endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#define MY_CPU_32BIT #ifdef _WIN32
#ifdef MY_CPU_ARM
#define MY_CPU_ARM_LE
#endif
#ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE
#endif
#ifdef _M_IA64
#define MY_CPU_IA64_LE
#endif
#endif #endif
#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE #if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL) \
|| defined(__BFIN__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE
#endif #endif
#if defined(_WIN32) && defined(_M_IA64) #if defined(__BIG_ENDIAN__) \
#define MY_CPU_IA64_LE || defined(__ARMEB__) \
|| defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif #endif
#if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN
#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__)
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE) #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian #error Stop_Compiling_Bad_Endian
#endif #endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT
#endif
#ifndef MY_CPU_NAME
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE"
#else
/*
#define MY_CPU_NAME ""
*/
#endif
#endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED)
#define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p)) #define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p)) #define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(const void *)(p)) #define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, 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,31 +220,54 @@ 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) #ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x)
#else
#define MY__has_builtin(x) 0
#endif
#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> #include <stdlib.h>
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64) #pragma intrinsic(_byteswap_uint64)
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
#define 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))) \
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
#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) ( \
@@ -116,9 +278,23 @@ 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
#ifndef GetBe16
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#endif #endif
#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
@@ -140,15 +316,18 @@ enum
CPU_FIRM_VIA CPU_FIRM_VIA
}; };
Bool x86cpuid_CheckAndRead(Cx86cpuid *p); void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
BoolInt 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(); BoolInt CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported(); BoolInt CPU_Is_Aes_Supported();
BoolInt CPU_IsSupported_PageGB();
#endif #endif

108
C/DllSecur.c Normal file
View File

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

20
C/DllSecur.h Normal file
View File

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

View File

@@ -1,5 +1,5 @@
/* HuffEnc.c -- functions for Huffman encoding /* HuffEnc.c -- functions for Huffman encoding
2009-09-02 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -113,7 +113,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
if (len >= maxLen) if (len >= maxLen)
for (len = maxLen - 1; lenCounters[len] == 0; len--); for (len = maxLen - 1; lenCounters[len] == 0; len--);
lenCounters[len]--; lenCounters[len]--;
lenCounters[len + 1] += 2; lenCounters[(size_t)len + 1] += 2;
} }
{ {
@@ -121,8 +121,8 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
i = 0; i = 0;
for (len = maxLen; len != 0; len--) for (len = maxLen; len != 0; len--)
{ {
UInt32 num; UInt32 k;
for (num = lenCounters[len]; num != 0; num--) for (k = lenCounters[len]; k != 0; k--)
lens[p[i++] & MASK] = (Byte)len; lens[p[i++] & MASK] = (Byte)len;
} }
} }
@@ -133,14 +133,14 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
UInt32 code = 0; UInt32 code = 0;
UInt32 len; UInt32 len;
for (len = 1; len <= kMaxLen; len++) for (len = 1; len <= kMaxLen; len++)
nextCodes[len] = code = (code + lenCounters[len - 1]) << 1; nextCodes[len] = code = (code + lenCounters[(size_t)len - 1]) << 1;
} }
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */ /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
{ {
UInt32 i; UInt32 k;
for (i = 0; i < numSymbols; i++) for (k = 0; k < numSymbols; k++)
p[i] = nextCodes[lens[i]]++; p[k] = nextCodes[lens[k]]++;
} }
} }
} }

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2013-01-18 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
@@ -21,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;
@@ -29,30 +34,32 @@ 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;
UInt64 expectedDataSize;
} 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);
@@ -66,9 +73,9 @@ void MatchFinder_Construct(CMatchFinder *p);
*/ */
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc); ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr 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,
@@ -82,7 +89,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);
@@ -91,7 +97,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;
@@ -100,9 +105,14 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_3(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p); void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);

View File

@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2014-12-29 : Igor Pavlov : Public domain */ 2018-12-29 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -7,7 +7,7 @@
#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;
@@ -20,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)
{ {
@@ -33,6 +33,8 @@ void MtSync_GetNextBlock(CMtSync *p)
Event_Set(&p->canStart); Event_Set(&p->canStart);
Event_Wait(&p->wasStarted); Event_Wait(&p->wasStarted);
// if (mt) MatchFinder_Init_LowHash(mt->MatchFinder);
} }
else else
{ {
@@ -48,7 +50,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)
@@ -71,7 +73,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))
{ {
@@ -134,20 +136,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 (;;)
@@ -155,6 +157,9 @@ void HashThreadFunc(CMatchFinderMt *mt)
UInt32 numProcessedBlocks = 0; UInt32 numProcessedBlocks = 0;
Event_Wait(&p->canStart); Event_Wait(&p->canStart);
Event_Set(&p->wasStarted); Event_Set(&p->wasStarted);
MatchFinder_Init_HighHash(mt->MatchFinder);
for (;;) for (;;)
{ {
if (p->exit) if (p->exit)
@@ -173,12 +178,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);
@@ -192,7 +197,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;
@@ -205,7 +210,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
if (num > kMtHashBlockSize - 2) if (num > kMtHashBlockSize - 2)
num = kMtHashBlockSize - 2; num = kMtHashBlockSize - 2;
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc); mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
heads[0] += num; heads[0] = 2 + num;
} }
mf->pos += num; mf->pos += num;
mf->buffer += num; mf->buffer += num;
@@ -217,7 +222,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;
@@ -227,38 +232,57 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
#define kEmptyHashValue 0 #define kEmptyHashValue 0
/* #define MFMT_GM_INLINE */ #define MFMT_GM_INLINE
#ifdef MFMT_GM_INLINE #ifdef MFMT_GM_INLINE
#define NO_INLINE MY_FAST_CALL /*
we use size_t for _cyclicBufferPos instead of UInt32
to eliminate "movsx" BUG in old MSVC x64 compiler.
*/
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, MY_NO_INLINE
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, static UInt32 *GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes) size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 _maxLen, const UInt32 *hash, const UInt32 *limit, UInt32 size, UInt32 *posRes)
{ {
do do
{ {
UInt32 *distances = _distances + 1; UInt32 *_distances = ++distances;
UInt32 curMatch = pos - *hash++; UInt32 delta = *hash++;
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; CLzRef *ptr0 = son + ((size_t)_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1); CLzRef *ptr1 = son + ((size_t)_cyclicBufferPos << 1);
UInt32 len0 = 0, len1 = 0; unsigned len0 = 0, len1 = 0;
UInt32 cutValue = _cutValue; UInt32 cutValue = _cutValue;
UInt32 maxLen = _maxLen; unsigned maxLen = (unsigned)_maxLen;
for (;;)
/*
if (size > 1)
{ {
UInt32 delta = pos - curMatch; UInt32 delta = *hash;
if (cutValue-- == 0 || delta >= _cyclicBufferSize) if (delta < _cyclicBufferSize)
{ {
*ptr0 = *ptr1 = kEmptyHashValue; UInt32 cyc1 = _cyclicBufferPos + 1;
break; CLzRef *pair = son + ((size_t)(cyc1 - delta + ((delta > cyc1) ? _cyclicBufferSize : 0)) << 1);
Byte b = *(cur + 1 - delta);
_distances[0] = pair[0];
_distances[1] = b;
} }
}
*/
if (cutValue == 0 || delta >= _cyclicBufferSize)
{
*ptr0 = *ptr1 = kEmptyHashValue;
}
else
for(;;)
{
{ {
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); CLzRef *pair = son + ((size_t)(_cyclicBufferPos - delta + ((_cyclicBufferPos < delta) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta; const Byte *pb = cur - delta;
UInt32 len = (len0 < len1 ? len0 : len1); unsigned len = (len0 < len1 ? len0 : len1);
UInt32 pair0 = *pair;
if (pb[len] == cur[len]) if (pb[len] == cur[len])
{ {
if (++len != lenLimit && pb[len] == cur[len]) if (++len != lenLimit && pb[len] == cur[len])
@@ -267,55 +291,69 @@ Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CL
break; break;
if (maxLen < len) if (maxLen < len)
{ {
*distances++ = maxLen = len; maxLen = len;
*distances++ = (UInt32)len;
*distances++ = delta - 1; *distances++ = delta - 1;
if (len == lenLimit) if (len == lenLimit)
{ {
*ptr1 = pair[0]; UInt32 pair1 = pair[1];
*ptr0 = pair[1]; *ptr1 = pair0;
*ptr0 = pair1;
break; break;
} }
} }
} }
if (pb[len] < cur[len])
{ {
*ptr1 = curMatch; UInt32 curMatch = pos - delta;
ptr1 = pair + 1; // delta = pos - *pair;
curMatch = *ptr1; // delta = pos - pair[((UInt32)pb[len] - (UInt32)cur[len]) >> 31];
len1 = len; if (pb[len] < cur[len])
} {
else delta = pos - pair[1];
{ *ptr1 = curMatch;
*ptr0 = curMatch; ptr1 = pair + 1;
ptr0 = pair; len1 = len;
curMatch = *ptr0; }
len0 = len; else
{
delta = pos - *pair;
*ptr0 = curMatch;
ptr0 = pair;
len0 = len;
}
} }
} }
if (--cutValue == 0 || delta >= _cyclicBufferSize)
{
*ptr0 = *ptr1 = kEmptyHashValue;
break;
}
} }
pos++; pos++;
_cyclicBufferPos++; _cyclicBufferPos++;
cur++; cur++;
{ {
UInt32 num = (UInt32)(distances - _distances); UInt32 num = (UInt32)(distances - _distances);
*_distances = num - 1; _distances[-1] = num;
_distances += num;
limit -= num;
} }
} }
while (limit > 0 && --size != 0); while (distances < limit && --size != 0);
*posRes = pos; *posRes = pos;
return limit; return distances;
} }
#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); // * 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)
@@ -324,9 +362,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;
@@ -343,13 +383,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++;
@@ -359,8 +400,10 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
#else #else
{ {
UInt32 posRes; UInt32 posRes;
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, curPos = (UInt32)(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,
distances + limit,
size, &posRes) - distances);
p->hashBufPos += posRes - pos; p->hashBufPos += posRes - pos;
cyclicBufferPos += posRes - pos; cyclicBufferPos += posRes - pos;
p->buffer += posRes - pos; p->buffer += posRes - pos;
@@ -376,10 +419,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)
@@ -393,7 +437,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;
} }
@@ -432,18 +476,18 @@ 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, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->hashBuf); ISzAlloc_Free(alloc, p->hashBuf);
p->hashBuf = 0; p->hashBuf = NULL;
} }
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
{ {
MtSync_Destruct(&p->hashSync); MtSync_Destruct(&p->hashSync);
MtSync_Destruct(&p->btSync); MtSync_Destruct(&p->btSync);
@@ -457,23 +501,25 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { Has
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
{ {
Byte allocaDummy[0x180]; Byte allocaDummy[0x180];
allocaDummy[0] = 0; unsigned i = 0;
allocaDummy[1] = allocaDummy[0]; for (i = 0; i < 16; i++)
BtThreadFunc((CMatchFinderMt *)p); allocaDummy[i] = (Byte)0;
if (allocaDummy[0] == 0)
BtThreadFunc((CMatchFinderMt *)p);
return 0; return 0;
} }
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc) UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
{ {
CMatchFinder *mf = p->MatchFinder; CMatchFinder *mf = p->MatchFinder;
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 *)ISzAlloc_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;
} }
@@ -488,13 +534,20 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
} }
/* Call it after ReleaseStream / SetStream */ /* Call it after ReleaseStream / SetStream */
void MatchFinderMt_Init(CMatchFinderMt *p) static void MatchFinderMt_Init(CMatchFinderMt *p)
{ {
CMatchFinder *mf = p->MatchFinder; CMatchFinder *mf = p->MatchFinder;
p->btBufPos = p->btBufPosLimit = 0;
p->hashBufPos = p->hashBufPosLimit = 0; p->btBufPos =
MatchFinder_Init(mf); p->btBufPosLimit = 0;
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf); p->hashBufPos =
p->hashBufPosLimit = 0;
/* Init without data reading. We don't want to read data in this thread */
MatchFinder_Init_3(mf, False);
MatchFinder_Init_LowHash(mf);
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
p->btNumAvailBytes = 0; p->btNumAvailBytes = 0;
p->lzPos = p->historySize + 1; p->lzPos = p->historySize + 1;
@@ -519,13 +572,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);
@@ -537,34 +590,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])
@@ -572,23 +620,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])
{ {
@@ -601,43 +649,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;
@@ -659,13 +709,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++;
@@ -675,15 +726,19 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
UInt32 i; UInt32 i;
for (i = 0; i < len; i += 2) for (i = 0; i < len; i += 2)
{ {
*distances++ = *btBuf++; UInt32 v0 = btBuf[0];
*distances++ = *btBuf++; UInt32 v1 = btBuf[1];
btBuf += 2;
distances[0] = v0;
distances[1] = v1;
distances += 2;
} }
} }
INCREASE_LZ_POS INCREASE_LZ_POS
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++;
@@ -691,6 +746,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));
} }
@@ -702,11 +758,15 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances); distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
do do
{ {
*distances2++ = *btBuf++; UInt32 v0 = btBuf[0];
*distances2++ = *btBuf++; UInt32 v1 = btBuf[1];
btBuf += 2;
distances2[0] = v0;
distances2[1] = v1;
distances2 += 2;
} }
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;
@@ -716,41 +776,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
} }
@@ -759,15 +819,15 @@ 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;
p->MixMatchesFunc = (Mf_Mix_Matches)0; p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip; vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches; vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
break; break;
@@ -779,7 +839,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;

View File

@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2013-01-18 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H #ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H #define __LZ_FIND_MT_H
@@ -19,10 +19,10 @@ EXTERN_C_BEGIN
typedef struct _CMtSync typedef struct _CMtSync
{ {
Bool wasCreated; BoolInt wasCreated;
Bool needStart; BoolInt needStart;
Bool exit; BoolInt exit;
Bool stopWriting; BoolInt stopWriting;
CThread thread; CThread thread;
CAutoResetEvent canStart; CAutoResetEvent canStart;
@@ -30,8 +30,8 @@ typedef struct _CMtSync
CAutoResetEvent wasStopped; CAutoResetEvent wasStopped;
CSemaphore freeSemaphore; CSemaphore freeSemaphore;
CSemaphore filledSemaphore; CSemaphore filledSemaphore;
Bool csWasInitialized; BoolInt csWasInitialized;
Bool csWasEntered; BoolInt csWasEntered;
CCriticalSection cs; CCriticalSection cs;
UInt32 numProcessedBlocks; UInt32 numProcessedBlocks;
} CMtSync; } CMtSync;
@@ -75,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;
@@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt
} CMatchFinderMt; } CMatchFinderMt;
void MatchFinderMt_Construct(CMatchFinderMt *p); void MatchFinderMt_Construct(CMatchFinderMt *p);
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc); void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc); UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);

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

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2010-12-15 : Igor Pavlov : Public domain */ 2019-02-02 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@@ -14,28 +14,22 @@
#include "Lzma2Dec.h" #include "Lzma2Dec.h"
/* /*
00000000 - EOS 00000000 - End of data
00000001 U U - Uncompressed Reset Dic 00000001 U U - Uncompressed, reset dic, need reset state and set new prop
00000010 U U - Uncompressed No Reset 00000010 U U - Uncompressed, no reset
100uuuuu U U P P - LZMA no reset 100uuuuu U U P P - LZMA, no reset
101uuuuu U U P P - LZMA reset state 101uuuuu U U P P - LZMA, reset state
110uuuuu U U P P S - LZMA reset state + new prop 110uuuuu U U P P S - LZMA, reset state + set new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic 111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
u, U - Unpack Size u, U - Unpack Size
P - Pack Size P - Pack Size
S - Props S - Props
*/ */
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1 #define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4 #define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
@@ -74,14 +68,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
return SZ_OK; return SZ_OK;
} }
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
@@ -91,30 +85,39 @@ SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
void Lzma2Dec_Init(CLzma2Dec *p) void Lzma2Dec_Init(CLzma2Dec *p)
{ {
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
p->needInitDic = True; p->needInitLevel = 0xE0;
p->needInitState = True; p->isExtraMode = False;
p->needInitProp = True; p->unpackSize = 0;
// p->decoder.dicPos = 0; // we can use it instead of full init
LzmaDec_Init(&p->decoder); LzmaDec_Init(&p->decoder);
} }
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{ {
switch(p->state) switch (p->state)
{ {
case LZMA2_STATE_CONTROL: case LZMA2_STATE_CONTROL:
p->isExtraMode = False;
p->control = b; p->control = b;
PRF(printf("\n %4X ", p->decoder.dicPos)); PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", b)); PRF(printf(" %02X", (unsigned)b));
if (p->control == 0) if (b == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if ((p->control & 0x7F) > 2) if (b == LZMA2_CONTROL_COPY_RESET_DIC)
p->needInitLevel = 0xC0;
else if (b > 2 || p->needInitLevel == 0xE0)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
p->unpackSize = 0;
} }
else else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16; {
if (b < p->needInitLevel)
return LZMA2_STATE_ERROR;
p->needInitLevel = 0;
p->unpackSize = (UInt32)(b & 0x1F) << 16;
}
return LZMA2_STATE_UNPACK0; return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0: case LZMA2_STATE_UNPACK0:
@@ -124,8 +127,8 @@ 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(" %7u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8; p->packSize = (UInt32)b << 8;
@@ -134,24 +137,23 @@ 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)); // if (p->packSize < 5) return LZMA2_STATE_ERROR;
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: PRF(printf(" %5u", (unsigned)p->packSize));
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); return (p->control & 0x40) ? LZMA2_STATE_PROP : 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;
b /= 9; b /= 9;
p->decoder.prop.pb = b / 5; p->decoder.prop.pb = (Byte)(b / 5);
lp = b % 5; lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX) if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc; p->decoder.prop.lc = (Byte)lc;
p->decoder.prop.lp = lp; p->decoder.prop.lp = (Byte)lp;
p->needInitProp = False;
return LZMA2_STATE_DATA; return LZMA2_STATE_DATA;
} }
} }
@@ -167,7 +169,8 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
p->processedPos += (UInt32)size; p->processedPos += (UInt32)size;
} }
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
@@ -176,16 +179,24 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
*srcLen = 0; *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED) while (p->state != LZMA2_STATE_ERROR)
{ {
SizeT dicPos = p->decoder.dicPos; SizeT dicPos;
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA; if (p->state == LZMA2_STATE_FINISHED)
{
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
dicPos = p->decoder.dicPos;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK; return SZ_OK;
} }
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{ {
if (*srcLen == inSize) if (*srcLen == inSize)
@@ -195,22 +206,25 @@ 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)
break;
continue; continue;
} }
{ {
SizeT destSizeCur = dicLimit - dicPos; SizeT inCur = inSize - *srcLen;
SizeT srcSizeCur = inSize - *srcLen; SizeT outCur = dicLimit - dicPos;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur) if (outCur >= p->unpackSize)
{ {
destSizeCur = (SizeT)p->unpackSize; outCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END; curFinishMode = LZMA_FINISH_END;
} }
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{ {
if (*srcLen == inSize) if (inCur == 0)
{ {
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
@@ -218,119 +232,241 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
return SZ_ERROR_DATA;
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False); LzmaDec_InitDicAndState(&p->decoder, initDic, False);
} }
if (srcSizeCur > destSizeCur) if (inCur > outCur)
srcSizeCur = destSizeCur; inCur = outCur;
if (inCur == 0)
break;
if (srcSizeCur == 0) LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
return SZ_ERROR_DATA;
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); src += inCur;
*srcLen += inCur;
src += srcSizeCur; p->unpackSize -= (UInt32)inCur;
*srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
} }
else else
{ {
SizeT outSizeProcessed;
SRes res; SRes res;
if (p->state == LZMA2_STATE_DATA) if (p->state == LZMA2_STATE_DATA)
{ {
int mode = LZMA2_GET_LZMA_MODE(p); BoolInt initDic = (p->control >= 0xE0);
Bool initDic = (mode == 3); BoolInt initState = (p->control >= 0xA0);
Bool initState = (mode > 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
return SZ_ERROR_DATA;
LzmaDec_InitDicAndState(&p->decoder, initDic, initState); LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT; p->state = LZMA2_STATE_DATA_CONT;
} }
if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); if (inCur > p->packSize)
inCur = (SizeT)p->packSize;
src += srcSizeCur; res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
*srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur;
outSizeProcessed = p->decoder.dicPos - dicPos; src += inCur;
p->unpackSize -= (UInt32)outSizeProcessed; *srcLen += inCur;
p->packSize -= (UInt32)inCur;
outCur = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outCur;
if (res != 0)
break;
RINOK(res);
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res;
if (srcSizeCur == 0 && outSizeProcessed == 0)
{ {
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || if (p->packSize == 0)
p->unpackSize != 0 || p->packSize != 0) break;
return SZ_ERROR_DATA; return SZ_OK;
}
if (inCur == 0 && outCur == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0
|| p->packSize != 0)
break;
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
} }
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_SPECIFIED;
} }
} }
} }
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK; *status = LZMA_STATUS_NOT_SPECIFIED;
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
} }
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize,
const Byte *src, SizeT *srcLen,
int checkFinishBlock)
{
SizeT inSize = *srcLen;
*srcLen = 0;
while (p->state != LZMA2_STATE_ERROR)
{
if (p->state == LZMA2_STATE_FINISHED)
return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
if (outSize == 0 && !checkFinishBlock)
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
if (p->state == LZMA2_STATE_UNPACK0)
{
// if (p->decoder.dicPos != 0)
if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
return LZMA2_PARSE_STATUS_NEW_BLOCK;
// if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
}
// The following code can be commented.
// It's not big problem, if we read additional input bytes.
// It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
{
// checkFinishBlock is true. So we expect that block must be finished,
// We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
// break;
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
}
if (p->state == LZMA2_STATE_DATA)
return LZMA2_PARSE_STATUS_NEW_CHUNK;
continue;
}
if (outSize == 0)
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
{
SizeT inCur = inSize - *srcLen;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (inCur == 0)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
if (inCur > p->unpackSize)
inCur = p->unpackSize;
if (inCur > outSize)
inCur = outSize;
p->decoder.dicPos += inCur;
src += inCur;
*srcLen += inCur;
outSize -= inCur;
p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
p->isExtraMode = True;
if (inCur == 0)
{
if (p->packSize != 0)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
}
else if (p->state == LZMA2_STATE_DATA)
{
p->state = LZMA2_STATE_DATA_CONT;
if (*src != 0)
{
// first byte of lzma chunk must be Zero
*srcLen += 1;
p->packSize--;
break;
}
}
if (inCur > p->packSize)
inCur = (SizeT)p->packSize;
src += inCur;
*srcLen += inCur;
p->packSize -= (UInt32)inCur;
if (p->packSize == 0)
{
SizeT rem = outSize;
if (rem > p->unpackSize)
rem = p->unpackSize;
p->decoder.dicPos += rem;
p->unpackSize -= (UInt32)rem;
outSize -= rem;
if (p->unpackSize == 0)
p->state = LZMA2_STATE_CONTROL;
}
}
}
}
p->state = LZMA2_STATE_ERROR;
return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) for (;;)
{ {
SizeT srcSizeCur = inSize, outSizeCur, dicPos; SizeT inCur = inSize, outCur, dicPos;
ELzmaFinishMode curFinishMode; ELzmaFinishMode curFinishMode;
SRes res; SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize) if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0; p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos; dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos) curFinishMode = LZMA_FINISH_ANY;
outCur = p->decoder.dicBufSize - dicPos;
if (outCur >= outSize)
{ {
outSizeCur = p->decoder.dicBufSize; outCur = outSize;
curFinishMode = LZMA_FINISH_ANY;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode; curFinishMode = finishMode;
} }
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur; src += inCur;
*srcLen += srcSizeCur; inSize -= inCur;
outSizeCur = p->decoder.dicPos - dicPos; *srcLen += inCur;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur); outCur = p->decoder.dicPos - dicPos;
dest += outSizeCur; memcpy(dest, p->decoder.dic + dicPos, outCur);
outSize -= outSizeCur; dest += outCur;
*destLen += outSizeCur; outSize -= outCur;
*destLen += outCur;
if (res != 0) if (res != 0)
return res; return res;
if (outSizeCur == 0 || outSize == 0) if (outCur == 0 || outSize == 0)
return SZ_OK; return SZ_OK;
} }
} }
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
{ {
CLzma2Dec p; CLzma2Dec p;
SRes res; SRes res;

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder /* Lzma2Dec.h -- LZMA2 Decoder
2013-01-18 : Igor Pavlov : Public domain */ 2018-02-19 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H #ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H #define __LZMA2_DEC_H
@@ -12,25 +12,24 @@ EXTERN_C_BEGIN
typedef struct typedef struct
{ {
CLzmaDec decoder; unsigned state;
Byte control;
Byte needInitLevel;
Byte isExtraMode;
Byte _pad_;
UInt32 packSize; UInt32 packSize;
UInt32 unpackSize; UInt32 unpackSize;
int state; CLzmaDec decoder;
Byte control;
Bool needInitDic;
Bool needInitState;
Bool needInitProp;
} CLzma2Dec; } CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) #define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p); void Lzma2Dec_Init(CLzma2Dec *p);
/* /*
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit). It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
@@ -53,6 +52,47 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- LZMA2 block and chunk parsing ---------- */
/*
Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
- LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
- LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
CLzma2Dec::unpackSize contains unpack size of that chunk
*/
typedef enum
{
/*
LZMA_STATUS_NOT_SPECIFIED // data error
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED //
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
*/
LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
LZMA2_PARSE_STATUS_NEW_CHUNK
} ELzma2ParseStatus;
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize, // output size
const Byte *src, SizeT *srcLen,
int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position.
);
/*
LZMA2 parser doesn't decode LZMA chunks, so we must read
full input LZMA chunk to decode some part of LZMA chunk.
Lzma2Dec_GetUnpackExtra() returns the value that shows
max possible number of output bytes that can be output by decoder
at current input positon.
*/
#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
/* /*
@@ -73,7 +113,7 @@ 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, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

1082
C/Lzma2DecMt.c Normal file
View File

File diff suppressed because it is too large Load Diff

79
C/Lzma2DecMt.h Normal file
View File

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

View File

@@ -1,9 +1,8 @@
/* Lzma2Enc.c -- LZMA2 Encoder /* Lzma2Enc.c -- LZMA2 Encoder
2012-06-19 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
/* #include <stdio.h> */
#include <string.h> #include <string.h>
/* #define _7ZIP_ST */ /* #define _7ZIP_ST */
@@ -13,7 +12,7 @@
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
#include "MtCoder.h" #include "MtCoder.h"
#else #else
#define NUM_MT_CODER_THREADS_MAX 1 #define MTCODER__THREADS_MAX 1
#endif #endif
#define LZMA2_CONTROL_LZMA (1 << 7) #define LZMA2_CONTROL_LZMA (1 << 7)
@@ -35,41 +34,97 @@
#define PRF(x) /* x */ #define PRF(x) /* x */
/* ---------- CLimitedSeqInStream ---------- */
typedef struct
{
ISeqInStream vt;
ISeqInStream *realStream;
UInt64 limit;
UInt64 processed;
int finished;
} CLimitedSeqInStream;
static void LimitedSeqInStream_Init(CLimitedSeqInStream *p)
{
p->limit = (UInt64)(Int64)-1;
p->processed = 0;
p->finished = 0;
}
static SRes LimitedSeqInStream_Read(const ISeqInStream *pp, void *data, size_t *size)
{
CLimitedSeqInStream *p = CONTAINER_FROM_VTBL(pp, CLimitedSeqInStream, vt);
size_t size2 = *size;
SRes res = SZ_OK;
if (p->limit != (UInt64)(Int64)-1)
{
UInt64 rem = p->limit - p->processed;
if (size2 > rem)
size2 = (size_t)rem;
}
if (size2 != 0)
{
res = ISeqInStream_Read(p->realStream, data, &size2);
p->finished = (size2 == 0 ? 1 : 0);
p->processed += size2;
}
*size = size2;
return res;
}
/* ---------- CLzma2EncInt ---------- */ /* ---------- CLzma2EncInt ---------- */
typedef struct typedef struct
{ {
CLzmaEncHandle enc; CLzmaEncHandle enc;
Byte propsAreSet;
Byte propsByte;
Byte needInitState;
Byte needInitProp;
UInt64 srcPos; UInt64 srcPos;
Byte props;
Bool needInitState;
Bool needInitProp;
} CLzma2EncInt; } CLzma2EncInt;
static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props)
static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props)
{ {
Byte propsEncoded[LZMA_PROPS_SIZE]; if (!p->propsAreSet)
SizeT propsSize = LZMA_PROPS_SIZE; {
RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)); SizeT propsSize = LZMA_PROPS_SIZE;
RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)); Byte propsEncoded[LZMA_PROPS_SIZE];
p->srcPos = 0; RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
p->props = propsEncoded[0]; RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
p->needInitState = True; p->propsByte = propsEncoded[0];
p->needInitProp = True; p->propsAreSet = True;
}
return SZ_OK; return SZ_OK;
} }
static void Lzma2EncInt_InitBlock(CLzma2EncInt *p)
{
p->srcPos = 0;
p->needInitState = True;
p->needInitProp = True;
}
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
ISzAlloc *alloc, ISzAlloc *allocBig); ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig); UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
void LzmaEnc_Finish(CLzmaEncHandle pp); void LzmaEnc_Finish(CLzmaEncHandle pp);
void LzmaEnc_SaveState(CLzmaEncHandle pp); void LzmaEnc_SaveState(CLzmaEncHandle pp);
void LzmaEnc_RestoreState(CLzmaEncHandle pp); void LzmaEnc_RestoreState(CLzmaEncHandle pp);
/*
UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp);
*/
static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
size_t *packSizeRes, ISeqOutStream *outStream) size_t *packSizeRes, ISeqOutStream *outStream)
@@ -78,7 +133,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
size_t packSize = packSizeLimit; size_t packSize = packSizeLimit;
UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX; UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX;
unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0); unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0);
Bool useCopyBlock; BoolInt useCopyBlock;
SRes res; SRes res;
*packSizeRes = 0; *packSizeRes = 0;
@@ -109,6 +164,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;
@@ -121,10 +177,11 @@ 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;
if (outStream->Write(outStream, outBuf, destPos) != destPos) if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
return SZ_ERROR_WRITE; return SZ_ERROR_WRITE;
destPos = 0; destPos = 0;
} }
@@ -132,9 +189,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;
@@ -150,7 +209,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
outBuf[destPos++] = (Byte)pm; outBuf[destPos++] = (Byte)pm;
if (p->needInitProp) if (p->needInitProp)
outBuf[destPos++] = p->props; outBuf[destPos++] = p->propsByte;
p->needInitProp = False; p->needInitProp = False;
p->needInitState = False; p->needInitState = False;
@@ -158,26 +217,30 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
p->srcPos += unpackSize; p->srcPos += unpackSize;
if (outStream) if (outStream)
if (outStream->Write(outStream, outBuf, destPos) != destPos) if (ISeqOutStream_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)
{ {
LzmaEncProps_Init(&p->lzmaProps); LzmaEncProps_Init(&p->lzmaProps);
p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO;
p->numBlockThreads_Reduced = -1;
p->numBlockThreads_Max = -1;
p->numTotalThreads = -1; p->numTotalThreads = -1;
p->numBlockThreads = -1;
p->blockSize = 0;
} }
void Lzma2EncProps_Normalize(CLzma2EncProps *p) void Lzma2EncProps_Normalize(CLzma2EncProps *p)
{ {
int t1, t1n, t2, t3; UInt64 fileSize;
int t1, t1n, t2, t2r, t3;
{ {
CLzmaEncProps lzmaProps = p->lzmaProps; CLzmaEncProps lzmaProps = p->lzmaProps;
LzmaEncProps_Normalize(&lzmaProps); LzmaEncProps_Normalize(&lzmaProps);
@@ -185,11 +248,11 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
} }
t1 = p->lzmaProps.numThreads; t1 = p->lzmaProps.numThreads;
t2 = p->numBlockThreads; t2 = p->numBlockThreads_Max;
t3 = p->numTotalThreads; t3 = p->numTotalThreads;
if (t2 > NUM_MT_CODER_THREADS_MAX) if (t2 > MTCODER__THREADS_MAX)
t2 = NUM_MT_CODER_THREADS_MAX; t2 = MTCODER__THREADS_MAX;
if (t3 <= 0) if (t3 <= 0)
{ {
@@ -205,8 +268,8 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
t1 = 1; t1 = 1;
t2 = t3; t2 = t3;
} }
if (t2 > NUM_MT_CODER_THREADS_MAX) if (t2 > MTCODER__THREADS_MAX)
t2 = NUM_MT_CODER_THREADS_MAX; t2 = MTCODER__THREADS_MAX;
} }
else if (t1 <= 0) else if (t1 <= 0)
{ {
@@ -219,211 +282,186 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
p->lzmaProps.numThreads = t1; p->lzmaProps.numThreads = t1;
t2r = t2;
fileSize = p->lzmaProps.reduceSize;
if ( p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
&& p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO
&& (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1))
p->lzmaProps.reduceSize = p->blockSize;
LzmaEncProps_Normalize(&p->lzmaProps); LzmaEncProps_Normalize(&p->lzmaProps);
if (p->blockSize == 0) p->lzmaProps.reduceSize = fileSize;
t1 = p->lzmaProps.numThreads;
if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID)
{ {
UInt32 dictSize = p->lzmaProps.dictSize; t2r = t2 = 1;
UInt64 blockSize = (UInt64)dictSize << 2; t3 = t1;
const UInt32 kMinSize = (UInt32)1 << 20;
const UInt32 kMaxSize = (UInt32)1 << 28;
if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize;
if (blockSize < dictSize) blockSize = dictSize;
p->blockSize = (size_t)blockSize;
} }
if (t2 > 1) else if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO && t2 <= 1)
{ {
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1; /* if there is no block multi-threading, we use SOLID block */
if (temp > p->lzmaProps.reduceSize) p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID;
}
else
{
if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO)
{ {
UInt64 numBlocks = temp / p->blockSize; const UInt32 kMinSize = (UInt32)1 << 20;
if (numBlocks < t2) const UInt32 kMaxSize = (UInt32)1 << 28;
const UInt32 dictSize = p->lzmaProps.dictSize;
UInt64 blockSize = (UInt64)dictSize << 2;
if (blockSize < kMinSize) blockSize = kMinSize;
if (blockSize > kMaxSize) blockSize = kMaxSize;
if (blockSize < dictSize) blockSize = dictSize;
blockSize += (kMinSize - 1);
blockSize &= ~(UInt64)(kMinSize - 1);
p->blockSize = blockSize;
}
if (t2 > 1 && fileSize != (UInt64)(Int64)-1)
{
UInt64 numBlocks = fileSize / p->blockSize;
if (numBlocks * p->blockSize != fileSize)
numBlocks++;
if (numBlocks < (unsigned)t2)
{ {
t2 = (UInt32)numBlocks; t2r = (unsigned)numBlocks;
t3 = t1 * t2; if (t2r == 0)
t2r = 1;
t3 = t1 * t2r;
} }
} }
} }
p->numBlockThreads = t2;
p->numBlockThreads_Max = t2;
p->numBlockThreads_Reduced = t2r;
p->numTotalThreads = t3; 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 && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
} }
/* ---------- Lzma2 ---------- */ /* ---------- Lzma2 ---------- */
typedef struct typedef struct
{ {
Byte propEncoded; Byte propEncoded;
CLzma2EncProps props; CLzma2EncProps props;
UInt64 expectedDataSize;
Byte *outBuf; Byte *tempBufLzma;
ISzAlloc *alloc; ISzAllocPtr alloc;
ISzAlloc *allocBig; ISzAllocPtr allocBig;
CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX]; CLzma2EncInt coders[MTCODER__THREADS_MAX];
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
ISeqOutStream *outStream;
Byte *outBuf;
size_t outBuf_Rem; /* remainder in outBuf */
size_t outBufSize; /* size of allocated outBufs[i] */
size_t outBufsDataSizes[MTCODER__BLOCKS_MAX];
BoolInt mtCoder_WasConstructed;
CMtCoder mtCoder; CMtCoder mtCoder;
Byte *outBufs[MTCODER__BLOCKS_MAX];
#endif #endif
} CLzma2Enc; } CLzma2Enc;
/* ---------- Lzma2EncThread ---------- */
static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder, CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig)
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
{ {
UInt64 packTotal = 0; CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc));
SRes res = SZ_OK; if (!p)
if (mainEncoder->outBuf == 0)
{
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
if (mainEncoder->outBuf == 0)
return SZ_ERROR_MEM;
}
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
mainEncoder->alloc, mainEncoder->allocBig));
for (;;)
{
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream);
if (res != SZ_OK)
break;
packTotal += packSize;
res = Progress(progress, p->srcPos, packTotal);
if (res != SZ_OK)
break;
if (packSize == 0)
break;
}
LzmaEnc_Finish(p->enc);
if (res == SZ_OK)
{
Byte b = 0;
if (outStream->Write(outStream, &b, 1) != 1)
return SZ_ERROR_WRITE;
}
return res;
}
#ifndef _7ZIP_ST
typedef struct
{
IMtCoderCallback funcTable;
CLzma2Enc *lzma2Enc;
} CMtCallbackImp;
static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize,
const Byte *src, size_t srcSize, int finished)
{
CMtCallbackImp *imp = (CMtCallbackImp *)pp;
CLzma2Enc *mainEncoder = imp->lzma2Enc;
CLzma2EncInt *p = &mainEncoder->coders[index];
SRes res = SZ_OK;
{
size_t destLim = *destSize;
*destSize = 0;
if (srcSize != 0)
{
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE,
mainEncoder->alloc, mainEncoder->allocBig));
while (p->srcPos < srcSize)
{
size_t packSize = destLim - *destSize;
res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL);
if (res != SZ_OK)
break;
*destSize += packSize;
if (packSize == 0)
{
res = SZ_ERROR_FAIL;
break;
}
if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK)
{
res = SZ_ERROR_PROGRESS;
break;
}
}
LzmaEnc_Finish(p->enc);
if (res != SZ_OK)
return res;
}
if (finished)
{
if (*destSize == destLim)
return SZ_ERROR_OUTPUT_EOF;
dest[(*destSize)++] = 0;
}
}
return res;
}
#endif
/* ---------- Lzma2Enc ---------- */
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
if (p == 0)
return NULL; return NULL;
Lzma2EncProps_Init(&p->props); Lzma2EncProps_Init(&p->props);
Lzma2EncProps_Normalize(&p->props); Lzma2EncProps_Normalize(&p->props);
p->outBuf = 0; p->expectedDataSize = (UInt64)(Int64)-1;
p->tempBufLzma = NULL;
p->alloc = alloc; p->alloc = alloc;
p->allocBig = allocBig; p->allocBig = allocBig;
{ {
unsigned i; unsigned i;
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) for (i = 0; i < MTCODER__THREADS_MAX; i++)
p->coders[i].enc = 0; p->coders[i].enc = NULL;
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MtCoder_Construct(&p->mtCoder); p->mtCoder_WasConstructed = False;
{
unsigned i;
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
p->outBufs[i] = NULL;
p->outBufSize = 0;
}
#endif #endif
return p; return p;
} }
#ifndef _7ZIP_ST
static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p)
{
unsigned i;
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
if (p->outBufs[i])
{
ISzAlloc_Free(p->alloc, p->outBufs[i]);
p->outBufs[i] = NULL;
}
p->outBufSize = 0;
}
#endif
void Lzma2Enc_Destroy(CLzma2EncHandle pp) void Lzma2Enc_Destroy(CLzma2EncHandle pp)
{ {
CLzma2Enc *p = (CLzma2Enc *)pp; CLzma2Enc *p = (CLzma2Enc *)pp;
unsigned i; unsigned i;
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) for (i = 0; i < MTCODER__THREADS_MAX; i++)
{ {
CLzma2EncInt *t = &p->coders[i]; CLzma2EncInt *t = &p->coders[i];
if (t->enc) if (t->enc)
{ {
LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig); LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
t->enc = 0; t->enc = NULL;
} }
} }
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MtCoder_Destruct(&p->mtCoder); if (p->mtCoder_WasConstructed)
{
MtCoder_Destruct(&p->mtCoder);
p->mtCoder_WasConstructed = False;
}
Lzma2Enc_FreeOutBufs(p);
#endif #endif
IAlloc_Free(p->alloc, p->outBuf); ISzAlloc_Free(p->alloc, p->tempBufLzma);
IAlloc_Free(p->alloc, pp); p->tempBufLzma = NULL;
ISzAlloc_Free(p->alloc, pp);
} }
SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props) SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
{ {
CLzma2Enc *p = (CLzma2Enc *)pp; CLzma2Enc *p = (CLzma2Enc *)pp;
@@ -436,6 +474,14 @@ SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
return SZ_OK; return SZ_OK;
} }
void Lzma2Enc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
{
CLzma2Enc *p = (CLzma2Enc *)pp;
p->expectedDataSize = expectedDataSiize;
}
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp) Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
{ {
CLzma2Enc *p = (CLzma2Enc *)pp; CLzma2Enc *p = (CLzma2Enc *)pp;
@@ -447,47 +493,311 @@ Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
return (Byte)i; return (Byte)i;
} }
SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
{
CLzma2Enc *p = (CLzma2Enc *)pp;
int i;
for (i = 0; i < p->props.numBlockThreads; i++) static SRes Lzma2Enc_EncodeMt1(
CLzma2Enc *me,
CLzma2EncInt *p,
ISeqOutStream *outStream,
Byte *outBuf, size_t *outBufSize,
ISeqInStream *inStream,
const Byte *inData, size_t inDataSize,
int finished,
ICompressProgress *progress)
{
UInt64 unpackTotal = 0;
UInt64 packTotal = 0;
size_t outLim = 0;
CLimitedSeqInStream limitedInStream;
if (outBuf)
{ {
CLzma2EncInt *t = &p->coders[i]; outLim = *outBufSize;
if (t->enc == NULL) *outBufSize = 0;
}
if (!p->enc)
{
p->propsAreSet = False;
p->enc = LzmaEnc_Create(me->alloc);
if (!p->enc)
return SZ_ERROR_MEM;
}
limitedInStream.realStream = inStream;
if (inStream)
{
limitedInStream.vt.Read = LimitedSeqInStream_Read;
}
if (!outBuf)
{
// outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma
if (!me->tempBufLzma)
{ {
t->enc = LzmaEnc_Create(p->alloc); me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
if (t->enc == NULL) if (!me->tempBufLzma)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
} }
} }
#ifndef _7ZIP_ST RINOK(Lzma2EncInt_InitStream(p, &me->props));
if (p->props.numBlockThreads <= 1)
#endif
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
#ifndef _7ZIP_ST for (;;)
{
SRes res = SZ_OK;
size_t inSizeCur = 0;
Lzma2EncInt_InitBlock(p);
LimitedSeqInStream_Init(&limitedInStream);
limitedInStream.limit = me->props.blockSize;
if (inStream)
{
UInt64 expected = (UInt64)(Int64)-1;
// inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize
if (me->expectedDataSize != (UInt64)(Int64)-1
&& me->expectedDataSize >= unpackTotal)
expected = me->expectedDataSize - unpackTotal;
if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
&& expected > me->props.blockSize)
expected = (size_t)me->props.blockSize;
LzmaEnc_SetDataSize(p->enc, expected);
RINOK(LzmaEnc_PrepareForLzma2(p->enc,
&limitedInStream.vt,
LZMA2_KEEP_WINDOW_SIZE,
me->alloc,
me->allocBig));
}
else
{
inSizeCur = inDataSize - (size_t)unpackTotal;
if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
&& inSizeCur > me->props.blockSize)
inSizeCur = (size_t)me->props.blockSize;
// LzmaEnc_SetDataSize(p->enc, inSizeCur);
RINOK(LzmaEnc_MemPrepare(p->enc,
inData + (size_t)unpackTotal, inSizeCur,
LZMA2_KEEP_WINDOW_SIZE,
me->alloc,
me->allocBig));
}
for (;;)
{
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
if (outBuf)
packSize = outLim - (size_t)packTotal;
res = Lzma2EncInt_EncodeSubblock(p,
outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize,
outBuf ? NULL : outStream);
if (res != SZ_OK)
break;
packTotal += packSize;
if (outBuf)
*outBufSize = (size_t)packTotal;
res = Progress(progress, unpackTotal + p->srcPos, packTotal);
if (res != SZ_OK)
break;
/*
if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0)
break;
*/
if (packSize == 0)
break;
}
LzmaEnc_Finish(p->enc);
unpackTotal += p->srcPos;
RINOK(res);
if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur))
return SZ_ERROR_FAIL;
if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize))
{
if (finished)
{
if (outBuf)
{
size_t destPos = *outBufSize;
if (destPos >= outLim)
return SZ_ERROR_OUTPUT_EOF;
outBuf[destPos] = 0;
*outBufSize = destPos + 1;
}
else
{
Byte b = 0;
if (ISeqOutStream_Write(outStream, &b, 1) != 1)
return SZ_ERROR_WRITE;
}
}
return SZ_OK;
}
}
}
#ifndef _7ZIP_ST
static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex,
const Byte *src, size_t srcSize, int finished)
{
CLzma2Enc *me = (CLzma2Enc *)pp;
size_t destSize = me->outBufSize;
SRes res;
CMtProgressThunk progressThunk;
Byte *dest = me->outBufs[outBufIndex];
me->outBufsDataSizes[outBufIndex] = 0;
if (!dest)
{
dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize);
if (!dest)
return SZ_ERROR_MEM;
me->outBufs[outBufIndex] = dest;
}
MtProgressThunk_CreateVTable(&progressThunk);
progressThunk.mtProgress = &me->mtCoder.mtProgress;
progressThunk.inSize = 0;
progressThunk.outSize = 0;
res = Lzma2Enc_EncodeMt1(me,
&me->coders[coderIndex],
NULL, dest, &destSize,
NULL, src, srcSize,
finished,
&progressThunk.vt);
me->outBufsDataSizes[outBufIndex] = destSize;
return res;
}
static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex)
{
CLzma2Enc *me = (CLzma2Enc *)pp;
size_t size = me->outBufsDataSizes[outBufIndex];
const Byte *data = me->outBufs[outBufIndex];
if (me->outStream)
return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE;
if (size > me->outBuf_Rem)
return SZ_ERROR_OUTPUT_EOF;
memcpy(me->outBuf, data, size);
me->outBuf_Rem -= size;
me->outBuf += size;
return SZ_OK;
}
#endif
SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
ISeqOutStream *outStream,
Byte *outBuf, size_t *outBufSize,
ISeqInStream *inStream,
const Byte *inData, size_t inDataSize,
ICompressProgress *progress)
{
CLzma2Enc *p = (CLzma2Enc *)pp;
if (inStream && inData)
return SZ_ERROR_PARAM;
if (outStream && outBuf)
return SZ_ERROR_PARAM;
{ {
CMtCallbackImp mtCallback; unsigned i;
for (i = 0; i < MTCODER__THREADS_MAX; i++)
p->coders[i].propsAreSet = False;
}
mtCallback.funcTable.Code = MtCallbackImp_Code; #ifndef _7ZIP_ST
mtCallback.lzma2Enc = p;
if (p->props.numBlockThreads_Reduced > 1)
{
IMtCoderCallback2 vt;
if (!p->mtCoder_WasConstructed)
{
p->mtCoder_WasConstructed = True;
MtCoder_Construct(&p->mtCoder);
}
vt.Code = Lzma2Enc_MtCallback_Code;
vt.Write = Lzma2Enc_MtCallback_Write;
p->outStream = outStream;
p->outBuf = NULL;
p->outBuf_Rem = 0;
if (!outStream)
{
p->outBuf = outBuf;
p->outBuf_Rem = *outBufSize;
*outBufSize = 0;
}
p->mtCoder.allocBig = p->allocBig;
p->mtCoder.progress = progress; p->mtCoder.progress = progress;
p->mtCoder.inStream = inStream; p->mtCoder.inStream = inStream;
p->mtCoder.outStream = outStream; p->mtCoder.inData = inData;
p->mtCoder.alloc = p->alloc; p->mtCoder.inDataSize = inDataSize;
p->mtCoder.mtCallback = &mtCallback.funcTable; p->mtCoder.mtCallback = &vt;
p->mtCoder.mtCallbackObject = p;
p->mtCoder.blockSize = p->props.blockSize; p->mtCoder.blockSize = (size_t)p->props.blockSize;
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16; if (p->mtCoder.blockSize != p->props.blockSize)
p->mtCoder.numThreads = p->props.numBlockThreads; return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */
return MtCoder_Code(&p->mtCoder); {
size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16;
if (destBlockSize < p->mtCoder.blockSize)
return SZ_ERROR_PARAM;
if (p->outBufSize != destBlockSize)
Lzma2Enc_FreeOutBufs(p);
p->outBufSize = destBlockSize;
}
p->mtCoder.numThreadsMax = p->props.numBlockThreads_Max;
p->mtCoder.expectedDataSize = p->expectedDataSize;
{
SRes res = MtCoder_Code(&p->mtCoder);
if (!outStream)
*outBufSize = p->outBuf - outBuf;
return res;
}
} }
#endif #endif
return Lzma2Enc_EncodeMt1(p,
&p->coders[0],
outStream, outBuf, outBufSize,
inStream, inData, inDataSize,
True, /* finished */
progress);
} }

View File

@@ -1,5 +1,5 @@
/* Lzma2Enc.h -- LZMA2 Encoder /* Lzma2Enc.h -- LZMA2 Encoder
2013-01-18 : Igor Pavlov : Public domain */ 2017-07-27 : Igor Pavlov : Public domain */
#ifndef __LZMA2_ENC_H #ifndef __LZMA2_ENC_H
#define __LZMA2_ENC_H #define __LZMA2_ENC_H
@@ -8,11 +8,15 @@
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0
#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1)
typedef struct typedef struct
{ {
CLzmaEncProps lzmaProps; CLzmaEncProps lzmaProps;
size_t blockSize; UInt64 blockSize;
int numBlockThreads; int numBlockThreads_Reduced;
int numBlockThreads_Max;
int numTotalThreads; int numTotalThreads;
} CLzma2EncProps; } CLzma2EncProps;
@@ -22,40 +26,29 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p);
/* ---------- CLzmaEnc2Handle Interface ---------- */ /* ---------- CLzmaEnc2Handle Interface ---------- */
/* Lzma2Enc_* functions can return the following exit codes: /* Lzma2Enc_* functions can return the following exit codes:
Returns: SRes:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - Write callback error SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/ */
typedef void * CLzma2EncHandle; typedef void * CLzma2EncHandle;
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig); CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
void Lzma2Enc_Destroy(CLzma2EncHandle p); void Lzma2Enc_Destroy(CLzma2EncHandle p);
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize);
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
SRes Lzma2Enc_Encode(CLzma2EncHandle p, SRes Lzma2Enc_Encode2(CLzma2EncHandle p,
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress); ISeqOutStream *outStream,
Byte *outBuf, size_t *outBufSize,
/* ---------- One Call Interface ---------- */ ISeqInStream *inStream,
const Byte *inData, size_t inDataSize,
/* Lzma2Encode ICompressProgress *progress);
Return code:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
/*
SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
*/
EXTERN_C_END EXTERN_C_END

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 */ 2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Lzma86.h" #include "Lzma86.h"
@@ -7,9 +9,6 @@
#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 SzFree(void *p, void *address) { p = p; MyFree(address); }
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
{ {
unsigned i; unsigned i;
@@ -23,7 +22,6 @@ SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
{ {
ISzAlloc g_Alloc = { SzAlloc, SzFree };
SRes res; SRes res;
int useFilter; int useFilter;
SizeT inSizePure; SizeT inSizePure;

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 */ 2018-07-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -11,16 +13,12 @@
#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 SzFree(void *p, void *address) { p = 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)
{ {
ISzAlloc g_Alloc = { SzAlloc, SzFree };
size_t outSize2 = *destLen; size_t outSize2 = *destLen;
Byte *filteredStream; Byte *filteredStream;
Bool useFilter; BoolInt useFilter;
int mainResult = SZ_ERROR_OUTPUT_EOF; int mainResult = SZ_ERROR_OUTPUT_EOF;
CLzmaEncProps props; CLzmaEncProps props;
LzmaEncProps_Init(&props); LzmaEncProps_Init(&props);
@@ -58,7 +56,7 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
{ {
size_t minSize = 0; size_t minSize = 0;
Bool bestIsFiltered = False; BoolInt bestIsFiltered = False;
/* passes for SZ_FILTER_AUTO: /* passes for SZ_FILTER_AUTO:
0 - BCJ + LZMA 0 - BCJ + LZMA
@@ -73,7 +71,7 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
size_t outPropsSize = 5; size_t outPropsSize = 5;
SRes curRes; SRes curRes;
Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
if (curModeIsFiltered && !bestIsFiltered) if (curModeIsFiltered && !bestIsFiltered)
break; break;
if (useFilter && i == 0) if (useFilter && i == 0)

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2013-01-18 : Igor Pavlov : Public domain */ 2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H #ifndef __LZMA_DEC_H
#define __LZMA_DEC_H #define __LZMA_DEC_H
@@ -12,11 +12,13 @@ EXTERN_C_BEGIN
/* _LZMA_PROB32 can increase the speed on some CPUs, /* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */ but memory usage for CLzmaDec::probs will be doubled in that case */
typedef
#ifdef _LZMA_PROB32 #ifdef _LZMA_PROB32
#define CLzmaProb UInt32 UInt32
#else #else
#define CLzmaProb UInt16 UInt16
#endif #endif
CLzmaProb;
/* ---------- LZMA Properties ---------- */ /* ---------- LZMA Properties ---------- */
@@ -25,7 +27,10 @@ EXTERN_C_BEGIN
typedef struct _CLzmaProps typedef struct _CLzmaProps
{ {
unsigned lc, lp, pb; Byte lc;
Byte lp;
Byte pb;
Byte _pad_;
UInt32 dicSize; UInt32 dicSize;
} CLzmaProps; } CLzmaProps;
@@ -47,32 +52,34 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
typedef struct typedef struct
{ {
/* Don't change this structure. ASM code can use it. */
CLzmaProps prop; CLzmaProps prop;
CLzmaProb *probs; CLzmaProb *probs;
CLzmaProb *probs_1664;
Byte *dic; Byte *dic;
const Byte *buf;
UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize; SizeT dicBufSize;
SizeT dicPos;
const Byte *buf;
UInt32 range;
UInt32 code;
UInt32 processedPos; UInt32 processedPos;
UInt32 checkDicSize; UInt32 checkDicSize;
unsigned state;
UInt32 reps[4]; UInt32 reps[4];
unsigned remainLen; UInt32 state;
int needFlush; UInt32 remainLen;
int needInitState;
UInt32 numProbs; UInt32 numProbs;
unsigned tempBufSize; unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } #define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams: /* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum typedef enum
{ {
@@ -129,11 +136,11 @@ LzmaDec_Allocate* can return:
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */ /* ---------- Dictionary Interface ---------- */
@@ -142,7 +149,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
You must work with CLzmaDec variables directly in this interface. You must work with CLzmaDec variables directly in this interface.
STEPS: STEPS:
LzmaDec_Constr() LzmaDec_Construct()
LzmaDec_Allocate() LzmaDec_Allocate()
for (each new stream) for (each new stream)
{ {
@@ -220,7 +227,7 @@ Returns:
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc); ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

View File

File diff suppressed because it is too large Load Diff

View File

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

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;

View File

@@ -1,170 +1,89 @@
/* MtCoder.c -- Multi-thread Coder /* MtCoder.c -- Multi-thread Coder
2010-09-24 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdio.h>
#include "MtCoder.h" #include "MtCoder.h"
void LoopThread_Construct(CLoopThread *p) #ifndef _7ZIP_ST
{
Thread_Construct(&p->thread);
Event_Construct(&p->startEvent);
Event_Construct(&p->finishedEvent);
}
void LoopThread_Close(CLoopThread *p) SRes MtProgressThunk_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize)
{ {
Thread_Close(&p->thread); CMtProgressThunk *thunk = CONTAINER_FROM_VTBL(pp, CMtProgressThunk, vt);
Event_Close(&p->startEvent); UInt64 inSize2 = 0;
Event_Close(&p->finishedEvent); UInt64 outSize2 = 0;
} if (inSize != (UInt64)(Int64)-1)
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE LoopThreadFunc(void *pp)
{
CLoopThread *p = (CLoopThread *)pp;
for (;;)
{ {
if (Event_Wait(&p->startEvent) != 0) inSize2 = inSize - thunk->inSize;
return SZ_ERROR_THREAD; thunk->inSize = inSize;
if (p->stop) }
return 0; if (outSize != (UInt64)(Int64)-1)
p->res = p->func(p->param); {
if (Event_Set(&p->finishedEvent) != 0) outSize2 = outSize - thunk->outSize;
return SZ_ERROR_THREAD; thunk->outSize = outSize;
}
return MtProgress_ProgressAdd(thunk->mtProgress, inSize2, outSize2);
}
void MtProgressThunk_CreateVTable(CMtProgressThunk *p)
{
p->vt.Progress = MtProgressThunk_Progress;
}
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
static WRes ArEvent_OptCreate_And_Reset(CEvent *p)
{
if (Event_IsCreated(p))
return Event_Reset(p);
return AutoResetEvent_CreateNotSignaled(p);
}
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp);
static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t)
{
WRes wres = ArEvent_OptCreate_And_Reset(&t->startEvent);
if (wres == 0)
{
t->stop = False;
if (!Thread_WasCreated(&t->thread))
wres = Thread_Create(&t->thread, ThreadFunc, t);
if (wres == 0)
wres = Event_Set(&t->startEvent);
}
if (wres == 0)
return SZ_OK;
return MY_SRes_HRESULT_FROM_WRes(wres);
}
static void MtCoderThread_Destruct(CMtCoderThread *t)
{
if (Thread_WasCreated(&t->thread))
{
t->stop = 1;
Event_Set(&t->startEvent);
Thread_Wait(&t->thread);
Thread_Close(&t->thread);
}
Event_Close(&t->startEvent);
if (t->inBuf)
{
ISzAlloc_Free(t->mtCoder->allocBig, t->inBuf);
t->inBuf = NULL;
} }
} }
WRes LoopThread_Create(CLoopThread *p)
{
p->stop = 0;
RINOK(AutoResetEvent_CreateNotSignaled(&p->startEvent));
RINOK(AutoResetEvent_CreateNotSignaled(&p->finishedEvent));
return Thread_Create(&p->thread, LoopThreadFunc, p);
}
WRes LoopThread_StopAndWait(CLoopThread *p)
{
p->stop = 1;
if (Event_Set(&p->startEvent) != 0)
return SZ_ERROR_THREAD;
return Thread_Wait(&p->thread);
}
WRes LoopThread_StartSubThread(CLoopThread *p) { return Event_Set(&p->startEvent); }
WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEvent); }
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
}
static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)
{
unsigned i;
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
p->inSizes[i] = p->outSizes[i] = 0;
p->totalInSize = p->totalOutSize = 0;
p->progress = progress;
p->res = SZ_OK;
}
static void MtProgress_Reinit(CMtProgress *p, unsigned index)
{
p->inSizes[index] = 0;
p->outSizes[index] = 0;
}
#define UPDATE_PROGRESS(size, prev, total) \
if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; }
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize)
{
SRes res;
CriticalSection_Enter(&p->cs);
UPDATE_PROGRESS(inSize, p->inSizes[index], p->totalInSize)
UPDATE_PROGRESS(outSize, p->outSizes[index], p->totalOutSize)
if (p->res == SZ_OK)
p->res = Progress(p->progress, p->totalInSize, p->totalOutSize);
res = p->res;
CriticalSection_Leave(&p->cs);
return res;
}
static void MtProgress_SetError(CMtProgress *p, SRes res)
{
CriticalSection_Enter(&p->cs);
if (p->res == SZ_OK)
p->res = res;
CriticalSection_Leave(&p->cs);
}
static void MtCoder_SetError(CMtCoder* p, SRes res)
{
CriticalSection_Enter(&p->cs);
if (p->res == SZ_OK)
p->res = res;
CriticalSection_Leave(&p->cs);
}
/* ---------- MtThread ---------- */
void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
{
p->mtCoder = mtCoder;
p->outBuf = 0;
p->inBuf = 0;
Event_Construct(&p->canRead);
Event_Construct(&p->canWrite);
LoopThread_Construct(&p->thread);
}
#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }
static void CMtThread_CloseEvents(CMtThread *p)
{
Event_Close(&p->canRead);
Event_Close(&p->canWrite);
}
static void CMtThread_Destruct(CMtThread *p)
{
CMtThread_CloseEvents(p);
if (Thread_WasCreated(&p->thread.thread))
{
LoopThread_StopAndWait(&p->thread);
LoopThread_Close(&p->thread);
}
if (p->mtCoder->alloc)
IAlloc_Free(p->mtCoder->alloc, p->outBuf);
p->outBuf = 0;
if (p->mtCoder->alloc)
IAlloc_Free(p->mtCoder->alloc, p->inBuf);
p->inBuf = 0;
}
#define MY_BUF_ALLOC(buf, size, newSize) \
if (buf == 0 || size != newSize) \
{ IAlloc_Free(p->mtCoder->alloc, buf); \
size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \
if (buf == 0) return SZ_ERROR_MEM; }
static SRes CMtThread_Prepare(CMtThread *p)
{
MY_BUF_ALLOC(p->inBuf, p->inBufSize, p->mtCoder->blockSize)
MY_BUF_ALLOC(p->outBuf, p->outBufSize, p->mtCoder->destBlockSize)
p->stopReading = False;
p->stopWriting = False;
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canRead));
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canWrite));
return SZ_OK;
}
static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize) static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
{ {
@@ -172,158 +91,511 @@ static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
*processedSize = 0; *processedSize = 0;
while (size != 0) while (size != 0)
{ {
size_t curSize = size; size_t cur = size;
SRes res = stream->Read(stream, data, &curSize); SRes res = ISeqInStream_Read(stream, data, &cur);
*processedSize += curSize; *processedSize += cur;
data += curSize; data += cur;
size -= curSize; size -= cur;
RINOK(res); RINOK(res);
if (curSize == 0) if (cur == 0)
return SZ_OK; return SZ_OK;
} }
return SZ_OK; return SZ_OK;
} }
#define GET_NEXT_THREAD(p) &p->mtCoder->threads[p->index == p->mtCoder->numThreads - 1 ? 0 : p->index + 1]
static SRes MtThread_Process(CMtThread *p, Bool *stop) /*
ThreadFunc2() returns:
SZ_OK - in all normal cases (even for stream error or memory allocation error)
SZ_ERROR_THREAD - in case of failure in system synch function
*/
static SRes ThreadFunc2(CMtCoderThread *t)
{ {
CMtThread *next; CMtCoder *mtc = t->mtCoder;
*stop = True;
if (Event_Wait(&p->canRead) != 0)
return SZ_ERROR_THREAD;
next = GET_NEXT_THREAD(p);
if (p->stopReading)
{
next->stopReading = True;
return Event_Set(&next->canRead) == 0 ? SZ_OK : SZ_ERROR_THREAD;
}
{
size_t size = p->mtCoder->blockSize;
size_t destSize = p->outBufSize;
RINOK(FullRead(p->mtCoder->inStream, p->inBuf, &size));
next->stopReading = *stop = (size != p->mtCoder->blockSize);
if (Event_Set(&next->canRead) != 0)
return SZ_ERROR_THREAD;
RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index,
p->outBuf, &destSize, p->inBuf, size, *stop));
MtProgress_Reinit(&p->mtCoder->mtProgress, p->index);
if (Event_Wait(&p->canWrite) != 0)
return SZ_ERROR_THREAD;
if (p->stopWriting)
return SZ_ERROR_FAIL;
if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize)
return SZ_ERROR_WRITE;
return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD;
}
}
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
{
CMtThread *p = (CMtThread *)pp;
for (;;) for (;;)
{ {
Bool stop; unsigned bi;
CMtThread *next = GET_NEXT_THREAD(p); SRes res;
SRes res = MtThread_Process(p, &stop); SRes res2;
if (res != SZ_OK) BoolInt finished;
unsigned bufIndex;
size_t size;
const Byte *inData;
UInt64 readProcessed = 0;
RINOK_THREAD(Event_Wait(&mtc->readEvent))
/* after Event_Wait(&mtc->readEvent) we must call Event_Set(&mtc->readEvent) in any case to unlock another threads */
if (mtc->stopReading)
{ {
MtCoder_SetError(p->mtCoder, res); return Event_Set(&mtc->readEvent) == 0 ? SZ_OK : SZ_ERROR_THREAD;
MtProgress_SetError(&p->mtCoder->mtProgress, res);
next->stopReading = True;
next->stopWriting = True;
Event_Set(&next->canRead);
Event_Set(&next->canWrite);
return res;
} }
if (stop)
res = MtProgress_GetError(&mtc->mtProgress);
size = 0;
inData = NULL;
finished = True;
if (res == SZ_OK)
{
size = mtc->blockSize;
if (mtc->inStream)
{
if (!t->inBuf)
{
t->inBuf = (Byte *)ISzAlloc_Alloc(mtc->allocBig, mtc->blockSize);
if (!t->inBuf)
res = SZ_ERROR_MEM;
}
if (res == SZ_OK)
{
res = FullRead(mtc->inStream, t->inBuf, &size);
readProcessed = mtc->readProcessed + size;
mtc->readProcessed = readProcessed;
}
if (res != SZ_OK)
{
mtc->readRes = res;
/* after reading error - we can stop encoding of previous blocks */
MtProgress_SetError(&mtc->mtProgress, res);
}
else
finished = (size != mtc->blockSize);
}
else
{
size_t rem;
readProcessed = mtc->readProcessed;
rem = mtc->inDataSize - (size_t)readProcessed;
if (size > rem)
size = rem;
inData = mtc->inData + (size_t)readProcessed;
readProcessed += size;
mtc->readProcessed = readProcessed;
finished = (mtc->inDataSize == (size_t)readProcessed);
}
}
/* we must get some block from blocksSemaphore before Event_Set(&mtc->readEvent) */
res2 = SZ_OK;
if (Semaphore_Wait(&mtc->blocksSemaphore) != 0)
{
res2 = SZ_ERROR_THREAD;
if (res == SZ_OK)
{
res = res2;
// MtProgress_SetError(&mtc->mtProgress, res);
}
}
bi = mtc->blockIndex;
if (++mtc->blockIndex >= mtc->numBlocksMax)
mtc->blockIndex = 0;
bufIndex = (unsigned)(int)-1;
if (res == SZ_OK)
res = MtProgress_GetError(&mtc->mtProgress);
if (res != SZ_OK)
finished = True;
if (!finished)
{
if (mtc->numStartedThreads < mtc->numStartedThreadsLimit
&& mtc->expectedDataSize != readProcessed)
{
res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads]);
if (res == SZ_OK)
mtc->numStartedThreads++;
else
{
MtProgress_SetError(&mtc->mtProgress, res);
finished = True;
}
}
}
if (finished)
mtc->stopReading = True;
RINOK_THREAD(Event_Set(&mtc->readEvent))
if (res2 != SZ_OK)
return res2;
if (res == SZ_OK)
{
CriticalSection_Enter(&mtc->cs);
bufIndex = mtc->freeBlockHead;
mtc->freeBlockHead = mtc->freeBlockList[bufIndex];
CriticalSection_Leave(&mtc->cs);
res = mtc->mtCallback->Code(mtc->mtCallbackObject, t->index, bufIndex,
mtc->inStream ? t->inBuf : inData, size, finished);
// MtProgress_Reinit(&mtc->mtProgress, t->index);
if (res != SZ_OK)
MtProgress_SetError(&mtc->mtProgress, res);
}
{
CMtCoderBlock *block = &mtc->blocks[bi];
block->res = res;
block->bufIndex = bufIndex;
block->finished = finished;
}
#ifdef MTCODER__USE_WRITE_THREAD
RINOK_THREAD(Event_Set(&mtc->writeEvents[bi]))
#else
{
unsigned wi;
{
CriticalSection_Enter(&mtc->cs);
wi = mtc->writeIndex;
if (wi == bi)
mtc->writeIndex = (unsigned)(int)-1;
else
mtc->ReadyBlocks[bi] = True;
CriticalSection_Leave(&mtc->cs);
}
if (wi != bi)
{
if (res != SZ_OK || finished)
return 0;
continue;
}
if (mtc->writeRes != SZ_OK)
res = mtc->writeRes;
for (;;)
{
if (res == SZ_OK && bufIndex != (unsigned)(int)-1)
{
res = mtc->mtCallback->Write(mtc->mtCallbackObject, bufIndex);
if (res != SZ_OK)
{
mtc->writeRes = res;
MtProgress_SetError(&mtc->mtProgress, res);
}
}
if (++wi >= mtc->numBlocksMax)
wi = 0;
{
BoolInt isReady;
CriticalSection_Enter(&mtc->cs);
if (bufIndex != (unsigned)(int)-1)
{
mtc->freeBlockList[bufIndex] = mtc->freeBlockHead;
mtc->freeBlockHead = bufIndex;
}
isReady = mtc->ReadyBlocks[wi];
if (isReady)
mtc->ReadyBlocks[wi] = False;
else
mtc->writeIndex = wi;
CriticalSection_Leave(&mtc->cs);
RINOK_THREAD(Semaphore_Release1(&mtc->blocksSemaphore))
if (!isReady)
break;
}
{
CMtCoderBlock *block = &mtc->blocks[wi];
if (res == SZ_OK && block->res != SZ_OK)
res = block->res;
bufIndex = block->bufIndex;
finished = block->finished;
}
}
}
#endif
if (finished || res != SZ_OK)
return 0; return 0;
} }
} }
void MtCoder_Construct(CMtCoder* p)
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
{
CMtCoderThread *t = (CMtCoderThread *)pp;
for (;;)
{
if (Event_Wait(&t->startEvent) != 0)
return SZ_ERROR_THREAD;
if (t->stop)
return 0;
{
SRes res = ThreadFunc2(t);
CMtCoder *mtc = t->mtCoder;
if (res != SZ_OK)
{
MtProgress_SetError(&mtc->mtProgress, res);
}
#ifndef MTCODER__USE_WRITE_THREAD
{
unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads);
if (numFinished == mtc->numStartedThreads)
if (Event_Set(&mtc->finishedEvent) != 0)
return SZ_ERROR_THREAD;
}
#endif
}
}
}
void MtCoder_Construct(CMtCoder *p)
{ {
unsigned i; unsigned i;
p->alloc = 0;
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++) p->blockSize = 0;
p->numThreadsMax = 0;
p->expectedDataSize = (UInt64)(Int64)-1;
p->inStream = NULL;
p->inData = NULL;
p->inDataSize = 0;
p->progress = NULL;
p->allocBig = NULL;
p->mtCallback = NULL;
p->mtCallbackObject = NULL;
p->allocatedBufsSize = 0;
Event_Construct(&p->readEvent);
Semaphore_Construct(&p->blocksSemaphore);
for (i = 0; i < MTCODER__THREADS_MAX; i++)
{ {
CMtThread *t = &p->threads[i]; CMtCoderThread *t = &p->threads[i];
t->mtCoder = p;
t->index = i; t->index = i;
CMtThread_Construct(t, p); t->inBuf = NULL;
t->stop = False;
Event_Construct(&t->startEvent);
Thread_Construct(&t->thread);
} }
#ifdef MTCODER__USE_WRITE_THREAD
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
Event_Construct(&p->writeEvents[i]);
#else
Event_Construct(&p->finishedEvent);
#endif
CriticalSection_Init(&p->cs); CriticalSection_Init(&p->cs);
CriticalSection_Init(&p->mtProgress.cs); CriticalSection_Init(&p->mtProgress.cs);
} }
void MtCoder_Destruct(CMtCoder* p)
static void MtCoder_Free(CMtCoder *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
CMtThread_Destruct(&p->threads[i]); /*
p->stopReading = True;
if (Event_IsCreated(&p->readEvent))
Event_Set(&p->readEvent);
*/
for (i = 0; i < MTCODER__THREADS_MAX; i++)
MtCoderThread_Destruct(&p->threads[i]);
Event_Close(&p->readEvent);
Semaphore_Close(&p->blocksSemaphore);
#ifdef MTCODER__USE_WRITE_THREAD
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
Event_Close(&p->writeEvents[i]);
#else
Event_Close(&p->finishedEvent);
#endif
}
void MtCoder_Destruct(CMtCoder *p)
{
MtCoder_Free(p);
CriticalSection_Delete(&p->cs); CriticalSection_Delete(&p->cs);
CriticalSection_Delete(&p->mtProgress.cs); CriticalSection_Delete(&p->mtProgress.cs);
} }
SRes MtCoder_Code(CMtCoder *p) SRes MtCoder_Code(CMtCoder *p)
{ {
unsigned i, numThreads = p->numThreads; unsigned numThreads = p->numThreadsMax;
unsigned numBlocksMax;
unsigned i;
SRes res = SZ_OK; SRes res = SZ_OK;
p->res = SZ_OK;
if (numThreads > MTCODER__THREADS_MAX)
numThreads = MTCODER__THREADS_MAX;
numBlocksMax = MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads);
if (p->blockSize < ((UInt32)1 << 26)) numBlocksMax++;
if (p->blockSize < ((UInt32)1 << 24)) numBlocksMax++;
if (p->blockSize < ((UInt32)1 << 22)) numBlocksMax++;
if (numBlocksMax > MTCODER__BLOCKS_MAX)
numBlocksMax = MTCODER__BLOCKS_MAX;
if (p->blockSize != p->allocatedBufsSize)
{
for (i = 0; i < MTCODER__THREADS_MAX; i++)
{
CMtCoderThread *t = &p->threads[i];
if (t->inBuf)
{
ISzAlloc_Free(p->allocBig, t->inBuf);
t->inBuf = NULL;
}
}
p->allocatedBufsSize = p->blockSize;
}
p->readRes = SZ_OK;
MtProgress_Init(&p->mtProgress, p->progress); MtProgress_Init(&p->mtProgress, p->progress);
for (i = 0; i < numThreads; i++) #ifdef MTCODER__USE_WRITE_THREAD
for (i = 0; i < numBlocksMax; i++)
{
RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->writeEvents[i]));
}
#else
RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->finishedEvent));
#endif
{ {
RINOK(CMtThread_Prepare(&p->threads[i])); RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->readEvent));
if (Semaphore_IsCreated(&p->blocksSemaphore))
{
RINOK_THREAD(Semaphore_Close(&p->blocksSemaphore));
}
RINOK_THREAD(Semaphore_Create(&p->blocksSemaphore, numBlocksMax, numBlocksMax));
} }
for (i = 0; i < numThreads; i++) for (i = 0; i < MTCODER__BLOCKS_MAX - 1; i++)
p->freeBlockList[i] = i + 1;
p->freeBlockList[MTCODER__BLOCKS_MAX - 1] = (unsigned)(int)-1;
p->freeBlockHead = 0;
p->readProcessed = 0;
p->blockIndex = 0;
p->numBlocksMax = numBlocksMax;
p->stopReading = False;
#ifndef MTCODER__USE_WRITE_THREAD
p->writeIndex = 0;
p->writeRes = SZ_OK;
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
p->ReadyBlocks[i] = False;
p->numFinishedThreads = 0;
#endif
p->numStartedThreadsLimit = numThreads;
p->numStartedThreads = 0;
// for (i = 0; i < numThreads; i++)
{ {
CMtThread *t = &p->threads[i]; CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++];
CLoopThread *lt = &t->thread; RINOK(MtCoderThread_CreateAndStart(nextThread));
}
if (!Thread_WasCreated(&lt->thread)) RINOK_THREAD(Event_Set(&p->readEvent))
#ifdef MTCODER__USE_WRITE_THREAD
{
unsigned bi = 0;
for (;; bi++)
{ {
lt->func = ThreadFunc; if (bi >= numBlocksMax)
lt->param = t; bi = 0;
RINOK_THREAD(Event_Wait(&p->writeEvents[bi]))
if (LoopThread_Create(lt) != SZ_OK)
{ {
res = SZ_ERROR_THREAD; const CMtCoderBlock *block = &p->blocks[bi];
break; unsigned bufIndex = block->bufIndex;
BoolInt finished = block->finished;
if (res == SZ_OK && block->res != SZ_OK)
res = block->res;
if (bufIndex != (unsigned)(int)-1)
{
if (res == SZ_OK)
{
res = p->mtCallback->Write(p->mtCallbackObject, bufIndex);
if (res != SZ_OK)
MtProgress_SetError(&p->mtProgress, res);
}
CriticalSection_Enter(&p->cs);
{
p->freeBlockList[bufIndex] = p->freeBlockHead;
p->freeBlockHead = bufIndex;
}
CriticalSection_Leave(&p->cs);
}
RINOK_THREAD(Semaphore_Release1(&p->blocksSemaphore))
if (finished)
break;
} }
} }
} }
#else
{
WRes wres = Event_Wait(&p->finishedEvent);
res = MY_SRes_HRESULT_FROM_WRes(wres);
}
#endif
if (res == SZ_OK) if (res == SZ_OK)
{ res = p->readRes;
unsigned j;
for (i = 0; i < numThreads; i++)
{
CMtThread *t = &p->threads[i];
if (LoopThread_StartSubThread(&t->thread) != SZ_OK)
{
res = SZ_ERROR_THREAD;
p->threads[0].stopReading = True;
break;
}
}
Event_Set(&p->threads[0].canWrite); if (res == SZ_OK)
Event_Set(&p->threads[0].canRead); res = p->mtProgress.res;
for (j = 0; j < i; j++) #ifndef MTCODER__USE_WRITE_THREAD
LoopThread_WaitSubThread(&p->threads[j].thread); if (res == SZ_OK)
} res = p->writeRes;
#endif
for (i = 0; i < numThreads; i++) if (res != SZ_OK)
CMtThread_CloseEvents(&p->threads[i]); MtCoder_Free(p);
return (res == SZ_OK) ? p->res : res; return res;
} }
#endif

View File

@@ -1,98 +1,141 @@
/* MtCoder.h -- Multi-thread Coder /* MtCoder.h -- Multi-thread Coder
2009-11-19 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#ifndef __MT_CODER_H #ifndef __MT_CODER_H
#define __MT_CODER_H #define __MT_CODER_H
#include "Threads.h" #include "MtDec.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
typedef struct /*
{ if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream
CThread thread; if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
CAutoResetEvent startEvent; */
CAutoResetEvent finishedEvent; /* #define MTCODER__USE_WRITE_THREAD */
int stop;
THREAD_FUNC_TYPE func;
LPVOID param;
THREAD_FUNC_RET_TYPE res;
} CLoopThread;
void LoopThread_Construct(CLoopThread *p);
void LoopThread_Close(CLoopThread *p);
WRes LoopThread_Create(CLoopThread *p);
WRes LoopThread_StopAndWait(CLoopThread *p);
WRes LoopThread_StartSubThread(CLoopThread *p);
WRes LoopThread_WaitSubThread(CLoopThread *p);
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
#define NUM_MT_CODER_THREADS_MAX 32 #define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
#define MTCODER__THREADS_MAX 64
#define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3)
#else #else
#define NUM_MT_CODER_THREADS_MAX 1 #define MTCODER__THREADS_MAX 1
#define MTCODER__BLOCKS_MAX 1
#endif #endif
#ifndef _7ZIP_ST
typedef struct typedef struct
{ {
UInt64 totalInSize; ICompressProgress vt;
UInt64 totalOutSize; CMtProgress *mtProgress;
ICompressProgress *progress; UInt64 inSize;
SRes res; UInt64 outSize;
CCriticalSection cs; } CMtProgressThunk;
UInt64 inSizes[NUM_MT_CODER_THREADS_MAX];
UInt64 outSizes[NUM_MT_CODER_THREADS_MAX]; void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
} CMtProgress;
#define MtProgressThunk_Init(p) { (p)->inSize = 0; (p)->outSize = 0; }
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize);
struct _CMtCoder; struct _CMtCoder;
typedef struct typedef struct
{ {
struct _CMtCoder *mtCoder; struct _CMtCoder *mtCoder;
Byte *outBuf;
size_t outBufSize;
Byte *inBuf;
size_t inBufSize;
unsigned index; unsigned index;
CLoopThread thread; int stop;
Byte *inBuf;
CAutoResetEvent startEvent;
CThread thread;
} CMtCoderThread;
Bool stopReading;
Bool stopWriting;
CAutoResetEvent canRead;
CAutoResetEvent canWrite;
} CMtThread;
typedef struct typedef struct
{ {
SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize, SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
const Byte *src, size_t srcSize, int finished); const Byte *src, size_t srcSize, int finished);
} IMtCoderCallback; SRes (*Write)(void *p, unsigned outBufIndex);
} IMtCoderCallback2;
typedef struct
{
SRes res;
unsigned bufIndex;
BoolInt finished;
} CMtCoderBlock;
typedef struct _CMtCoder typedef struct _CMtCoder
{ {
size_t blockSize; /* input variables */
size_t destBlockSize;
unsigned numThreads; size_t blockSize; /* size of input block */
unsigned numThreadsMax;
UInt64 expectedDataSize;
ISeqInStream *inStream; ISeqInStream *inStream;
ISeqOutStream *outStream; const Byte *inData;
ICompressProgress *progress; size_t inDataSize;
ISzAlloc *alloc;
ICompressProgress *progress;
ISzAllocPtr allocBig;
IMtCoderCallback2 *mtCallback;
void *mtCallbackObject;
/* internal variables */
size_t allocatedBufsSize;
CAutoResetEvent readEvent;
CSemaphore blocksSemaphore;
BoolInt stopReading;
SRes readRes;
#ifdef MTCODER__USE_WRITE_THREAD
CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX];
#else
CAutoResetEvent finishedEvent;
SRes writeRes;
unsigned writeIndex;
Byte ReadyBlocks[MTCODER__BLOCKS_MAX];
LONG numFinishedThreads;
#endif
unsigned numStartedThreadsLimit;
unsigned numStartedThreads;
unsigned numBlocksMax;
unsigned blockIndex;
UInt64 readProcessed;
IMtCoderCallback *mtCallback;
CCriticalSection cs; CCriticalSection cs;
SRes res;
unsigned freeBlockHead;
unsigned freeBlockList[MTCODER__BLOCKS_MAX];
CMtProgress mtProgress; CMtProgress mtProgress;
CMtThread threads[NUM_MT_CODER_THREADS_MAX]; CMtCoderBlock blocks[MTCODER__BLOCKS_MAX];
CMtCoderThread threads[MTCODER__THREADS_MAX];
} CMtCoder; } CMtCoder;
void MtCoder_Construct(CMtCoder* p);
void MtCoder_Destruct(CMtCoder* p); void MtCoder_Construct(CMtCoder *p);
void MtCoder_Destruct(CMtCoder *p);
SRes MtCoder_Code(CMtCoder *p); SRes MtCoder_Code(CMtCoder *p);
#endif
EXTERN_C_END EXTERN_C_END
#endif #endif

1138
C/MtDec.c Normal file
View File

File diff suppressed because it is too large Load Diff

201
C/MtDec.h Normal file
View File

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

View File

@@ -1,5 +1,5 @@
/* Ppmd.h -- PPMD codec common code /* Ppmd.h -- PPMD codec common code
2013-01-18 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
@@ -77,8 +77,8 @@ typedef
CPpmd_Byte_Ref; CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \ #define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END EXTERN_C_END

View File

@@ -1,10 +1,10 @@
/* Ppmd7.c -- PPMdH codec /* Ppmd7.c -- PPMdH codec
2010-03-12 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <memory.h> #include <string.h>
#include "Ppmd7.h" #include "Ppmd7.h"
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
#define UNIT_SIZE 12 #define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
#define U2I(nu) (p->Units2Indx[(nu) - 1]) #define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx]) #define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
@@ -66,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;
} }
@@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p)
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
} }
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc) void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->Base); ISzAlloc_Free(alloc, p->Base);
p->Size = 0; p->Size = 0;
p->Base = 0; p->Base = 0;
} }
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
{ {
if (p->Base == 0 || p->Size != size) if (!p->Base || p->Size != size)
{ {
size_t size2;
Ppmd7_Free(p, alloc); Ppmd7_Free(p, alloc);
size2 = 0
#ifndef PPMD_32BIT
+ UNIT_SIZE
#endif
;
p->AlignOffset = p->AlignOffset =
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
(4 - size) & 3; (4 - size) & 3;
#else #else
4 - (size & 3); 4 - (size & 3);
#endif #endif
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0)
#ifndef PPMD_32BIT
+ UNIT_SIZE
#endif
)) == 0)
return False; return False;
p->Size = size; p->Size = size;
} }
@@ -257,7 +259,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)
{ {
@@ -340,7 +342,7 @@ void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
p->DummySee.Count = 64; /* unused */ p->DummySee.Count = 64; /* unused */
} }
static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) static CTX_PTR CreateSuccessors(CPpmd7 *p, BoolInt skip)
{ {
CPpmd_State upState; CPpmd_State upState;
CTX_PTR c = p->MinContext; CTX_PTR c = p->MinContext;
@@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p)
/* Expand for one UNIT */ /* Expand for one UNIT */
unsigned oldNU = ns1 >> 1; unsigned oldNU = ns1 >> 1;
unsigned i = U2I(oldNU); unsigned i = U2I(oldNU);
if (i != U2I(oldNU + 1)) if (i != U2I((size_t)oldNU + 1))
{ {
void *ptr = AllocUnits(p, i + 1); void *ptr = AllocUnits(p, i + 1);
void *oldPtr; void *oldPtr;
@@ -639,10 +641,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
unsigned nonMasked = p->MinContext->NumStats - numMasked; unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256) if (p->MinContext->NumStats != 256)
{ {
see = p->See[p->NS2Indx[nonMasked - 1]] + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] +
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
4 * (numMasked > nonMasked) + 4 * (unsigned)(numMasked > nonMasked) +
p->HiBitsFlag; p->HiBitsFlag;
{ {
unsigned r = (see->Summ >> see->Shift); unsigned r = (see->Summ >> see->Shift);

View File

@@ -1,5 +1,5 @@
/* Ppmd7.h -- PPMdH compression codec /* Ppmd7.h -- PPMdH compression codec
2010-03-12 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation /* This code supports virtual RangeDecoder and includes the implementation
@@ -60,8 +60,8 @@ typedef struct
} CPpmd7; } CPpmd7;
void Ppmd7_Construct(CPpmd7 *p); void Ppmd7_Construct(CPpmd7 *p);
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
@@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p); void Ppmd7_UpdateBin(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \ #define Ppmd7_GetBinSumm(p) \
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ 2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
((p->RunLength >> 26) & 0x20)] ((p->RunLength >> 26) & 0x20)]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
@@ -97,26 +97,28 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */ /* ---------- Decode ---------- */
typedef struct typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
struct IPpmd7_RangeDec
{ {
UInt32 (*GetThreshold)(void *p, UInt32 total); UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
void (*Decode)(void *p, UInt32 start, UInt32 size); void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0); UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
} IPpmd7_RangeDec; };
typedef struct typedef struct
{ {
IPpmd7_RangeDec p; IPpmd7_RangeDec vt;
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
IByteIn *Stream; IByteIn *Stream;
} CPpmd7z_RangeDec; } CPpmd7z_RangeDec;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
/* ---------- Encode ---------- */ /* ---------- Encode ---------- */

View File

@@ -1,5 +1,5 @@
/* Ppmd7Dec.c -- PPMdH Decoder /* Ppmd7Dec.c -- PPMdH Decoder
2010-03-12 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -8,49 +8,51 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#define kTopValue (1 << 24) #define kTopValue (1 << 24)
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) BoolInt Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
{ {
unsigned i; unsigned i;
p->Code = 0; p->Code = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
if (p->Stream->Read((void *)p->Stream) != 0) if (IByteIn_Read(p->Stream) != 0)
return False; return False;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
return (p->Code < 0xFFFFFFFF); return (p->Code < 0xFFFFFFFF);
} }
static UInt32 Range_GetThreshold(void *pp, UInt32 total) #define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; GET_Ppmd7z_RangeDec
return (p->Code) / (p->Range /= total); return p->Code / (p->Range /= total);
} }
static void Range_Normalize(CPpmd7z_RangeDec *p) static void Range_Normalize(CPpmd7z_RangeDec *p)
{ {
if (p->Range < kTopValue) if (p->Range < kTopValue)
{ {
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8; p->Range <<= 8;
if (p->Range < kTopValue) if (p->Range < kTopValue)
{ {
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
p->Range <<= 8; p->Range <<= 8;
} }
} }
} }
static void Range_Decode(void *pp, UInt32 start, UInt32 size) static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; GET_Ppmd7z_RangeDec
p->Code -= start * p->Range; p->Code -= start * p->Range;
p->Range *= size; p->Range *= size;
Range_Normalize(p); Range_Normalize(p);
} }
static UInt32 Range_DecodeBit(void *pp, UInt32 size0) static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; GET_Ppmd7z_RangeDec
UInt32 newBound = (p->Range >> 14) * size0; UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol; UInt32 symbol;
if (p->Code < newBound) if (p->Code < newBound)
@@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{ {
p->p.GetThreshold = Range_GetThreshold; p->vt.GetThreshold = Range_GetThreshold;
p->p.Decode = Range_Decode; p->vt.Decode = Range_Decode;
p->p.DecodeBit = Range_DecodeBit; p->vt.DecodeBit = Range_DecodeBit;
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1) if (p->MinContext->NumStats != 1)

View File

@@ -1,5 +1,5 @@
/* Ppmd7Enc.c -- PPMdH Encoder /* Ppmd7Enc.c -- PPMdH Encoder
2010-03-12 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -23,10 +23,10 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
Byte temp = p->Cache; Byte temp = p->Cache;
do do
{ {
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); IByteOut_Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF; temp = 0xFF;
} }
while(--p->CacheSize != 0); while (--p->CacheSize != 0);
p->Cache = (Byte)((UInt32)p->Low >> 24); p->Cache = (Byte)((UInt32)p->Low >> 24);
} }
p->CacheSize++; p->CacheSize++;

View File

@@ -1,10 +1,10 @@
/* Ppmd8.c -- PPMdI codec /* Ppmd8.c -- PPMdI codec
2013-11-12 : Igor Pavlov : Public domain 2018-07-04 : 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 "Precomp.h" #include "Precomp.h"
#include <memory.h> #include <string.h>
#include "Ppmd8.h" #include "Ppmd8.h"
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
#define UNIT_SIZE 12 #define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
#define U2I(nu) (p->Units2Indx[(nu) - 1]) #define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx]) #define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
@@ -67,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;
} }
@@ -86,16 +86,16 @@ void Ppmd8_Construct(CPpmd8 *p)
} }
} }
void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc) void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->Base); ISzAlloc_Free(alloc, p->Base);
p->Size = 0; p->Size = 0;
p->Base = 0; p->Base = 0;
} }
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc) BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc)
{ {
if (p->Base == 0 || p->Size != size) if (!p->Base || p->Size != size)
{ {
Ppmd8_Free(p, alloc); Ppmd8_Free(p, alloc);
p->AlignOffset = p->AlignOffset =
@@ -104,7 +104,7 @@ Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
#else #else
4 - (size & 3); 4 - (size & 3);
#endif #endif
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size)) == 0) if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == 0)
return False; return False;
p->Size = size; p->Size = size;
} }
@@ -240,8 +240,8 @@ 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 *z = (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] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 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)
{ {
@@ -386,7 +386,7 @@ static void RestartModel(CPpmd8 *p)
for (i = m = 0; m < 24; m++) for (i = m = 0; m < 24; m++)
{ {
while (p->NS2Indx[i + 3] == m + 3) while (p->NS2Indx[(size_t)i + 3] == m + 3)
i++; i++;
for (k = 0; k < 32; k++) for (k = 0; k < 32; k++)
{ {
@@ -605,7 +605,7 @@ static void RestoreModel(CPpmd8 *p, CTX_PTR c1
} }
} }
static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c) static CTX_PTR CreateSuccessors(CPpmd8 *p, BoolInt skip, CPpmd_State *s1, CTX_PTR c)
{ {
CPpmd_State upState; CPpmd_State upState;
Byte flags; Byte flags;
@@ -772,7 +772,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
if (SUCCESSOR(s) <= upBranch) if (SUCCESSOR(s) <= upBranch)
{ {
CTX_PTR successor; CTX_PTR successor;
CPpmd_State *s1 = p->FoundState; CPpmd_State *s2 = p->FoundState;
p->FoundState = s; p->FoundState = s;
successor = CreateSuccessors(p, False, NULL, c); successor = CreateSuccessors(p, False, NULL, c);
@@ -780,7 +780,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
SetSuccessor(s, 0); SetSuccessor(s, 0);
else else
SetSuccessor(s, REF(successor)); SetSuccessor(s, REF(successor));
p->FoundState = s1; p->FoundState = s2;
} }
if (p->OrderFall == 1 && c1 == p->MaxContext) if (p->OrderFall == 1 && c1 == p->MaxContext)
@@ -905,7 +905,7 @@ static void UpdateModel(CPpmd8 *p)
/* Expand for one UNIT */ /* Expand for one UNIT */
unsigned oldNU = (ns1 + 1) >> 1; unsigned oldNU = (ns1 + 1) >> 1;
unsigned i = U2I(oldNU); unsigned i = U2I(oldNU);
if (i != U2I(oldNU + 1)) if (i != U2I((size_t)oldNU + 1))
{ {
void *ptr = AllocUnits(p, i + 1); void *ptr = AllocUnits(p, i + 1);
void *oldPtr; void *oldPtr;
@@ -924,19 +924,19 @@ static void UpdateModel(CPpmd8 *p)
} }
else else
{ {
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0);
if (!s) if (!s2)
{ {
RESTORE_MODEL(c, CTX(fSuccessor)); RESTORE_MODEL(c, CTX(fSuccessor));
return; return;
} }
*s = *ONE_STATE(c); *s2 = *ONE_STATE(c);
c->Stats = REF(s); c->Stats = REF(s2);
if (s->Freq < MAX_FREQ / 4 - 1) if (s2->Freq < MAX_FREQ / 4 - 1)
s->Freq <<= 1; s2->Freq <<= 1;
else else
s->Freq = MAX_FREQ - 4; s2->Freq = MAX_FREQ - 4;
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 2)); c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2));
} }
cf = 2 * fFreq * (c->SummFreq + 6); cf = 2 * fFreq * (c->SummFreq + 6);
sf = (UInt32)s0 + c->SummFreq; sf = (UInt32)s0 + c->SummFreq;
@@ -951,10 +951,10 @@ static void UpdateModel(CPpmd8 *p)
c->SummFreq = (UInt16)(c->SummFreq + cf); c->SummFreq = (UInt16)(c->SummFreq + cf);
} }
{ {
CPpmd_State *s = STATS(c) + ns1 + 1; CPpmd_State *s2 = STATS(c) + ns1 + 1;
SetSuccessor(s, successor); SetSuccessor(s2, successor);
s->Symbol = fSymbol; s2->Symbol = fSymbol;
s->Freq = (Byte)cf; s2->Freq = (Byte)cf;
c->Flags |= flag; c->Flags |= flag;
c->NumStats = (Byte)(ns1 + 1); c->NumStats = (Byte)(ns1 + 1);
} }
@@ -1038,9 +1038,9 @@ CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
CPpmd_See *see; CPpmd_See *see;
if (p->MinContext->NumStats != 0xFF) if (p->MinContext->NumStats != 0xFF)
{ {
see = p->See[p->NS2Indx[p->MinContext->NumStats + 2] - 3] + see = p->See[(size_t)(unsigned)p->NS2Indx[(size_t)(unsigned)p->MinContext->NumStats + 2] - 3] +
(p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) + (p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
2 * (2 * (unsigned)p->MinContext->NumStats < 2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) + ((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
p->MinContext->Flags; p->MinContext->Flags;
{ {

View File

@@ -1,5 +1,5 @@
/* Ppmd8.h -- PPMdI codec /* Ppmd8.h -- PPMdI codec
2011-01-27 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -86,8 +86,8 @@ typedef struct
} CPpmd8; } CPpmd8;
void Ppmd8_Construct(CPpmd8 *p); void Ppmd8_Construct(CPpmd8 *p);
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc); BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc); void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL) #define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
@@ -112,7 +112,7 @@ void Ppmd8_Update2(CPpmd8 *p);
void Ppmd8_UpdateBin(CPpmd8 *p); void Ppmd8_UpdateBin(CPpmd8 *p);
#define Ppmd8_GetBinSumm(p) \ #define Ppmd8_GetBinSumm(p) \
&p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \ &p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)] p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
@@ -121,7 +121,7 @@ CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
/* ---------- Decode ---------- */ /* ---------- Decode ---------- */
Bool Ppmd8_RangeDec_Init(CPpmd8 *p); BoolInt Ppmd8_RangeDec_Init(CPpmd8 *p);
#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) #define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */ int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */

View File

@@ -1,5 +1,5 @@
/* Ppmd8Dec.c -- PPMdI Decoder /* Ppmd8Dec.c -- PPMdI Decoder
2010-04-16 : Igor Pavlov : Public domain 2018-07-04 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -11,14 +11,14 @@ This code is based on:
#define kTop (1 << 24) #define kTop (1 << 24)
#define kBot (1 << 15) #define kBot (1 << 15)
Bool Ppmd8_RangeDec_Init(CPpmd8 *p) BoolInt Ppmd8_RangeDec_Init(CPpmd8 *p)
{ {
unsigned i; unsigned i;
p->Low = 0; p->Low = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
p->Code = 0; p->Code = 0;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
return (p->Code < 0xFFFFFFFF); return (p->Code < 0xFFFFFFFF);
} }
@@ -37,7 +37,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
while ((p->Low ^ (p->Low + p->Range)) < kTop || while ((p->Low ^ (p->Low + p->Range)) < kTop ||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{ {
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In); p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
p->Range <<= 8; p->Range <<= 8;
p->Low <<= 8; p->Low <<= 8;
} }

View File

@@ -1,5 +1,5 @@
/* Ppmd8Enc.c -- PPMdI Encoder /* Ppmd8Enc.c -- PPMdI Encoder
2010-04-16 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -15,7 +15,7 @@ void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < 4; i++, p->Low <<= 8 ) for (i = 0; i < 4; i++, p->Low <<= 8 )
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24)); IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
} }
static void RangeEnc_Normalize(CPpmd8 *p) static void RangeEnc_Normalize(CPpmd8 *p)
@@ -23,7 +23,7 @@ static void RangeEnc_Normalize(CPpmd8 *p)
while ((p->Low ^ (p->Low + p->Range)) < kTop || while ((p->Low ^ (p->Low + p->Range)) < kTop ||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
{ {
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24)); IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
p->Range <<= 8; p->Range <<= 8;
p->Low <<= 8; p->Low <<= 8;
} }

View File

@@ -1,5 +1,5 @@
/* RotateDefs.h -- Rotate functions /* RotateDefs.h -- Rotate functions
2013-11-12 : 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
@@ -8,16 +8,20 @@
#include <stdlib.h> #include <stdlib.h>
// #if (_MSC_VER >= 1200) /* don't use _rotl with MINGW. It can insert slow call to function. */
/* #if (_MSC_VER >= 1200) */
#pragma intrinsic(_rotl) #pragma intrinsic(_rotl)
#pragma intrinsic(_rotr) #pragma intrinsic(_rotr)
// #endif /* #endif */
#define rotlFixed(x, n) _rotl((x), (n)) #define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n)) #define rotrFixed(x, n) _rotr((x), (n))
#else #else
/* new compilers can translate these macros to fast commands. */
#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))))

340
C/Sha1.c Normal file
View File

@@ -0,0 +1,340 @@
/* Sha1.c -- SHA-1 Hash
2017-04-03 : 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 { size_t i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
#define RX_20(rx, ii) { size_t i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
#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)
{
size_t 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;
pos2 = (3 - pos2) * 8;
w = ((UInt32)*data++) << pos2;
if (--size && pos2)
{
pos2 -= 8;
w |= ((UInt32)*data++) << pos2;
if (--size && pos2)
{
pos2 -= 8;
w |= ((UInt32)*data++) << pos2;
size--;
}
}
p->buffer[pos] |= w;
if (pos2 == 0)
pos++;
}
for (;;)
{
if (pos == SHA1_NUM_BLOCK_WORDS)
{
for (;;)
{
size_t 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)
{
size_t 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;
returnRes = True;
}
}
}
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
2016-05-20 : 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

View File

@@ -1,14 +1,21 @@
/* Crypto/Sha256.c -- SHA-256 Hash /* Crypto/Sha256.c -- SHA-256 Hash
2010-06-11 : Igor Pavlov : Public domain 2017-04-03 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */ This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
#include <string.h>
#include "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)
@@ -29,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)+(size_t)(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); \
@@ -60,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)+(size_t)(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
@@ -92,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];
@@ -107,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
@@ -146,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);
} }

View File

@@ -1,9 +1,9 @@
/* Threads.c -- multithreading library /* Threads.c -- multithreading library
2013-11-12 : Igor Pavlov : Public domain */ 2017-06-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#ifndef _WIN32_WCE #ifndef UNDER_CE
#include <process.h> #include <process.h>
#endif #endif
@@ -12,18 +12,20 @@
static WRes GetError() static WRes GetError()
{ {
DWORD res = GetLastError(); DWORD res = GetLastError();
return (res) ? (WRes)(res) : 1; return res ? (WRes)res : 1;
} }
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
WRes HandlePtr_Close(HANDLE *p) WRes HandlePtr_Close(HANDLE *p)
{ {
if (*p != NULL) if (*p != NULL)
{
if (!CloseHandle(*p)) if (!CloseHandle(*p))
return GetError(); return GetError();
*p = NULL; *p = NULL;
}
return 0; return 0;
} }
@@ -49,7 +51,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
return HandleToWRes(*p); return HandleToWRes(*p);
} }
WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
{ {
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
return HandleToWRes(*p); return HandleToWRes(*p);

View File

@@ -1,5 +1,5 @@
/* Threads.h -- multithreading library /* Threads.h -- multithreading library
2013-11-12 : Igor Pavlov : Public domain */ 2017-06-18 : Igor Pavlov : Public domain */
#ifndef __7Z_THREADS_H #ifndef __7Z_THREADS_H
#define __7Z_THREADS_H #define __7Z_THREADS_H
@@ -49,7 +49,8 @@ WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
typedef HANDLE CSemaphore; typedef HANDLE CSemaphore;
#define Semaphore_Construct(p) (*p) = NULL #define Semaphore_Construct(p) *(p) = NULL
#define Semaphore_IsCreated(p) (*(p) != NULL)
#define Semaphore_Close(p) HandlePtr_Close(p) #define Semaphore_Close(p) HandlePtr_Close(p)
#define Semaphore_Wait(p) Handle_WaitObject(*(p)) #define Semaphore_Wait(p) Handle_WaitObject(*(p))
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);

View File

@@ -1,229 +0,0 @@
# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=7z - 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 "7z.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 "7z.mak" CFG="7z - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "7z - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /Yu"Precomp.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib 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
!ELSEIF "$(CFG)" == "7z - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /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 RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib 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
# Begin Target
# Name "7z - Win32 Release"
# Name "7z - 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
# ADD CPP /D "_7ZIP_PPMD_SUPPPORT"
# 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=..\..\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=..\..\CpuArch.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.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
# Begin Source File
SOURCE=..\..\Ppmd.h
# End Source File
# Begin Source File
SOURCE=..\..\Ppmd7.c
# End Source File
# Begin Source File
SOURCE=..\..\Ppmd7.h
# End Source File
# Begin Source File
SOURCE=..\..\Ppmd7Dec.c
# End Source File
# End Group
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compiler.h
# End Source File
# 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=.\7zMain.c
# End Source File
# End Target
# End Project

View File

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

View File

@@ -1,11 +1,13 @@
/* 7zMain.c - Test application for 7z Decoder /* 7zMain.c - Test application for 7z Decoder
2015-01-02 : Igor Pavlov : Public domain */ 2019-02-02 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../../CpuArch.h"
#include "../../7z.h" #include "../../7z.h"
#include "../../7zAlloc.h" #include "../../7zAlloc.h"
#include "../../7zBuf.h" #include "../../7zBuf.h"
@@ -23,7 +25,17 @@
#endif #endif
#endif #endif
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
#define kInputBufSize ((size_t)1 << 18)
static const ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void Print(const char *s)
{
fputs(s, stdout);
}
static int Buf_EnsureSize(CBuf *dest, size_t size) static int Buf_EnsureSize(CBuf *dest, size_t size)
{ {
@@ -34,75 +46,117 @@ 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 static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
#ifdef _WIN32 #ifndef _USE_UTF8
, UINT codePage , UINT codePage
#endif #endif
) )
@@ -110,7 +164,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
unsigned len = 0; unsigned len = 0;
for (len = 0; s[len] != 0; len++); for (len = 0; s[len] != 0; len++);
#ifdef _WIN32 #ifndef _USE_UTF8
{ {
unsigned size = len * 3 + 100; unsigned size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size)) if (!Buf_EnsureSize(buf, size))
@@ -122,7 +176,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
char defaultChar = '_'; char defaultChar = '_';
BOOL defUsed; BOOL defUsed;
unsigned numChars = 0; unsigned numChars = 0;
numChars = WideCharToMultiByte(codePage, 0, s, len, (char *)buf->data, size, &defaultChar, &defUsed); numChars = WideCharToMultiByte(codePage, 0, (LPCWSTR)s, len, (char *)buf->data, size, &defaultChar, &defUsed);
if (numChars == 0 || numChars >= size) if (numChars == 0 || numChars >= size)
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
buf->data[numChars] = 0; buf->data[numChars] = 0;
@@ -148,7 +202,7 @@ static WRes MyCreateDir(const UInt16 *name)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
return CreateDirectoryW(name, NULL) ? 0 : GetLastError(); return CreateDirectoryW((LPCWSTR)name, NULL) ? 0 : GetLastError();
#else #else
@@ -173,7 +227,7 @@ static WRes MyCreateDir(const UInt16 *name)
static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name) static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
{ {
#ifdef USE_WINDOWS_FILE #ifdef USE_WINDOWS_FILE
return OutFile_OpenW(p, name); return OutFile_OpenW(p, (LPCWSTR)name);
#else #else
CBuf buf; CBuf buf;
WRes res; WRes res;
@@ -185,23 +239,24 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
#endif #endif
} }
static SRes PrintString(const UInt16 *s) 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 res = Utf16_To_Char(&buf, s
#ifdef _WIN32 #ifndef _USE_UTF8
, CP_OEMCP , CP_OEMCP
#endif #endif
); );
if (res == SZ_OK) if (res == SZ_OK)
fputs((const char *)buf.data, stdout); Print((const char *)buf.data);
Buf_Free(&buf, &g_Alloc); Buf_Free(&buf, &g_Alloc);
return res; return res;
} }
static void UInt64ToStr(UInt64 value, char *s) static void UInt64ToStr(UInt64 value, char *s, int numDigits)
{ {
char temp[32]; char temp[32];
int pos = 0; int pos = 0;
@@ -211,6 +266,10 @@ static void UInt64ToStr(UInt64 value, char *s)
value /= 10; value /= 10;
} }
while (value != 0); while (value != 0);
for (numDigits -= pos; numDigits > 0; numDigits--)
*s++ = ' ';
do do
*s++ = temp[--pos]; *s++ = temp[--pos];
while (pos); while (pos);
@@ -224,8 +283,10 @@ static char *UIntToStr(char *s, unsigned value, int numDigits)
do do
temp[pos++] = (char)('0' + (value % 10)); temp[pos++] = (char)('0' + (value % 10));
while (value /= 10); while (value /= 10);
for (numDigits -= pos; numDigits > 0; numDigits--) for (numDigits -= pos; numDigits > 0; numDigits--)
*s++ = '0'; *s++ = '0';
do do
*s++ = temp[--pos]; *s++ = temp[--pos];
while (pos); while (pos);
@@ -268,10 +329,10 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
ms[1] = 29; ms[1] = 29;
for (mon = 0;; mon++) for (mon = 0;; mon++)
{ {
unsigned s = ms[mon]; unsigned d = ms[mon];
if (v < s) if (v < d)
break; break;
v -= s; v -= d;
} }
s = UIntToStr(s, year, 4); *s++ = '-'; s = UIntToStr(s, year, 4); *s++ = '-';
UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3; UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
@@ -281,46 +342,54 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
UIntToStr_2(s, sec); s[2] = 0; UIntToStr_2(s, sec); s[2] = 0;
} }
void PrintError(const char *sz) static void PrintLF()
{ {
printf("\nERROR: %s\n", sz); Print("\n");
} }
#ifdef USE_WINDOWS_FILE static void PrintError(char *s)
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
{ {
Print("\nERROR: ");
Print(s);
PrintLF();
}
static void GetAttribString(UInt32 wa, BoolInt isDir, char *s)
{
#ifdef USE_WINDOWS_FILE
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.'); s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.'); s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.'); s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.'); s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.'); s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
s[5] = '\0'; 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)
{
s[0] = '\0';
}
#endif
// #define NUM_PARENTS_MAX 128 // #define NUM_PARENTS_MAX 128
int MY_CDECL main(int numargs, char *args[]) int MY_CDECL main(int numargs, char *args[])
{ {
CFileInStream archiveStream;
CLookToRead lookStream;
CSzArEx db;
SRes res;
ISzAlloc allocImp; ISzAlloc allocImp;
ISzAlloc allocTempImp; ISzAlloc allocTempImp;
CFileInStream archiveStream;
CLookToRead2 lookStream;
CSzArEx db;
SRes res;
UInt16 *temp = NULL; UInt16 *temp = NULL;
size_t tempSize = 0; size_t tempSize = 0;
// UInt32 parents[NUM_PARENTS_MAX]; // UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n");
if (numargs == 1) if (numargs == 1)
{ {
printf( Print(
"Usage: 7zDec <command> <archive_name>\n\n" "Usage: 7zDec <command> <archive_name>\n\n"
"<Commands>\n" "<Commands>\n"
" e: Extract files from archive (without using directory names)\n" " e: Extract files from archive (without using directory names)\n"
@@ -329,6 +398,7 @@ 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");
@@ -339,11 +409,9 @@ int MY_CDECL main(int numargs, char *args[])
g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif #endif
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp; allocImp = g_Alloc;
allocTempImp.Free = SzFreeTemp; allocTempImp = g_Alloc;
#ifdef UNDER_CE #ifdef UNDER_CE
if (InFile_OpenW(&archiveStream.file, L"\test.7z")) if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
@@ -356,19 +424,37 @@ int MY_CDECL main(int numargs, char *args[])
} }
FileInStream_CreateVTable(&archiveStream); FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False); LookToRead2_CreateVTable(&lookStream, False);
lookStream.buf = NULL;
lookStream.realStream = &archiveStream.s; res = SZ_OK;
LookToRead_Init(&lookStream);
{
lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize);
if (!lookStream.buf)
res = SZ_ERROR_MEM;
else
{
lookStream.bufSize = kInputBufSize;
lookStream.realStream = &archiveStream.vt;
LookToRead2_Init(&lookStream);
}
}
CrcGenerateTable(); CrcGenerateTable();
SzArEx_Init(&db); SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if (res == SZ_OK)
{
res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
}
if (res == SZ_OK) if (res == SZ_OK)
{ {
char *command = args[1]; char *command = args[1];
int listCommand = 0, testCommand = 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) { } else if (strcmp(command, "e") == 0) { }
@@ -397,7 +483,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t outSizeProcessed = 0; size_t outSizeProcessed = 0;
// const CSzFileItem *f = db.Files + i; // const CSzFileItem *f = db.Files + i;
size_t len; size_t len;
int isDir = SzArEx_IsDir(&db, i); unsigned isDir = SzArEx_IsDir(&db, i);
if (listCommand == 0 && isDir && !fullPaths) if (listCommand == 0 && isDir && !fullPaths)
continue; continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL); len = SzArEx_GetFileNameUtf16(&db, i, NULL);
@@ -432,7 +518,8 @@ int MY_CDECL main(int numargs, char *args[])
GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr); GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
fileSize = SzArEx_GetFileSize(&db, i); fileSize = SzArEx_GetFileSize(&db, i);
UInt64ToStr(fileSize, s); UInt64ToStr(fileSize, s, 10);
if (SzBitWithVals_Check(&db.MTime, i)) if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t); ConvertFileTimeToString(&db.MTime.Vals[i], t);
else else
@@ -443,33 +530,40 @@ int MY_CDECL main(int numargs, char *args[])
t[j] = '\0'; t[j] = '\0';
} }
printf("%s %s %10s ", t, attr, s); Print(t);
Print(" ");
Print(attr);
Print(" ");
Print(s);
Print(" ");
res = PrintString(temp); res = PrintString(temp);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (isDir) if (isDir)
printf("/"); Print("/");
printf("\n"); PrintLF();
continue; continue;
} }
fputs(testCommand ?
Print(testCommand ?
"Testing ": "Testing ":
"Extracting ", "Extracting ");
stdout);
res = PrintString(temp); res = PrintString(temp);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (isDir) if (isDir)
printf("/"); Print("/");
else else
{ {
res = SzArEx_Extract(&db, &lookStream.s, i, res = SzArEx_Extract(&db, &lookStream.vt, i,
&blockIndex, &outBuffer, &outBufferSize, &blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed, &offset, &outSizeProcessed,
&allocImp, &allocTempImp); &allocImp, &allocTempImp);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
} }
if (!testCommand) if (!testCommand)
{ {
CSzFile outFile; CSzFile outFile;
@@ -477,6 +571,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] == '/')
{ {
@@ -493,7 +588,7 @@ int MY_CDECL main(int numargs, char *args[])
if (isDir) if (isDir)
{ {
MyCreateDir(destPath); MyCreateDir(destPath);
printf("\n"); PrintLF();
continue; continue;
} }
else if (OutFile_OpenUtf16(&outFile, destPath)) else if (OutFile_OpenUtf16(&outFile, destPath))
@@ -502,38 +597,78 @@ 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;
} }
#ifdef USE_WINDOWS_FILE
{
FILETIME mtime, ctime;
FILETIME *mtimePtr = NULL;
FILETIME *ctimePtr = NULL;
if (SzBitWithVals_Check(&db.MTime, i))
{
const CNtfsFileTime *t = &db.MTime.Vals[i];
mtime.dwLowDateTime = (DWORD)(t->Low);
mtime.dwHighDateTime = (DWORD)(t->High);
mtimePtr = &mtime;
}
if (SzBitWithVals_Check(&db.CTime, i))
{
const CNtfsFileTime *t = &db.CTime.Vals[i];
ctime.dwLowDateTime = (DWORD)(t->Low);
ctime.dwHighDateTime = (DWORD)(t->High);
ctimePtr = &ctime;
}
if (mtimePtr || ctimePtr)
SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr);
}
#endif
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 (SzBitWithVals_Check(&db.Attribs, i)) if (SzBitWithVals_Check(&db.Attribs, i))
SetFileAttributesW(destPath, db.Attribs.Vals[i]); {
UInt32 attrib = db.Attribs.Vals[i];
/* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker.
We remove posix bits, if we detect posix mode field */
if ((attrib & 0xF0000000) != 0)
attrib &= 0x7FFF;
SetFileAttributesW((LPCWSTR)destPath, attrib);
}
#endif #endif
} }
printf("\n"); PrintLF();
} }
IAlloc_Free(&allocImp, outBuffer); ISzAlloc_Free(&allocImp, outBuffer);
} }
} }
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp); SzFree(NULL, temp);
SzArEx_Free(&db, &allocImp);
ISzAlloc_Free(&allocImp, lookStream.buf);
File_Close(&archiveStream.file); File_Close(&archiveStream.file);
if (res == SZ_OK) if (res == SZ_OK)
{ {
printf("\nEverything is Ok\n"); Print("\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)
@@ -541,6 +676,11 @@ int MY_CDECL main(int numargs, char *args[])
else if (res == SZ_ERROR_CRC) else if (res == SZ_ERROR_CRC)
PrintError("CRC error"); PrintError("CRC error");
else else
printf("\nERROR #%d\n", res); {
char s[32];
UInt64ToStr(res, s, 0);
PrintError(s);
}
return 1; return 1;
} }

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
@@ -15,7 +14,9 @@ C_OBJS = \
$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 \

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 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.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)
@@ -38,6 +38,9 @@ $(PROG): $(OBJS)
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
@@ -67,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
clean: clean:
-$(RM) $(PROG) $(OBJS) -$(RM) $(PROG) $(OBJS)

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,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,42 @@
PROG = 7zipInstall.exe
MY_FIXED = 1
!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\DllSecur.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)

View File

@@ -0,0 +1,9 @@
#define IDD_INSTALL 100
#define IDT_EXTRACT_EXTRACT_TO 110
#define IDE_EXTRACT_PATH 111
#define IDB_EXTRACT_SET_PATH 112
#define IDT_CUR_FILE 113
#define IDC_PROGRESS 114
#define IDI_ICON 1

View File

@@ -0,0 +1,47 @@
#include <winnt.h>
#include <WinUser.h>
#include <CommCtrl.h>
#define USE_COPYRIGHT_CR
#include "../../7zVersion.rc"
#include "resource.h"
MY_VERSION_INFO(MY_VFT_APP, "7-Zip Installer", "7zipInstall", "7zipInstall.exe")
1 ICON "7zip.ico"
#define xc 184
#define yc 96
#define m 8
#define bxs 64
#define bys 16
#define bxsDots 20
#define xs (xc + m + m)
#define ys (yc + m + m)
#define bx1 (xs - m - bxs)
#define bx2 (bx1 - m - bxs)
#define by (ys - m - bys)
IDD_INSTALL DIALOG 0, 0, xs, ys
STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Install 7-Zip"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Destination folder:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8
EDITTEXT IDE_EXTRACT_PATH, m, 21, xc - bxsDots - 12, 14, ES_AUTOHSCROLL
PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, 20, bxsDots, bys, WS_GROUP
LTEXT "", IDT_CUR_FILE, m, 50, xc, 8
CONTROL "", IDC_PROGRESS, "msctls_progress32", WS_BORDER, m, 64, xc, 10
DEFPUSHBUTTON "&Install", IDOK, bx2, by, bxs, bys, WS_GROUP
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
END
#ifndef UNDER_CE
1 24 MOVEABLE PURE "7zipInstall.manifest"
#endif

View File

File diff suppressed because it is too large Load Diff

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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.Uninstall" type="win32"/>
<description>7-Zip Uninstaller</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,18 @@
PROG = 7zipUninstall.exe
MY_FIXED = 1
!IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
!ENDIF
MAIN_OBJS = \
$O\7zipUninstall.obj \
OBJS = \
$(MAIN_OBJS) \
$O\resource.res
!include "../../../CPP/Build.mak"
$(MAIN_OBJS): $(*B).c
$(COMPL_O1)

View File

@@ -0,0 +1,9 @@
#define IDD_INSTALL 100
#define IDT_EXTRACT_EXTRACT_TO 110
#define IDE_EXTRACT_PATH 111
#define IDT_CUR_FILE 113
#define IDC_PROGRESS 114
#define IDI_ICON 1

View File

@@ -0,0 +1,47 @@
#include <winnt.h>
#include <WinUser.h>
#include <CommCtrl.h>
#define USE_COPYRIGHT_CR
#include "../../7zVersion.rc"
#include "resource.h"
MY_VERSION_INFO(MY_VFT_APP, "7-Zip Uninstaller", "Uninstall", "Uninstall.exe")
1 ICON "7zipUninstall.ico"
#define xc 184
#define yc 96
#define m 8
#define bxs 64
#define bys 16
#define xs (xc + m + m)
#define ys (yc + m + m)
#define bx1 (xs - m - bxs)
#define bx2 (bx1 - m - bxs)
#define by (ys - m - bys)
IDD_INSTALL DIALOG 0, 0, xs, ys
STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Uninstall 7-Zip"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Uninstall from:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8
EDITTEXT IDE_EXTRACT_PATH, m, 21, xc, 14, ES_AUTOHSCROLL | WS_DISABLED
LTEXT "", IDT_CUR_FILE, m, 50, xc, 8
CONTROL "", IDC_PROGRESS, "msctls_progress32", WS_BORDER, m, 64, xc, 10
DEFPUSHBUTTON "&Uninstall", IDOK, bx2, by, bxs, bys, WS_GROUP
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
END
#ifndef UNDER_CE
1 24 MOVEABLE PURE "7zipUninstall.manifest"
#endif

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression /* LzmaUtil.c -- Test application for LZMA compression
2014-12-31 : Igor Pavlov : Public domain */ 2018-07-04 : Igor Pavlov : Public domain */
#include "../../Precomp.h" #include "../../Precomp.h"
@@ -7,30 +7,29 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../../CpuArch.h"
#include "../../Alloc.h" #include "../../Alloc.h"
#include "../../7zFile.h" #include "../../7zFile.h"
#include "../../7zVersion.h" #include "../../7zVersion.h"
#include "../../LzmaDec.h" #include "../../LzmaDec.h"
#include "../../LzmaEnc.h" #include "../../LzmaEnc.h"
const char *kCantReadMessage = "Can not read input file"; static const char * const kCantReadMessage = "Can not read input file";
const char *kCantWriteMessage = "Can not write output file"; static const char * const kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory"; static const char * const kCantAllocateMessage = "Can not allocate memory";
const char *kDataErrorMessage = "Data error"; static const char * const kDataErrorMessage = "Data error";
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void PrintHelp(char *buffer)
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
void PrintHelp(char *buffer)
{ {
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n" strcat(buffer,
"\nUsage: lzma <e|d> inputFile outputFile\n" "\nLZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"
" e: encode file\n" "Usage: lzma <e|d> inputFile outputFile\n"
" d: decode file\n"); " e: encode file\n"
" d: decode file\n");
} }
int PrintError(char *buffer, const char *message) static int PrintError(char *buffer, const char *message)
{ {
strcat(buffer, "\nError: "); strcat(buffer, "\nError: ");
strcat(buffer, message); strcat(buffer, message);
@@ -38,20 +37,22 @@ int PrintError(char *buffer, const char *message)
return 1; return 1;
} }
int PrintErrorNumber(char *buffer, SRes val) static int PrintErrorNumber(char *buffer, SRes val)
{ {
sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val); sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
return 1; return 1;
} }
int PrintUserError(char *buffer) static int PrintUserError(char *buffer)
{ {
return PrintError(buffer, "Incorrect command"); return PrintError(buffer, "Incorrect command");
} }
#define IN_BUF_SIZE (1 << 16) #define IN_BUF_SIZE (1 << 16)
#define OUT_BUF_SIZE (1 << 16) #define OUT_BUF_SIZE (1 << 16)
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
UInt64 unpackSize) UInt64 unpackSize)
{ {
@@ -105,6 +106,7 @@ static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inS
} }
} }
static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream) static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)
{ {
UInt64 unpackSize; UInt64 unpackSize;
@@ -137,7 +139,7 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
SRes res; SRes res;
CLzmaEncProps props; CLzmaEncProps props;
rs = rs; UNUSED_VAR(rs);
enc = LzmaEnc_Create(&g_Alloc); enc = LzmaEnc_Create(&g_Alloc);
if (enc == 0) if (enc == 0)
@@ -167,14 +169,15 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
return res; return res;
} }
int main2(int numArgs, const char *args[], char *rs)
static int main2(int numArgs, const char *args[], char *rs)
{ {
CFileSeqInStream inStream; CFileSeqInStream inStream;
CFileOutStream outStream; CFileOutStream outStream;
char c; char c;
int res; int res;
int encodeMode; int encodeMode;
Bool useOutFile = False; BoolInt useOutFile = False;
FileSeqInStream_CreateVTable(&inStream); FileSeqInStream_CreateVTable(&inStream);
File_Construct(&inStream.file); File_Construct(&inStream.file);
@@ -219,11 +222,11 @@ int main2(int numArgs, const char *args[], char *rs)
{ {
UInt64 fileSize; UInt64 fileSize;
File_GetLength(&inStream.file, &fileSize); File_GetLength(&inStream.file, &fileSize);
res = Encode(&outStream.s, &inStream.s, fileSize, rs); res = Encode(&outStream.vt, &inStream.vt, fileSize, rs);
} }
else else
{ {
res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL); res = Decode(&outStream.vt, useOutFile ? &inStream.vt : NULL);
} }
if (useOutFile) if (useOutFile)
@@ -245,6 +248,7 @@ int main2(int numArgs, const char *args[], char *rs)
return 0; return 0;
} }
int MY_CDECL main(int numArgs, const char *args[]) int MY_CDECL main(int numArgs, const char *args[])
{ {
char rs[800] = { 0 }; char rs[800] = { 0 };

View File

@@ -1,168 +0,0 @@
# Microsoft Developer Studio Project File - Name="LzmaUtil" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=LzmaUtil - 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 "LzmaUtil.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 "LzmaUtil.mak" CFG="LzmaUtil - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "LzmaUtil - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "LzmaUtil - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "LzmaUtil - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W4 /WX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib 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\7lzma.exe"
!ELSEIF "$(CFG)" == "LzmaUtil - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /WX /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib 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\7lzma.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "LzmaUtil - Win32 Release"
# Name "LzmaUtil - Win32 Debug"
# 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=..\..\7zVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\Alloc.c
# End Source File
# Begin Source File
SOURCE=..\..\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\LzFind.c
# End Source File
# Begin Source File
SOURCE=..\..\LzFind.h
# End Source File
# Begin Source File
SOURCE=..\..\LzFindMt.c
# End Source File
# Begin Source File
SOURCE=..\..\LzFindMt.h
# End Source File
# Begin Source File
SOURCE=..\..\LzHash.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaEnc.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaEnc.h
# End Source File
# Begin Source File
SOURCE=.\LzmaUtil.c
# End Source File
# Begin Source File
SOURCE=..\..\Threads.c
# End Source File
# Begin Source File
SOURCE=..\..\Threads.h
# End Source File
# Begin Source File
SOURCE=..\..\Types.h
# End Source File
# End Target
# End Project

View File

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

View File

@@ -1,178 +0,0 @@
# Microsoft Developer Studio Project File - Name="LzmaLib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=LzmaLib - 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 "LzmaLib.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 "LzmaLib.mak" CFG="LzmaLib - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "LzmaLib - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "LzmaLib - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "LzmaLib - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /c
# ADD CPP /nologo /Gr /MT /W3 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /FD /c
# SUBTRACT CPP /YX
# 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 /dll /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 /dll /machine:I386 /out:"C:\Util\LZMA.dll" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "LzmaLib - 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 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LZMALIB_EXPORTS" /D "COMPRESS_MF_MT" /FD /GZ /c
# SUBTRACT CPP /YX
# 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 /dll /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 /dll /debug /machine:I386 /out:"C:\Util\LZMA.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "LzmaLib - Win32 Release"
# Name "LzmaLib - Win32 Debug"
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\LzmaLib.def
# End Source File
# Begin Source File
SOURCE=.\LzmaLibExports.c
# End Source File
# End Group
# Begin Source File
SOURCE=..\..\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\Alloc.c
# End Source File
# Begin Source File
SOURCE=..\..\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\IStream.h
# End Source File
# Begin Source File
SOURCE=..\..\LzFind.c
# End Source File
# Begin Source File
SOURCE=..\..\LzFind.h
# End Source File
# Begin Source File
SOURCE=..\..\LzFindMt.c
# End Source File
# Begin Source File
SOURCE=..\..\LzFindMt.h
# End Source File
# Begin Source File
SOURCE=..\..\LzHash.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaEnc.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaEnc.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaLib.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaLib.h
# End Source File
# Begin Source File
SOURCE=.\resource.rc
# End Source File
# Begin Source File
SOURCE=..\..\Threads.c
# End Source File
# Begin Source File
SOURCE=..\..\Threads.h
# End Source File
# End Target
# End Project

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