aboutsummaryrefslogtreecommitdiff
path: root/C
diff options
context:
space:
mode:
authorTetsuo Osaka <tetsugit@gmail.com>2016-10-18 15:12:28 +0200
committerTetsuo Osaka <tetsugit@gmail.com>2017-04-18 10:07:58 +0200
commitf955a79a9fffb09826cf7547f70d08c3798a2f50 (patch)
tree7ba3acdf7ba22cb749ffd9e6a868630e5a8382f2 /C
parent462f68aa279e25fda265a87c6d3c4da3318314f8 (diff)
downloadlzma-f955a79a9fffb09826cf7547f70d08c3798a2f50.tar.gz
Rebase LZMA SDK on 16.04 stable
This was downloaded from http://www.7-zip.org/a/lzma1604.7z The bin folder was excluded like in previous updates All files were deleted and replaced with those from the SDK. The embedded projects Tukaani, xz-embedded and android build files where not touched. The changelog since the 9.38 beta is: 16.04 2016-10-04 ------------------------- - The bug was fixed in DllSecur.c. 16.03 2016-09-28 ------------------------- - SFX modules now use some protection against DLL preloading attack. - Some bugs in 7z code were fixed. 16.02 2016-05-21 ------------------------- - The BUG in 16.00 - 16.01 was fixed: Split Handler (SplitHandler.cpp) returned incorrect total size value (kpidSize) for split archives. 16.01 2016-05-19 ------------------------- - Some internal changes to reduce the number of compiler warnings. 16.00 2016-05-10 ------------------------- - Some bugs were fixed. 15.12 2015-11-19 ------------------------- - The BUG in C version of 7z decoder was fixed: 7zDec.c : SzDecodeLzma2() 7z decoder could mistakenly report about decoding error for some 7z archives that use LZMA2 compression method. The probability to get that mistaken decoding error report was about one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size). - The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: 7zArcIn.c : SzReadHeader2() 7z decoder worked incorrectly for 7z archives that contain empty solid blocks, that can be placed to 7z archive, if some file is unavailable for reading during archive creation. 15.09 beta 2015-10-16 ------------------------- - The BUG in LZMA / LZMA2 encoding code was fixed. The BUG in LzFind.c::MatchFinder_ReadBlock() function. If input data size is larger than (4 GiB - dictionary_size), the following code worked incorrectly: - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions for compressing from memory to memory. That BUG is not related to LZMA encoder version that works via streams. - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if default value of chunk size (CLzma2EncProps::blockSize) is changed to value larger than (4 GiB - dictionary_size). Change-Id: I6b3974015c605fba3c0d4d897fab5a166174f441
Diffstat (limited to 'C')
-rw-r--r--C/7z.h98
-rw-r--r--C/7zAlloc.c14
-rw-r--r--C/7zAlloc.h10
-rw-r--r--C/7zArcIn.c882
-rw-r--r--C/7zBuf2.c9
-rw-r--r--C/7zCrc.c69
-rw-r--r--C/7zCrcOpt.c85
-rw-r--r--C/7zDec.c268
-rw-r--r--C/7zVersion.h25
-rw-r--r--C/Aes.c37
-rw-r--r--C/Alloc.c11
-rw-r--r--C/Alloc.h15
-rw-r--r--C/Android.bp7
-rw-r--r--C/Bcj2.c328
-rw-r--r--C/Bcj2.h148
-rw-r--r--C/Bcj2Enc.c312
-rw-r--r--C/Compiler.h8
-rw-r--r--C/CpuArch.c36
-rw-r--r--C/CpuArch.h140
-rw-r--r--C/DllSecur.c87
-rw-r--r--C/DllSecur.h19
-rw-r--r--C/LzFind.c497
-rw-r--r--C/LzFind.h28
-rw-r--r--C/LzFindMt.c181
-rw-r--r--C/LzFindMt.h4
-rw-r--r--C/LzHash.h43
-rw-r--r--C/Lzma2Dec.c48
-rw-r--r--C/Lzma2Dec.h4
-rw-r--r--C/Lzma2Enc.c59
-rw-r--r--C/Lzma86Dec.c8
-rw-r--r--C/Lzma86Enc.c8
-rw-r--r--C/LzmaDec.c197
-rw-r--r--C/LzmaEnc.c341
-rw-r--r--C/LzmaLib.c16
-rw-r--r--C/MtCoder.c6
-rw-r--r--C/Ppmd.h6
-rw-r--r--C/Ppmd7.c14
-rw-r--r--C/Ppmd7.h6
-rw-r--r--C/Ppmd7Enc.c4
-rw-r--r--C/RotateDefs.h10
-rw-r--r--C/Sha256.c168
-rw-r--r--C/Threads.c4
-rw-r--r--C/Util/7z/7z.dsp14
-rw-r--r--C/Util/7z/7zMain.c174
-rw-r--r--C/Util/7z/makefile3
-rw-r--r--C/Util/7z/makefile.gcc11
-rw-r--r--C/Util/Lzma/LzmaUtil.c8
-rw-r--r--C/Util/LzmaLib/LzmaLibExports.c10
-rw-r--r--C/Util/SfxSetup/SfxSetup.c43
-rw-r--r--C/Util/SfxSetup/SfxSetup.dsp20
-rw-r--r--C/Util/SfxSetup/makefile3
-rw-r--r--C/Util/SfxSetup/makefile_con3
-rw-r--r--C/Xz.c10
-rw-r--r--C/Xz.h14
-rw-r--r--C/XzCrc64.c24
-rw-r--r--C/XzCrc64Opt.c56
-rw-r--r--C/XzDec.c68
-rw-r--r--C/XzEnc.c86
-rw-r--r--C/XzIn.c68
59 files changed, 3213 insertions, 1662 deletions
diff --git a/C/7z.h b/C/7z.h
index dc25f53..216f381 100644
--- a/C/7z.h
+++ b/C/7z.h
@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface
-2013-01-18 : Igor Pavlov : Public domain */
+2015-11-18 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
@@ -11,7 +11,7 @@ EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
-extern Byte k7zSignature[k7zSignatureSize];
+extern const Byte k7zSignature[k7zSignatureSize];
typedef struct
{
@@ -25,8 +25,7 @@ typedef struct
{
size_t PropsOffset;
UInt32 MethodID;
- Byte NumInStreams;
- Byte NumOutStreams;
+ Byte NumStreams;
Byte PropsSize;
} CSzCoderInfo;
@@ -34,37 +33,25 @@ typedef struct
{
UInt32 InIndex;
UInt32 OutIndex;
-} CSzBindPair;
+} CSzBond;
#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_CODERS_OUT_STREAMS_IN_FOLDER_MAX 4
typedef struct
{
UInt32 NumCoders;
- UInt32 NumBindPairs;
+ UInt32 NumBonds;
UInt32 NumPackStreams;
- UInt32 MainOutStream;
+ UInt32 UnpackStream;
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];
- UInt64 CodersUnpackSizes[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
} 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
{
@@ -94,47 +81,25 @@ typedef struct
UInt32 NumPackStreams;
UInt32 NumFolders;
- UInt64 *PackPositions; // NumPackStreams + 1
- CSzBitUi32s FolderCRCs;
+ UInt64 *PackPositions; // NumPackStreams + 1
+ CSzBitUi32s FolderCRCs; // NumFolders
- size_t *FoCodersOffsets;
- size_t *FoSizesOffsets;
- // UInt32 StartCoderUnpackSizesIndex;
- UInt32 *FoStartPackStreamIndex;
+ size_t *FoCodersOffsets; // NumFolders + 1
+ UInt32 *FoStartPackStreamIndex; // NumFolders + 1
+ UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
+ Byte *FoToMainUnpackSizeIndex; // NumFolders
+ UInt64 *CoderUnpackSizes; // for all coders in all folders
- // CSzFolder2 *Folders; // +1 item for sum values
Byte *CodersData;
- Byte *UnpackSizesData;
- size_t UnpackSizesDataSize;
- // UInt64 *CoderUnpackSizes;
} CSzAr;
+UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain);
-/*
- SzExtract extracts file from archive
-
- *outBuffer must be 0 before first call for each new archive.
-
- Extracting cache:
- If you need to decompress more than one file, you can send
- these values from previous call:
- *blockIndex,
- *outBuffer,
- *outBufferSize
- You can consider "*outBuffer" as cache of solid block. If your archive is solid,
- it will increase decompression speed.
-
- If you use external function, you can declare these 3 cache variables
- (blockIndex, outBuffer, outBufferSize) as static in that external function.
-
- Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
-*/
-
typedef struct
{
CSzAr db;
@@ -144,7 +109,7 @@ typedef struct
UInt32 NumFiles;
- UInt64 *UnpackPositions;
+ UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles;
Byte *IsDirs;
CSzBitUi32s CRCs;
@@ -154,9 +119,8 @@ typedef struct
CSzBitUi64s MTime;
CSzBitUi64s CTime;
- // UInt32 *FolderStartPackStreamIndex;
- UInt32 *FolderStartFileIndex; // + 1
- UInt32 *FileIndexToFolderIndexMap;
+ UInt32 *FolderToFile; // NumFolders + 1
+ UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
@@ -184,6 +148,28 @@ 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.
+
+ Extracting cache:
+ If you need to decompress more than one file, you can send
+ these values from previous call:
+ *blockIndex,
+ *outBuffer,
+ *outBufferSize
+ You can consider "*outBuffer" as cache of solid block. If your archive is solid,
+ it will increase decompression speed.
+
+ If you use external function, you can declare these 3 cache variables
+ (blockIndex, outBuffer, outBufferSize) as static in that external function.
+
+ Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
+*/
+
SRes SzArEx_Extract(
const CSzArEx *db,
ILookInStream *inStream,
diff --git a/C/7zAlloc.c b/C/7zAlloc.c
index 698071c..360da05 100644
--- a/C/7zAlloc.c
+++ b/C/7zAlloc.c
@@ -1,5 +1,5 @@
/* 7zAlloc.c -- Allocation functions
-2010-10-29 : Igor Pavlov : Public domain */
+2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -22,11 +22,11 @@ int g_allocCountTemp = 0;
void *SzAlloc(void *p, size_t size)
{
- p = p;
+ UNUSED_VAR(p);
if (size == 0)
return 0;
#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++;
#endif
return malloc(size);
@@ -34,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
void SzFree(void *p, void *address)
{
- p = p;
+ UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
@@ -47,11 +47,11 @@ void SzFree(void *p, void *address)
void *SzAllocTemp(void *p, size_t size)
{
- p = p;
+ UNUSED_VAR(p);
if (size == 0)
return 0;
#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++;
#ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size);
@@ -62,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
void SzFreeTemp(void *p, void *address)
{
- p = p;
+ UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
diff --git a/C/7zAlloc.h b/C/7zAlloc.h
index 860f116..4d7502f 100644
--- a/C/7zAlloc.h
+++ b/C/7zAlloc.h
@@ -1,15 +1,23 @@
/* 7zAlloc.h -- Allocation functions
-2010-10-29 : Igor Pavlov : Public domain */
+2013-03-25 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stdlib.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/C/7zArcIn.c b/C/7zArcIn.c
index 5fd4f6b..c324c37 100644
--- a/C/7zArcIn.c
+++ b/C/7zArcIn.c
@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions
-2014-06-16 : Igor Pavlov : Public domain */
+2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -10,8 +10,16 @@
#include "7zCrc.h"
#include "CpuArch.h"
-#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
- if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
+#define MY_ALLOC(T, p, size, alloc) { \
+ if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
+
+#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
+
+#define MY_ALLOC_AND_CPY(to, size, from, alloc) \
+ { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }
+
+#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
+ { if ((size) == 0) p = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
#define k7zMajorVersion 0
@@ -48,75 +56,69 @@ enum EIdEnum
// k7zIsReal
};
-Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
-
-#define NUM_FOLDER_CODERS_MAX 32
-#define NUM_CODER_STREAMS_MAX 32
-
-/*
-static int SzFolder_FindBindPairForInStream(const CSzFolder *p, UInt32 inStreamIndex)
-{
- UInt32 i;
- for (i = 0; i < p->NumBindPairs; i++)
- if (p->BindPairs[i].InIndex == inStreamIndex)
- return i;
- return -1;
-}
-*/
+const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
-#define SzBitUi32s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
+#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
{
- MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
- MY_ALLOC(UInt32, p->Vals, num, alloc);
+ if (num == 0)
+ {
+ p->Defs = NULL;
+ p->Vals = NULL;
+ }
+ else
+ {
+ MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
+ MY_ALLOC(UInt32, p->Vals, num, alloc);
+ }
return SZ_OK;
}
void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
{
- IAlloc_Free(alloc, p->Defs); p->Defs = 0;
- IAlloc_Free(alloc, p->Vals); p->Vals = 0;
+ IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+ IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
}
-#define SzBitUi64s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
+#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
{
- IAlloc_Free(alloc, p->Defs); p->Defs = 0;
- IAlloc_Free(alloc, p->Vals); p->Vals = 0;
+ IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+ IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
}
+
static void SzAr_Init(CSzAr *p)
{
p->NumPackStreams = 0;
p->NumFolders = 0;
- p->PackPositions = 0;
+
+ p->PackPositions = NULL;
SzBitUi32s_Init(&p->FolderCRCs);
- // p->Folders = 0;
- p->FoCodersOffsets = 0;
- p->FoSizesOffsets = 0;
- p->FoStartPackStreamIndex = 0;
-
- p->CodersData = 0;
- // p->CoderUnpackSizes = 0;
- p->UnpackSizesData = 0;
+
+ p->FoCodersOffsets = NULL;
+ p->FoStartPackStreamIndex = NULL;
+ p->FoToCoderUnpackSizes = NULL;
+ p->FoToMainUnpackSizeIndex = NULL;
+ p->CoderUnpackSizes = NULL;
+
+ p->CodersData = NULL;
}
static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
{
- IAlloc_Free(alloc, p->UnpackSizesData);
- IAlloc_Free(alloc, p->CodersData);
- // IAlloc_Free(alloc, p->CoderUnpackSizes);
-
IAlloc_Free(alloc, p->PackPositions);
+ SzBitUi32s_Free(&p->FolderCRCs, alloc);
- // IAlloc_Free(alloc, p->Folders);
IAlloc_Free(alloc, p->FoCodersOffsets);
- IAlloc_Free(alloc, p->FoSizesOffsets);
IAlloc_Free(alloc, p->FoStartPackStreamIndex);
+ IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
+ IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
+ IAlloc_Free(alloc, p->CoderUnpackSizes);
- SzBitUi32s_Free(&p->FolderCRCs, alloc);
+ IAlloc_Free(alloc, p->CodersData);
SzAr_Init(p);
}
@@ -125,18 +127,19 @@ static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
void SzArEx_Init(CSzArEx *p)
{
SzAr_Init(&p->db);
+
p->NumFiles = 0;
p->dataPos = 0;
- // p->Files = 0;
- p->UnpackPositions = 0;
- // p->IsEmptyFiles = 0;
- p->IsDirs = 0;
- // p->FolderStartPackStreamIndex = 0;
- // p->PackStreamStartPositions = 0;
- p->FolderStartFileIndex = 0;
- p->FileIndexToFolderIndexMap = 0;
- p->FileNameOffsets = 0;
- p->FileNames = 0;
+
+ p->UnpackPositions = NULL;
+ p->IsDirs = NULL;
+
+ p->FolderToFile = NULL;
+ p->FileToFolder = NULL;
+
+ p->FileNameOffsets = NULL;
+ p->FileNames = NULL;
+
SzBitUi32s_Init(&p->CRCs);
SzBitUi32s_Init(&p->Attribs);
// SzBitUi32s_Init(&p->Parents);
@@ -146,47 +149,36 @@ void SzArEx_Init(CSzArEx *p)
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
{
- // IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
- // IAlloc_Free(alloc, p->PackStreamStartPositions);
- IAlloc_Free(alloc, p->FolderStartFileIndex);
- IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
+ IAlloc_Free(alloc, p->UnpackPositions);
+ IAlloc_Free(alloc, p->IsDirs);
+
+ IAlloc_Free(alloc, p->FolderToFile);
+ IAlloc_Free(alloc, p->FileToFolder);
IAlloc_Free(alloc, p->FileNameOffsets);
IAlloc_Free(alloc, p->FileNames);
- SzBitUi64s_Free(&p->CTime, alloc);
- SzBitUi64s_Free(&p->MTime, alloc);
SzBitUi32s_Free(&p->CRCs, alloc);
- // SzBitUi32s_Free(&p->Parents, alloc);
SzBitUi32s_Free(&p->Attribs, alloc);
- IAlloc_Free(alloc, p->IsDirs);
- // IAlloc_Free(alloc, p->IsEmptyFiles);
- IAlloc_Free(alloc, p->UnpackPositions);
- // IAlloc_Free(alloc, p->Files);
-
+ // SzBitUi32s_Free(&p->Parents, alloc);
+ SzBitUi64s_Free(&p->MTime, alloc);
+ SzBitUi64s_Free(&p->CTime, alloc);
+
SzAr_Free(&p->db, alloc);
SzArEx_Init(p);
}
-static int TestSignatureCandidate(Byte *testBytes)
+
+static int TestSignatureCandidate(const Byte *testBytes)
{
- size_t i;
+ unsigned i;
for (i = 0; i < k7zSignatureSize; i++)
if (testBytes[i] != k7zSignature[i])
return 0;
return 1;
}
-#define SzData_Clear(p) { (p)->Data = 0; (p)->Size = 0; }
-
-static SRes SzReadByte(CSzData *sd, Byte *b)
-{
- if (sd->Size == 0)
- return SZ_ERROR_ARCHIVE;
- sd->Size--;
- *b = *sd->Data++;
- return SZ_OK;
-}
+#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; }
#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;
#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)
@@ -224,7 +216,7 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
Byte b;
if ((firstByte & mask) == 0)
{
- UInt64 highPart = firstByte & (mask - 1);
+ UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);
*value |= (highPart << (8 * i));
return SZ_OK;
}
@@ -235,57 +227,6 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
return SZ_OK;
}
-/*
-static MY_NO_INLINE const Byte *SzReadNumbers(const Byte *data, const Byte *dataLim, UInt64 *values, UInt32 num)
-{
- for (; num != 0; num--)
- {
- Byte firstByte;
- Byte mask;
-
- unsigned i;
- UInt32 v;
- UInt64 value;
-
- if (data == dataLim)
- return NULL;
- firstByte = *data++;
-
- if ((firstByte & 0x80) == 0)
- {
- *values++ = firstByte;
- continue;
- }
- if (data == dataLim)
- return NULL;
- v = *data++;
- if ((firstByte & 0x40) == 0)
- {
- *values++ = (((UInt32)firstByte & 0x3F) << 8) | v;
- continue;
- }
- if (data == dataLim)
- return NULL;
- value = v | ((UInt32)*data++ << 8);
- mask = 0x20;
- for (i = 2; i < 8; i++)
- {
- if ((firstByte & mask) == 0)
- {
- UInt64 highPart = firstByte & (mask - 1);
- value |= (highPart << (8 * i));
- break;
- }
- if (data == dataLim)
- return NULL;
- value |= ((UInt64)*data++ << (8 * i));
- mask >>= 1;
- }
- *values++ = value;
- }
- return data;
-}
-*/
static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
{
@@ -322,7 +263,7 @@ static SRes SkipData(CSzData *sd)
return SZ_OK;
}
-static SRes WaitId(CSzData *sd, UInt64 id)
+static SRes WaitId(CSzData *sd, UInt32 id)
{
for (;;)
{
@@ -361,29 +302,29 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
m--;
sum += ((b >> m) & 1);
}
- return sum ;
+ return sum;
}
static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
{
Byte allAreDefined;
- UInt32 i;
Byte *v2;
UInt32 numBytes = (numItems + 7) >> 3;
- RINOK(SzReadByte(sd, &allAreDefined));
+ *v = NULL;
+ SZ_READ_BYTE(allAreDefined);
+ if (numBytes == 0)
+ return SZ_OK;
if (allAreDefined == 0)
{
if (numBytes > sd->Size)
return SZ_ERROR_ARCHIVE;
- MY_ALLOC(Byte, *v, numBytes, alloc);
- memcpy(*v, sd->Data, numBytes);
+ MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc);
SKIP_DATA(sd, numBytes);
return SZ_OK;
}
MY_ALLOC(Byte, *v, numBytes, alloc);
v2 = *v;
- for (i = 0; i < numBytes; i++)
- v2[i] = 0xFF;
+ memset(v2, 0xFF, (size_t)numBytes);
{
unsigned numBits = (unsigned)numItems & 7;
if (numBits != 0)
@@ -398,7 +339,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
CSzData sd;
UInt32 *vals;
const Byte *defs;
- MY_ALLOC(UInt32, crcs->Vals, numItems, alloc);
+ MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc);
sd = *sd2;
defs = crcs->Defs;
vals = crcs->Vals;
@@ -424,7 +365,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
{
Byte allAreDefined;
UInt32 numDefined = numItems;
- RINOK(SzReadByte(sd, &allAreDefined));
+ SZ_READ_BYTE(allAreDefined);
if (!allAreDefined)
{
size_t numBytes = (numItems + 7) >> 3;
@@ -486,19 +427,22 @@ static SRes SzReadSwitch(CSzData *sd)
}
*/
-#define SZ_NUM_IN_STREAMS_IN_FOLDER_MAX 16
+#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
-SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
+SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
{
- UInt32 numCoders, numBindPairs, numPackStreams, i;
- UInt32 numInStreams = 0, numOutStreams = 0;
+ UInt32 numCoders, i;
+ UInt32 numInStreams = 0;
const Byte *dataStart = sd->Data;
- Byte inStreamUsed[SZ_NUM_IN_STREAMS_IN_FOLDER_MAX];
+
+ f->NumCoders = 0;
+ f->NumBonds = 0;
+ f->NumPackStreams = 0;
+ f->UnpackStream = 0;
RINOK(SzReadNumber32(sd, &numCoders));
- if (numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
+ if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
- f->NumCoders = numCoders;
for (i = 0; i < numCoders; i++)
{
@@ -506,9 +450,11 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
CSzCoderInfo *coder = f->Coders + i;
unsigned idSize, j;
UInt64 id;
- RINOK(SzReadByte(sd, &mainByte));
+
+ SZ_READ_BYTE(mainByte);
if ((mainByte & 0xC0) != 0)
return SZ_ERROR_UNSUPPORTED;
+
idSize = (unsigned)(mainByte & 0xF);
if (idSize > sizeof(id))
return SZ_ERROR_UNSUPPORTED;
@@ -525,109 +471,131 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
return SZ_ERROR_UNSUPPORTED;
coder->MethodID = (UInt32)id;
- coder->NumInStreams = 1;
- coder->NumOutStreams = 1;
+ coder->NumStreams = 1;
coder->PropsOffset = 0;
coder->PropsSize = 0;
if ((mainByte & 0x10) != 0)
{
UInt32 numStreams;
+
RINOK(SzReadNumber32(sd, &numStreams));
- if (numStreams > NUM_CODER_STREAMS_MAX)
+ if (numStreams > k_NumCodersStreams_in_Folder_MAX)
return SZ_ERROR_UNSUPPORTED;
- coder->NumInStreams = (Byte)numStreams;
+ coder->NumStreams = (Byte)numStreams;
+
RINOK(SzReadNumber32(sd, &numStreams));
- if (numStreams > NUM_CODER_STREAMS_MAX)
+ if (numStreams != 1)
return SZ_ERROR_UNSUPPORTED;
- coder->NumOutStreams = (Byte)numStreams;
}
+
+ numInStreams += coder->NumStreams;
+
+ if (numInStreams > k_NumCodersStreams_in_Folder_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+
if ((mainByte & 0x20) != 0)
{
UInt32 propsSize = 0;
RINOK(SzReadNumber32(sd, &propsSize));
- if (propsSize >= 0x40)
- return SZ_ERROR_UNSUPPORTED;
if (propsSize > sd->Size)
return SZ_ERROR_ARCHIVE;
+ if (propsSize >= 0x80)
+ return SZ_ERROR_UNSUPPORTED;
coder->PropsOffset = sd->Data - dataStart;
coder->PropsSize = (Byte)propsSize;
sd->Data += (size_t)propsSize;
sd->Size -= (size_t)propsSize;
}
- numInStreams += coder->NumInStreams;
- numOutStreams += coder->NumOutStreams;
}
- if (numOutStreams == 0)
- return SZ_ERROR_UNSUPPORTED;
-
- f->NumBindPairs = numBindPairs = numOutStreams - 1;
- if (numInStreams < numBindPairs)
- return SZ_ERROR_ARCHIVE;
- if (numInStreams > SZ_NUM_IN_STREAMS_IN_FOLDER_MAX)
- return SZ_ERROR_UNSUPPORTED;
- f->MainOutStream = 0;
- f->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
- if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
- return SZ_ERROR_UNSUPPORTED;
- for (i = 0; i < numInStreams; i++)
- inStreamUsed[i] = False;
- if (numBindPairs != 0)
+ /*
+ if (numInStreams == 1 && numCoders == 1)
{
- Byte outStreamUsed[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
-
- if (numBindPairs > SZ_NUM_BINDS_IN_FOLDER_MAX)
+ f->NumPackStreams = 1;
+ f->PackStreams[0] = 0;
+ }
+ else
+ */
+ {
+ Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];
+ UInt32 numBonds, numPackStreams;
+
+ numBonds = numCoders - 1;
+ if (numInStreams < numBonds)
+ return SZ_ERROR_ARCHIVE;
+ if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
-
- for (i = 0; i < numOutStreams; i++)
- outStreamUsed[i] = False;
-
- for (i = 0; i < numBindPairs; i++)
+ f->NumBonds = numBonds;
+
+ numPackStreams = numInStreams - numBonds;
+ if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
+ return SZ_ERROR_UNSUPPORTED;
+ f->NumPackStreams = numPackStreams;
+
+ for (i = 0; i < numInStreams; i++)
+ streamUsed[i] = False;
+
+ if (numBonds != 0)
{
- CSzBindPair *bp = f->BindPairs + i;
- RINOK(SzReadNumber32(sd, &bp->InIndex));
- if (bp->InIndex >= numInStreams)
+ Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];
+
+ for (i = 0; i < numCoders; i++)
+ coderUsed[i] = False;
+
+ for (i = 0; i < numBonds; i++)
+ {
+ CSzBond *bp = f->Bonds + i;
+
+ RINOK(SzReadNumber32(sd, &bp->InIndex));
+ if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex])
+ return SZ_ERROR_ARCHIVE;
+ streamUsed[bp->InIndex] = True;
+
+ RINOK(SzReadNumber32(sd, &bp->OutIndex));
+ if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex])
+ return SZ_ERROR_ARCHIVE;
+ coderUsed[bp->OutIndex] = True;
+ }
+
+ for (i = 0; i < numCoders; i++)
+ if (!coderUsed[i])
+ {
+ f->UnpackStream = i;
+ break;
+ }
+
+ if (i == numCoders)
return SZ_ERROR_ARCHIVE;
- inStreamUsed[bp->InIndex] = True;
- RINOK(SzReadNumber32(sd, &bp->OutIndex));
- if (bp->OutIndex >= numInStreams)
+ }
+
+ if (numPackStreams == 1)
+ {
+ for (i = 0; i < numInStreams; i++)
+ if (!streamUsed[i])
+ break;
+ if (i == numInStreams)
return SZ_ERROR_ARCHIVE;
- outStreamUsed[bp->OutIndex] = True;
+ f->PackStreams[0] = i;
}
- for (i = 0; i < numOutStreams; i++)
- if (!outStreamUsed[i])
+ else
+ for (i = 0; i < numPackStreams; i++)
{
- f->MainOutStream = i;
- break;
+ UInt32 index;
+ RINOK(SzReadNumber32(sd, &index));
+ if (index >= numInStreams || streamUsed[index])
+ return SZ_ERROR_ARCHIVE;
+ streamUsed[index] = True;
+ f->PackStreams[i] = index;
}
- if (i == numOutStreams)
- return SZ_ERROR_ARCHIVE;
}
- if (numPackStreams == 1)
- {
- for (i = 0; i < numInStreams; i++)
- if (!inStreamUsed[i])
- break;
- if (i == numInStreams)
- return SZ_ERROR_ARCHIVE;
- f->PackStreams[0] = i;
- }
- else
- for (i = 0; i < numPackStreams; i++)
- {
- RINOK(SzReadNumber32(sd, f->PackStreams + i));
- }
+ f->NumCoders = numCoders;
- for (i = 0; i < numOutStreams; i++)
- {
- RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
- }
-
return SZ_OK;
}
+
static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
{
CSzData sd;
@@ -658,24 +626,27 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
return SZ_OK;
}
-#define k_InStreamUsed_MAX 64
-#define k_OutStreamUsed_MAX 64
+
+#define k_Scan_NumCoders_MAX 64
+#define k_Scan_NumCodersStreams_in_Folder_MAX 64
+
static SRes ReadUnpackInfo(CSzAr *p,
CSzData *sd2,
- UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
+ UInt32 numFoldersMax,
+ const CBuf *tempBufs, UInt32 numTempBufs,
ISzAlloc *alloc)
{
CSzData sd;
- Byte inStreamUsed[k_InStreamUsed_MAX];
- Byte outStreamUsed[k_OutStreamUsed_MAX];
+
UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
const Byte *startBufPtr;
Byte external;
RINOK(WaitId(sd2, k7zIdFolder));
+
RINOK(SzReadNumber32(sd2, &numFolders));
- if (p->NumFolders > numFoldersMax)
+ if (numFolders > numFoldersMax)
return SZ_ERROR_UNSUPPORTED;
p->NumFolders = numFolders;
@@ -685,7 +656,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
else
{
UInt32 index;
- SzReadNumber32(sd2, &index);
+ RINOK(SzReadNumber32(sd2, &index));
if (index >= numTempBufs)
return SZ_ERROR_ARCHIVE;
sd.Data = tempBufs[index].data;
@@ -693,8 +664,9 @@ static SRes ReadUnpackInfo(CSzAr *p,
}
MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);
- MY_ALLOC(size_t, p->FoSizesOffsets, (size_t)numFolders + 1, alloc);
MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);
+ MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc);
+ MY_ALLOC(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc);
startBufPtr = sd.Data;
@@ -703,18 +675,19 @@ static SRes ReadUnpackInfo(CSzAr *p,
for (fo = 0; fo < numFolders; fo++)
{
- UInt32 numCoders, ci, numInStreams = 0, numOutStreams = 0;
+ UInt32 numCoders, ci, numInStreams = 0;
p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
+
RINOK(SzReadNumber32(&sd, &numCoders));
- if (numCoders > NUM_FOLDER_CODERS_MAX)
+ if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
return SZ_ERROR_UNSUPPORTED;
for (ci = 0; ci < numCoders; ci++)
{
Byte mainByte;
unsigned idSize;
- UInt32 coderInStreams, coderOutStreams;
+ UInt32 coderInStreams;
SZ_READ_BYTE_2(mainByte);
if ((mainByte & 0xC0) != 0)
@@ -727,17 +700,18 @@ static SRes ReadUnpackInfo(CSzAr *p,
SKIP_DATA2(sd, idSize);
coderInStreams = 1;
- coderOutStreams = 1;
+
if ((mainByte & 0x10) != 0)
{
+ UInt32 coderOutStreams;
RINOK(SzReadNumber32(&sd, &coderInStreams));
RINOK(SzReadNumber32(&sd, &coderOutStreams));
- if (coderInStreams > NUM_CODER_STREAMS_MAX ||
- coderOutStreams > NUM_CODER_STREAMS_MAX)
+ if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1)
return SZ_ERROR_UNSUPPORTED;
}
+
numInStreams += coderInStreams;
- numOutStreams += coderOutStreams;
+
if ((mainByte & 0x20) != 0)
{
UInt32 propsSize;
@@ -751,75 +725,82 @@ static SRes ReadUnpackInfo(CSzAr *p,
{
UInt32 indexOfMainStream = 0;
UInt32 numPackStreams = 1;
- if (numOutStreams != 1 || numInStreams != 1)
+
+ if (numCoders != 1 || numInStreams != 1)
{
+ Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX];
+ Byte coderUsed[k_Scan_NumCoders_MAX];
+
UInt32 i;
- UInt32 numBindPairs = numOutStreams - 1;
- if (numOutStreams == 0 || numInStreams < numBindPairs)
+ UInt32 numBonds = numCoders - 1;
+ if (numInStreams < numBonds)
return SZ_ERROR_ARCHIVE;
- if (numInStreams > k_InStreamUsed_MAX ||
- numOutStreams > k_OutStreamUsed_MAX)
+ if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
return SZ_ERROR_UNSUPPORTED;
for (i = 0; i < numInStreams; i++)
- inStreamUsed[i] = False;
- for (i = 0; i < numOutStreams; i++)
- outStreamUsed[i] = False;
+ streamUsed[i] = False;
+ for (i = 0; i < numCoders; i++)
+ coderUsed[i] = False;
- for (i = 0; i < numBindPairs; i++)
+ for (i = 0; i < numBonds; i++)
{
UInt32 index;
+
RINOK(SzReadNumber32(&sd, &index));
- if (index >= numInStreams || inStreamUsed[index])
+ if (index >= numInStreams || streamUsed[index])
return SZ_ERROR_ARCHIVE;
- inStreamUsed[index] = True;
+ streamUsed[index] = True;
+
RINOK(SzReadNumber32(&sd, &index));
- if (index >= numInStreams || outStreamUsed[index])
+ if (index >= numCoders || coderUsed[index])
return SZ_ERROR_ARCHIVE;
- outStreamUsed[index] = True;
+ coderUsed[index] = True;
}
- numPackStreams = numInStreams - numBindPairs;
+ numPackStreams = numInStreams - numBonds;
if (numPackStreams != 1)
for (i = 0; i < numPackStreams; i++)
{
- UInt32 temp;
- RINOK(SzReadNumber32(&sd, &temp));
- if (temp >= numInStreams)
+ UInt32 index;
+ RINOK(SzReadNumber32(&sd, &index));
+ if (index >= numInStreams || streamUsed[index])
return SZ_ERROR_ARCHIVE;
+ streamUsed[index] = True;
}
- for (i = 0; i < numOutStreams; i++)
- if (!outStreamUsed[i])
+ for (i = 0; i < numCoders; i++)
+ if (!coderUsed[i])
{
indexOfMainStream = i;
break;
}
- if (i == numOutStreams)
+ if (i == numCoders)
return SZ_ERROR_ARCHIVE;
}
+
p->FoStartPackStreamIndex[fo] = packStreamIndex;
- p->FoSizesOffsets[fo] = (numOutStreams << 8) | indexOfMainStream;
- numCodersOutStreams += numOutStreams;
- if (numCodersOutStreams < numOutStreams)
- return SZ_ERROR_UNSUPPORTED;
- packStreamIndex += numPackStreams;
- if (packStreamIndex < numPackStreams)
+ p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
+ p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
+ numCodersOutStreams += numCoders;
+ if (numCodersOutStreams < numCoders)
return SZ_ERROR_UNSUPPORTED;
- if (packStreamIndex > p->NumPackStreams)
+ if (numPackStreams > p->NumPackStreams - packStreamIndex)
return SZ_ERROR_ARCHIVE;
+ packStreamIndex += numPackStreams;
}
}
+
+ p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
{
size_t dataSize = sd.Data - startBufPtr;
p->FoStartPackStreamIndex[fo] = packStreamIndex;
p->FoCodersOffsets[fo] = dataSize;
- MY_ALLOC(Byte, p->CodersData, dataSize, alloc);
- memcpy(p->CodersData, startBufPtr, dataSize);
+ MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc);
}
if (external != 0)
@@ -831,28 +812,13 @@ static SRes ReadUnpackInfo(CSzAr *p,
RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
- // MY_ALLOC(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
+ MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
{
- size_t dataSize = sd.Size;
- /*
UInt32 i;
for (i = 0; i < numCodersOutStreams; i++)
{
- RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
+ RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
}
- */
- RINOK(SkipNumbers(&sd, numCodersOutStreams));
- dataSize -= sd.Size;
- MY_ALLOC(Byte, p->UnpackSizesData, dataSize, alloc);
- memcpy(p->UnpackSizesData, sd.Data - dataSize, dataSize);
- p->UnpackSizesDataSize = dataSize;
- /*
- const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams);
- if (data == NULL)
- return SZ_ERROR_ARCHIVE;
- sd.Size = sd.Data + sd.Size - data;
- sd.Data = data;
- */
}
for (;;)
@@ -873,6 +839,13 @@ static SRes ReadUnpackInfo(CSzAr *p,
}
}
+
+UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
+{
+ return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]];
+}
+
+
typedef struct
{
UInt32 NumTotalSubStreams;
@@ -882,12 +855,10 @@ typedef struct
CSzData sdCRCs;
} CSubStreamInfo;
-#define SzUi32IndexMax (((UInt32)1 << 31) - 2)
static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
{
UInt64 type = 0;
- UInt32 i;
UInt32 numSubDigests = 0;
UInt32 numFolders = p->NumFolders;
UInt32 numUnpackStreams = numFolders;
@@ -898,6 +869,7 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
RINOK(ReadID(sd, &type));
if (type == k7zIdNumUnpackStream)
{
+ UInt32 i;
ssi->sdNumSubStreams.Data = sd->Data;
numUnpackStreams = 0;
numSubDigests = 0;
@@ -1009,7 +981,6 @@ static SRes SzReadAndDecodePackedStreams(
UInt64 dataStartPos;
UInt32 fo;
CSubStreamInfo ssi;
- CSzData sdCodersUnpSizes;
RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));
@@ -1017,49 +988,26 @@ static SRes SzReadAndDecodePackedStreams(
if (p->NumFolders == 0)
return SZ_ERROR_ARCHIVE;
- sdCodersUnpSizes.Data = p->UnpackSizesData;
- sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
for (fo = 0; fo < p->NumFolders; fo++)
Buf_Init(tempBufs + fo);
+
for (fo = 0; fo < p->NumFolders; fo++)
{
CBuf *tempBuf = tempBufs + fo;
- // folder = p->Folders;
- // unpackSize = SzAr_GetFolderUnpackSize(p, 0);
- UInt32 mix = (UInt32)p->FoSizesOffsets[fo];
- UInt32 mainIndex = mix & 0xFF;
- UInt32 numOutStreams = mix >> 8;
- UInt32 si;
- UInt64 unpackSize = 0;
- p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
- for (si = 0; si < numOutStreams; si++)
- {
- UInt64 curSize;
- RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
- if (si == mainIndex)
- {
- unpackSize = curSize;
- break;
- }
- }
- if (si == numOutStreams)
- return SZ_ERROR_FAIL;
+ UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo);
if ((size_t)unpackSize != unpackSize)
return SZ_ERROR_MEM;
if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM;
}
- p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
-
+
for (fo = 0; fo < p->NumFolders; fo++)
{
const CBuf *tempBuf = tempBufs + fo;
RINOK(LookInStream_SeekTo(inStream, dataStartPos));
RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));
- if (SzBitWithVals_Check(&p->FolderCRCs, fo))
- if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
- return SZ_ERROR_CRC;
}
+
return SZ_OK;
}
@@ -1069,6 +1017,8 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
*offsets++ = 0;
if (numFiles == 0)
return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
+ if (size < 2)
+ return SZ_ERROR_ARCHIVE;
if (data[size - 2] != 0 || data[size - 1] != 0)
return SZ_ERROR_ARCHIVE;
do
@@ -1100,20 +1050,23 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
CNtfsFileTime *vals;
Byte *defs;
Byte external;
+
RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
- RINOK(SzReadByte(sd2, &external));
+
+ SZ_READ_BYTE_SD(sd2, external);
if (external == 0)
sd = *sd2;
else
{
UInt32 index;
- SzReadNumber32(sd2, &index);
+ RINOK(SzReadNumber32(sd2, &index));
if (index >= numTempBufs)
return SZ_ERROR_ARCHIVE;
sd.Data = tempBufs[index].data;
sd.Size = tempBufs[index].size;
}
- MY_ALLOC(CNtfsFileTime, p->Vals, num, alloc);
+
+ MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc);
vals = p->Vals;
defs = p->Defs;
for (i = 0; i < num; i++)
@@ -1127,34 +1080,31 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
}
else
vals[i].High = vals[i].Low = 0;
+
if (external == 0)
*sd2 = sd;
+
return SZ_OK;
}
+
#define NUM_ADDITIONAL_STREAMS_MAX 8
+
static SRes SzReadHeader2(
CSzArEx *p, /* allocMain */
CSzData *sd,
- // Byte **emptyStreamVector, /* allocTemp */
- // Byte **emptyFileVector, /* allocTemp */
- // Byte **lwtVector, /* allocTemp */
ILookInStream *inStream,
- CBuf *tempBufs,
- UInt32 *numTempBufs,
+ CBuf *tempBufs, UInt32 *numTempBufs,
ISzAlloc *allocMain,
ISzAlloc *allocTemp
)
{
- UInt64 type;
- UInt32 numFiles = 0;
- UInt32 numEmptyStreams = 0;
- UInt32 i;
CSubStreamInfo ssi;
- const Byte *emptyStreams = 0;
- const Byte *emptyFiles = 0;
+{
+ UInt64 type;
+
SzData_Clear(&ssi.sdSizes);
SzData_Clear(&ssi.sdCRCs);
SzData_Clear(&ssi.sdNumSubStreams);
@@ -1168,31 +1118,28 @@ static SRes SzReadHeader2(
{
for (;;)
{
- UInt64 type;
- RINOK(ReadID(sd, &type));
- if (type == k7zIdEnd)
+ UInt64 type2;
+ RINOK(ReadID(sd, &type2));
+ if (type2 == k7zIdEnd)
break;
RINOK(SkipData(sd));
}
RINOK(ReadID(sd, &type));
}
- // if (type == k7zIdAdditionalStreamsInfo) return SZ_ERROR_UNSUPPORTED;
-
if (type == k7zIdAdditionalStreamsInfo)
{
CSzAr tempAr;
SRes res;
- UInt32 numTempFolders;
SzAr_Init(&tempAr);
res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
p->startPosAfterHeader, &tempAr, allocTemp);
- numTempFolders = tempAr.NumFolders;
+ *numTempBufs = tempAr.NumFolders;
SzAr_Free(&tempAr, allocTemp);
+
if (res != SZ_OK)
return res;
- *numTempBufs = numTempFolders;
RINOK(ReadID(sd, &type));
}
@@ -1206,11 +1153,18 @@ static SRes SzReadHeader2(
if (type == k7zIdEnd)
{
- // *sd2 = sd;
return SZ_OK;
}
+
if (type != k7zIdFilesInfo)
return SZ_ERROR_ARCHIVE;
+}
+
+{
+ UInt32 numFiles = 0;
+ UInt32 numEmptyStreams = 0;
+ const Byte *emptyStreams = NULL;
+ const Byte *emptyFiles = NULL;
RINOK(SzReadNumber32(sd, &numFiles));
p->NumFiles = numFiles;
@@ -1225,11 +1179,12 @@ static SRes SzReadHeader2(
RINOK(ReadNumber(sd, &size));
if (size > sd->Size)
return SZ_ERROR_ARCHIVE;
- if ((UInt64)(int)type != type)
+
+ if (type >= ((UInt32)1 << 8))
{
SKIP_DATA(sd, size);
}
- else switch((int)type)
+ else switch ((unsigned)type)
{
case k7zIdName:
{
@@ -1246,7 +1201,7 @@ static SRes SzReadHeader2(
else
{
UInt32 index;
- SzReadNumber32(sd, &index);
+ RINOK(SzReadNumber32(sd, &index));
if (index >= *numTempBufs)
return SZ_ERROR_ARCHIVE;
namesData = (tempBufs)[index].data;
@@ -1255,9 +1210,8 @@ static SRes SzReadHeader2(
if ((namesSize & 1) != 0)
return SZ_ERROR_ARCHIVE;
- MY_ALLOC(Byte, p->FileNames, namesSize, allocMain);
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
- memcpy(p->FileNames, namesData, namesSize);
+ MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain);
RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
if (external == 0)
{
@@ -1269,6 +1223,7 @@ static SRes SzReadHeader2(
{
RINOK(RememberBitVector(sd, numFiles, &emptyStreams));
numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
+ emptyFiles = NULL;
break;
}
case k7zIdEmptyFile:
@@ -1290,7 +1245,7 @@ static SRes SzReadHeader2(
else
{
UInt32 index;
- SzReadNumber32(sd, &index);
+ RINOK(SzReadNumber32(sd, &index));
if (index >= *numTempBufs)
return SZ_ERROR_ARCHIVE;
sdSwitch.Data = (tempBufs)[index].data;
@@ -1332,35 +1287,31 @@ static SRes SzReadHeader2(
}
{
+ UInt32 i;
UInt32 emptyFileIndex = 0;
-
UInt32 folderIndex = 0;
- UInt32 indexInFolder = 0;
+ UInt32 remSubStreams = 0;
+ UInt32 numSubStreams = 0;
UInt64 unpackPos = 0;
- const Byte *digestsDefs = 0;
- const Byte *digestsVals = 0;
+ const Byte *digestsDefs = NULL;
+ const Byte *digestsVals = NULL;
UInt32 digestsValsIndex = 0;
UInt32 digestIndex;
Byte allDigestsDefined = 0;
- UInt32 curNumSubStreams = (UInt32)(Int32)-1;
Byte isDirMask = 0;
Byte crcMask = 0;
Byte mask = 0x80;
- // size_t unpSizesOffset = 0;
- CSzData sdCodersUnpSizes;
- sdCodersUnpSizes.Data = p->db.UnpackSizesData;
- sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
- MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain);
- MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain);
+ MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain);
+ MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain);
MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
- MY_ALLOC(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
+ MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));
if (ssi.sdCRCs.Size != 0)
{
- RINOK(SzReadByte(&ssi.sdCRCs, &allDigestsDefined));
+ SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined);
if (allDigestsDefined)
digestsVals = ssi.sdCRCs.Data;
else
@@ -1372,6 +1323,7 @@ static SRes SzReadHeader2(
}
digestIndex = 0;
+
for (i = 0; i < numFiles; i++, mask >>= 1)
{
if (mask == 0)
@@ -1386,79 +1338,66 @@ static SRes SzReadHeader2(
p->UnpackPositions[i] = unpackPos;
p->CRCs.Vals[i] = 0;
- // p->CRCs.Defs[i] = 0;
- if (emptyStreams && SzBitArray_Check(emptyStreams , i))
+
+ if (emptyStreams && SzBitArray_Check(emptyStreams, i))
{
- if (!emptyFiles || !SzBitArray_Check(emptyFiles, emptyFileIndex))
+ if (emptyFiles)
+ {
+ if (!SzBitArray_Check(emptyFiles, emptyFileIndex))
+ isDirMask |= mask;
+ emptyFileIndex++;
+ }
+ else
isDirMask |= mask;
- emptyFileIndex++;
- if (indexInFolder == 0)
+ if (remSubStreams == 0)
{
- p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+ p->FileToFolder[i] = (UInt32)-1;
continue;
}
}
- if (indexInFolder == 0)
+
+ if (remSubStreams == 0)
{
- /*
- v3.13 incorrectly worked with empty folders
- v4.07: Loop for skipping empty folders
- */
for (;;)
{
if (folderIndex >= p->db.NumFolders)
return SZ_ERROR_ARCHIVE;
- p->FolderStartFileIndex[folderIndex] = i;
- if (curNumSubStreams == (UInt32)(Int32)-1);
+ p->FolderToFile[folderIndex] = i;
+ numSubStreams = 1;
+ if (ssi.sdNumSubStreams.Data)
{
- curNumSubStreams = 1;
- if (ssi.sdNumSubStreams.Data != 0)
- {
- RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &curNumSubStreams));
- }
+ RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
}
- if (curNumSubStreams != 0)
+ remSubStreams = numSubStreams;
+ if (numSubStreams != 0)
break;
- curNumSubStreams = (UInt32)(Int32)-1;
- folderIndex++; // check it
+ {
+ UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ unpackPos += folderUnpackSize;
+ if (unpackPos < folderUnpackSize)
+ return SZ_ERROR_ARCHIVE;
+ }
+
+ folderIndex++;
}
}
- p->FileIndexToFolderIndexMap[i] = folderIndex;
- if (emptyStreams && SzBitArray_Check(emptyStreams , i))
+
+ p->FileToFolder[i] = folderIndex;
+
+ if (emptyStreams && SzBitArray_Check(emptyStreams, i))
continue;
- indexInFolder++;
- if (indexInFolder >= curNumSubStreams)
+ if (--remSubStreams == 0)
{
- UInt64 folderUnpackSize = 0;
- UInt64 startFolderUnpackPos;
- {
- UInt32 mix = (UInt32)p->db.FoSizesOffsets[folderIndex];
- UInt32 mainIndex = mix & 0xFF;
- UInt32 numOutStreams = mix >> 8;
- UInt32 si;
- p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
- for (si = 0; si < numOutStreams; si++)
- {
- UInt64 curSize;
- RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
- if (si == mainIndex)
- {
- folderUnpackSize = curSize;
- break;
- }
- }
- if (si == numOutStreams)
- return SZ_ERROR_FAIL;
- }
-
- // UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
- startFolderUnpackPos = p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
+ UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]];
if (folderUnpackSize < unpackPos - startFolderUnpackPos)
return SZ_ERROR_ARCHIVE;
unpackPos = startFolderUnpackPos + folderUnpackSize;
+ if (unpackPos < folderUnpackSize)
+ return SZ_ERROR_ARCHIVE;
- if (curNumSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
+ if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
{
p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex];
crcMask |= mask;
@@ -1469,14 +1408,16 @@ static SRes SzReadHeader2(
digestsValsIndex++;
crcMask |= mask;
}
+
folderIndex++;
- indexInFolder = 0;
}
else
{
UInt64 v;
RINOK(ReadNumber(&ssi.sdSizes, &v));
unpackPos += v;
+ if (unpackPos < v)
+ return SZ_ERROR_ARCHIVE;
if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
{
p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
@@ -1485,30 +1426,55 @@ static SRes SzReadHeader2(
}
}
}
+
if (mask != 0x80)
{
UInt32 byteIndex = (i - 1) >> 3;
p->IsDirs[byteIndex] = isDirMask;
p->CRCs.Defs[byteIndex] = crcMask;
}
+
p->UnpackPositions[i] = unpackPos;
- p->FolderStartFileIndex[folderIndex] = i;
- p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
+
+ if (remSubStreams != 0)
+ return SZ_ERROR_ARCHIVE;
+
+ for (;;)
+ {
+ p->FolderToFile[folderIndex] = i;
+ if (folderIndex >= p->db.NumFolders)
+ break;
+ if (!ssi.sdNumSubStreams.Data)
+ return SZ_ERROR_ARCHIVE;
+ RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
+ if (numSubStreams != 0)
+ return SZ_ERROR_ARCHIVE;
+ /*
+ {
+ UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ unpackPos += folderUnpackSize;
+ if (unpackPos < folderUnpackSize)
+ return SZ_ERROR_ARCHIVE;
+ }
+ */
+ folderIndex++;
+ }
+
+ if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
+ return SZ_ERROR_ARCHIVE;
}
+}
return SZ_OK;
}
+
static SRes SzReadHeader(
CSzArEx *p,
CSzData *sd,
ILookInStream *inStream,
- ISzAlloc *allocMain
- ,ISzAlloc *allocTemp
- )
+ ISzAlloc *allocMain,
+ ISzAlloc *allocTemp)
{
- // Byte *emptyStreamVector = 0;
- // Byte *emptyFileVector = 0;
- // Byte *lwtVector = 0;
UInt32 i;
UInt32 numTempBufs = 0;
SRes res;
@@ -1516,54 +1482,21 @@ static SRes SzReadHeader(
for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
Buf_Init(tempBufs + i);
- // SzBitUi32s_Init(&digests);
- res = SzReadHeader2(p, sd,
- // &emptyStreamVector,
- // &emptyFileVector,
- // &lwtVector,
- inStream,
+ res = SzReadHeader2(p, sd, inStream,
tempBufs, &numTempBufs,
- allocMain, allocTemp
- );
+ allocMain, allocTemp);
- for (i = 0; i < numTempBufs; i++)
+ for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
Buf_Free(tempBufs + i, allocTemp);
- // IAlloc_Free(allocTemp, emptyStreamVector);
- // IAlloc_Free(allocTemp, emptyFileVector);
- // IAlloc_Free(allocTemp, lwtVector);
-
RINOK(res);
- {
- if (sd->Size != 0)
- return SZ_ERROR_FAIL;
- }
-
- return res;
-}
-/*
-static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
-{
- const CSzFolder2 *f = p->Folders + folderIndex;
+ if (sd->Size != 0)
+ return SZ_ERROR_FAIL;
- // return p->CoderUnpackSizes[f->StartCoderUnpackSizesIndex + f->IndexOfMainOutStream];
-
- UInt32 si;
- CSzData sdCodersUnpSizes;
- sdCodersUnpSizes.Data = p->UnpackSizesData + f->UnpackSizeDataOffset;
- sdCodersUnpSizes.Size = p->UnpackSizesDataSize - f->UnpackSizeDataOffset;
- for (si = 0; si < numOutStreams; si++)
- {
- UInt64 curSize;
- ReadNumber(&sdCodersUnpSizes, &curSize);
- if (si == mainIndex)
- return curSize;
- }
- return 0;
+ return res;
}
-*/
static SRes SzArEx_Open2(
CSzArEx *p,
@@ -1622,6 +1555,7 @@ static SRes SzArEx_Open2(
return SZ_ERROR_MEM;
res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);
+
if (res == SZ_OK)
{
res = SZ_ERROR_ARCHIVE;
@@ -1631,7 +1565,9 @@ static SRes SzArEx_Open2(
UInt64 type;
sd.Data = buf.data;
sd.Size = buf.size;
+
res = ReadID(&sd, &type);
+
if (res == SZ_OK && type == k7zIdEncodedHeader)
{
CSzAr tempAr;
@@ -1656,35 +1592,35 @@ static SRes SzArEx_Open2(
res = ReadID(&sd, &type);
}
}
+
if (res == SZ_OK)
{
if (type == k7zIdHeader)
{
+ /*
CSzData sd2;
- int ttt;
- for (ttt = 0; ttt < 1; ttt++)
- // for (ttt = 0; ttt < 40000; ttt++)
+ unsigned ttt;
+ for (ttt = 0; ttt < 40000; ttt++)
{
SzArEx_Free(p, allocMain);
sd2 = sd;
- res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp
- );
+ res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp);
if (res != SZ_OK)
break;
}
-
- // res = SzReadHeader(p, &sd, allocMain, allocTemp);
+ */
+ res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp);
}
else
res = SZ_ERROR_UNSUPPORTED;
}
}
}
+
Buf_Free(&buf, allocTemp);
return res;
}
-// #include <stdio.h>
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAlloc *allocMain, ISzAlloc *allocTemp)
@@ -1692,10 +1628,10 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
if (res != SZ_OK)
SzArEx_Free(p, allocMain);
- // printf ("\nrrr=%d\n", rrr);
return res;
}
+
SRes SzArEx_Extract(
const CSzArEx *p,
ILookInStream *inStream,
@@ -1708,34 +1644,36 @@ SRes SzArEx_Extract(
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
- UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
+ UInt32 folderIndex = p->FileToFolder[fileIndex];
SRes res = SZ_OK;
+
*offset = 0;
*outSizeProcessed = 0;
+
if (folderIndex == (UInt32)-1)
{
IAlloc_Free(allocMain, *tempBuf);
*blockIndex = folderIndex;
- *tempBuf = 0;
+ *tempBuf = NULL;
*outBufferSize = 0;
return SZ_OK;
}
- if (*tempBuf == 0 || *blockIndex != folderIndex)
+ if (*tempBuf == NULL || *blockIndex != folderIndex)
{
- // UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
+ /*
UInt64 unpackSizeSpec =
- p->UnpackPositions[p->FolderStartFileIndex[folderIndex + 1]] -
- p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
+ p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
+ p->UnpackPositions[p->FolderToFile[folderIndex]];
+ */
size_t unpackSize = (size_t)unpackSizeSpec;
if (unpackSize != unpackSizeSpec)
return SZ_ERROR_MEM;
*blockIndex = folderIndex;
IAlloc_Free(allocMain, *tempBuf);
- *tempBuf = 0;
-
- // RINOK(LookInStream_SeekTo(inStream, startOffset));
+ *tempBuf = NULL;
if (res == SZ_OK)
{
@@ -1743,36 +1681,30 @@ SRes SzArEx_Extract(
if (unpackSize != 0)
{
*tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
- if (*tempBuf == 0)
+ if (*tempBuf == NULL)
res = SZ_ERROR_MEM;
}
+
if (res == SZ_OK)
{
res = SzAr_DecodeFolder(&p->db, folderIndex,
- inStream,
- p->dataPos,
- *tempBuf, unpackSize, allocTemp);
- if (res == SZ_OK)
- {
- if (SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex))
- {
- if (CrcCalc(*tempBuf, unpackSize) != p->db.FolderCRCs.Vals[folderIndex])
- res = SZ_ERROR_CRC;
- }
- }
+ inStream, p->dataPos, *tempBuf, unpackSize, allocTemp);
}
}
}
+
if (res == SZ_OK)
{
UInt64 unpackPos = p->UnpackPositions[fileIndex];
- *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]);
+ *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
*outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
if (*offset + *outSizeProcessed > *outBufferSize)
return SZ_ERROR_FAIL;
- if (SzBitWithVals_Check(&p->CRCs, fileIndex) && CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
- res = SZ_ERROR_CRC;
+ if (SzBitWithVals_Check(&p->CRCs, fileIndex))
+ if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
+ res = SZ_ERROR_CRC;
}
+
return res;
}
diff --git a/C/7zBuf2.c b/C/7zBuf2.c
index 9633796..8e3fe92 100644
--- a/C/7zBuf2.c
+++ b/C/7zBuf2.c
@@ -1,5 +1,5 @@
/* 7zBuf2.c -- Byte Buffer
-2013-11-12 : Igor Pavlov : Public domain */
+2014-08-22 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -34,8 +34,11 @@ int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
alloc->Free(alloc, p->data);
p->data = data;
}
- memcpy(p->data + p->pos, buf, size);
- p->pos += size;
+ if (size != 0)
+ {
+ memcpy(p->data + p->pos, buf, size);
+ p->pos += size;
+ }
return 1;
}
diff --git a/C/7zCrc.c b/C/7zCrc.c
index 161d4d1..607db34 100644
--- a/C/7zCrc.c
+++ b/C/7zCrc.c
@@ -1,5 +1,5 @@
/* 7zCrc.c -- CRC32 init
-2013-11-12 : Igor Pavlov : Public domain */
+2015-03-10 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -8,24 +8,28 @@
#define kCrcPoly 0xEDB88320
-#ifdef MY_CPU_X86_OR_AMD64
+#ifdef MY_CPU_LE
#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
- #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))
+
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
#ifndef MY_CPU_BE
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
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;
+
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
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;
}
+#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()
{
UInt32 i;
@@ -54,22 +69,43 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
+
+ #if CRC_NUM_TABLES < 4
+ g_CrcUpdate = CrcUpdateT1;
+
+ #else
+
#ifdef MY_CPU_LE
- g_CrcUpdate = CrcUpdateT4;
+ g_CrcUpdateT4 = CrcUpdateT4;
+ g_CrcUpdate = CrcUpdateT4;
+
+ #if CRC_NUM_TABLES >= 8
+ g_CrcUpdateT8 = CrcUpdateT8;
- #if CRC_NUM_TABLES == 8
- if (!CPU_Is_InOrder())
- g_CrcUpdate = CrcUpdateT8;
- #endif
+ #ifdef MY_CPU_X86_OR_AMD64
+ if (!CPU_Is_InOrder())
+ g_CrcUpdate = CrcUpdateT8;
+ #endif
+ #endif
#else
{
#ifndef MY_CPU_BE
- UInt32 k = 1;
- if (*(const Byte *)&k == 1)
+ UInt32 k = 0x01020304;
+ const Byte *p = (const Byte *)&k;
+ if (p[0] == 4 && p[1] == 3)
+ {
+ g_CrcUpdateT4 = 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
#endif
{
@@ -78,8 +114,15 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 x = g_CrcTable[i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
+ g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4;
+ #if CRC_NUM_TABLES >= 8
+ g_CrcUpdateT8 = CrcUpdateT1_BeT8;
+ // g_CrcUpdate = CrcUpdateT1_BeT8;
+ #endif
}
}
#endif
+
+ #endif
}
diff --git a/C/7zCrcOpt.c b/C/7zCrcOpt.c
index 48b0136..58628ef 100644
--- a/C/7zCrcOpt.c
+++ b/C/7zCrcOpt.c
@@ -1,14 +1,14 @@
/* 7zCrcOpt.c -- CRC32 calculation
-2013-11-12 : Igor Pavlov : Public domain */
+2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
-#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
-
#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)
{
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 =
- table[0x300 + (v & 0xFF)] ^
- table[0x200 + ((v >> 8) & 0xFF)] ^
- table[0x100 + ((v >> 16) & 0xFF)] ^
- table[0x000 + ((v >> 24))];
+ table[0x300 + ((v ) & 0xFF)]
+ ^ table[0x200 + ((v >> 8) & 0xFF)]
+ ^ table[0x100 + ((v >> 16) & 0xFF)]
+ ^ table[0x000 + ((v >> 24))];
}
for (; size > 0; size--, 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)
{
- 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
@@ -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_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)
{
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;
+ 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)
{
v ^= *(const UInt32 *)p;
v =
- table[0x000 + (v & 0xFF)] ^
- table[0x100 + ((v >> 8) & 0xFF)] ^
- table[0x200 + ((v >> 16) & 0xFF)] ^
- table[0x300 + ((v >> 24))];
+ table[0x000 + ((v ) & 0xFF)]
+ ^ table[0x100 + ((v >> 8) & 0xFF)]
+ ^ table[0x200 + ((v >> 16) & 0xFF)]
+ ^ table[0x300 + ((v >> 24))];
}
- table -= 0x100;
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ 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(v, *p);
- return v;
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ return CRC_UINT32_SWAP(v);
}
#endif
diff --git a/C/7zDec.c b/C/7zDec.c
index 1c363a5..e39b4ff 100644
--- a/C/7zDec.c
+++ b/C/7zDec.c
@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder
-2014-06-16 : Igor Pavlov : Public domain */
+2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -8,10 +8,12 @@
/* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h"
+#include "7zCrc.h"
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
+#include "Delta.h"
#include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -19,14 +21,17 @@
#endif
#define k_Copy 0
+#define k_Delta 3
#define k_LZMA2 0x21
#define k_LZMA 0x30101
-#define k_BCJ 0x03030103
-#define k_PPC 0x03030205
-#define k_ARM 0x03030501
-#define k_ARMT 0x03030701
-#define k_SPARC 0x03030805
-#define k_BCJ2 0x0303011B
+#define k_BCJ 0x3030103
+#define k_BCJ2 0x303011B
+#define k_PPC 0x3030205
+#define k_IA64 0x3030401
+#define k_ARM 0x3030501
+#define k_ARMT 0x3030701
+#define k_SPARC 0x3030805
+
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -140,11 +145,11 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
for (;;)
{
- Byte *inBuf = NULL;
+ const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
- res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
+ res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
@@ -156,14 +161,23 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
inSize -= inProcessed;
if (res != SZ_OK)
break;
- if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
+
+ if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
- if (state.dicBufSize != outSize || lookahead != 0 ||
- (status != LZMA_STATUS_FINISHED_WITH_MARK &&
- status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
+ if (outSize != state.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
+
+ 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 = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
@@ -174,6 +188,9 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
return res;
}
+
+#ifndef _7Z_NO_METHOD_LZMA2
+
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
@@ -190,11 +207,11 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
for (;;)
{
- Byte *inBuf = NULL;
+ const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
- res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
+ res = inStream->Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
@@ -206,13 +223,20 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
inSize -= inProcessed;
if (res != SZ_OK)
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 ||
- (status != LZMA_STATUS_FINISHED_WITH_MARK))
+ if (outSize != state.decoder.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
+
+ if (inProcessed == 0 && dicPos == state.decoder.dicPos)
+ {
+ res = SZ_ERROR_DATA;
+ break;
+ }
+
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
@@ -223,15 +247,18 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
return res;
}
+#endif
+
+
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
{
- void *inBuf;
+ const void *inBuf;
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
- RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
+ RINOK(inStream->Look(inStream, &inBuf, &curSize));
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
@@ -248,7 +275,9 @@ static Bool IS_MAIN_METHOD(UInt32 m)
{
case k_Copy:
case k_LZMA:
+ #ifndef _7Z_NO_METHOD_LZMA2
case k_LZMA2:
+ #endif
#ifdef _7ZIP_PPMD_SUPPPORT
case k_PPMD:
#endif
@@ -260,13 +289,12 @@ static Bool IS_MAIN_METHOD(UInt32 m)
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{
return
- c->NumInStreams == 1 &&
- c->NumOutStreams == 1 &&
- /* c->MethodID <= (UInt32)0xFFFFFFFF && */
- IS_MAIN_METHOD((UInt32)c->MethodID);
+ c->NumStreams == 1
+ /* && c->MethodID <= (UInt32)0xFFFFFFFF */
+ && 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)
{
@@ -276,51 +304,64 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
return SZ_ERROR_UNSUPPORTED;
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_OK;
}
+
+
+ #ifndef _7Z_NO_METHODS_FILTERS
+
if (f->NumCoders == 2)
{
const CSzCoderInfo *c = &f->Coders[1];
if (
/* c->MethodID > (UInt32)0xFFFFFFFF || */
- c->NumInStreams != 1 ||
- c->NumOutStreams != 1 ||
- f->NumPackStreams != 1 ||
- f->PackStreams[0] != 0 ||
- f->NumBindPairs != 1 ||
- f->BindPairs[0].InIndex != 1 ||
- f->BindPairs[0].OutIndex != 0)
+ c->NumStreams != 1
+ || f->NumPackStreams != 1
+ || f->PackStreams[0] != 0
+ || f->NumBonds != 1
+ || f->Bonds[0].InIndex != 1
+ || f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
+ case k_Delta:
case k_BCJ:
+ case k_PPC:
+ case k_IA64:
+ case k_SPARC:
case k_ARM:
+ case k_ARMT:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
+
+ #endif
+
+
if (f->NumCoders == 4)
{
- if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
- !IS_SUPPORTED_CODER(&f->Coders[2]) ||
- !IS_BCJ2(&f->Coders[3]))
+ if (!IS_SUPPORTED_CODER(&f->Coders[1])
+ || !IS_SUPPORTED_CODER(&f->Coders[2])
+ || !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
- if (f->NumPackStreams != 4 ||
- f->PackStreams[0] != 2 ||
- f->PackStreams[1] != 6 ||
- f->PackStreams[2] != 1 ||
- f->PackStreams[3] != 0 ||
- f->NumBindPairs != 3 ||
- f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
- f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
- f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
+ if (f->NumPackStreams != 4
+ || f->PackStreams[0] != 2
+ || f->PackStreams[1] != 6
+ || f->PackStreams[2] != 1
+ || f->PackStreams[3] != 0
+ || f->NumBonds != 3
+ || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
+ || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
+ || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
+
return SZ_ERROR_UNSUPPORTED;
}
@@ -364,7 +405,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
- if (temp == 0 && outSizeCur != 0)
+ if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
@@ -393,66 +434,118 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
{
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
+ #ifndef _7Z_NO_METHOD_LZMA2
else if (coder->MethodID == k_LZMA2)
{
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));
- #else
- return SZ_ERROR_UNSUPPORTED;
- #endif
}
+ #endif
+ else
+ return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
UInt64 offset = packPositions[1];
UInt64 s3Size = packPositions[2] - offset;
- SRes res;
+
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
- RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
- if (tempBuf[2] == 0 && tempSizes[2] != 0)
+ if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
- res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
- RINOK(res)
-
- res = Bcj2_Decode(
- tempBuf3, tempSize3,
- tempBuf[0], tempSizes[0],
- tempBuf[1], tempSizes[1],
- tempBuf[2], tempSizes[2],
- outBuffer, outSize);
- RINOK(res)
+
+ RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+ RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
+
+ if ((tempSizes[0] & 3) != 0 ||
+ (tempSizes[1] & 3) != 0 ||
+ tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
+ return SZ_ERROR_DATA;
+
+ {
+ 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));
+
+ {
+ unsigned i;
+ for (i = 0; i < 4; i++)
+ if (p.bufs[i] != p.lims[i])
+ 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;
+ }
+ }
}
- else
+ #ifndef _7Z_NO_METHODS_FILTERS
+ else if (ci == 1)
{
- if (ci != 1)
- return SZ_ERROR_UNSUPPORTED;
- switch (coder->MethodID)
+ if (coder->MethodID == k_Delta)
{
- case k_BCJ:
+ if (coder->PropsSize != 1)
+ return SZ_ERROR_UNSUPPORTED;
{
- UInt32 state;
- x86_Convert_Init(state);
- x86_Convert(outBuffer, outSize, 0, &state, 0);
- break;
+ Byte state[DELTA_STATE_SIZE];
+ Delta_Init(state);
+ Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
- CASE_BRA_CONV(ARM)
- default:
+ }
+ 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;
}
+
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
@@ -461,33 +554,38 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
SRes res;
CSzFolder folder;
CSzData sd;
- CSzData sdSizes;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
- sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex];
- sdSizes.Size =
- p->FoSizesOffsets[folderIndex + 1] -
- p->FoSizesOffsets[folderIndex];
-
- res = SzGetNextFolderItem(&folder, &sd, &sdSizes);
+ res = SzGetNextFolderItem(&folder, &sd);
if (res != SZ_OK)
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;
{
- int i;
+ unsigned i;
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],
inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
+
for (i = 0; i < 3; i++)
IAlloc_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;
}
}
diff --git a/C/7zVersion.h b/C/7zVersion.h
index feedd30..acb67a9 100644
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,10 +1,19 @@
-#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 38
-#define MY_VER_BUILD 00
-#define MY_VERSION "9.38 beta"
-// #define MY_7ZIP_VERSION "9.38"
-#define MY_DATE "2015-01-03"
+#define MY_VER_MAJOR 16
+#define MY_VER_MINOR 04
+#define MY_VER_BUILD 0
+#define MY_VERSION_NUMBERS "16.04"
+#define MY_VERSION "16.04"
+#define MY_DATE "2016-10-04"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
-#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
+#define MY_AUTHOR_NAME "Igor Pavlov"
+#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov"
+
+#ifdef USE_COPYRIGHT_CR
+ #define MY_COPYRIGHT MY_COPYRIGHT_CR
+#else
+ #define MY_COPYRIGHT MY_COPYRIGHT_PD
+#endif
+
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
diff --git a/C/Aes.c b/C/Aes.c
index 06bf9d3..8e658e7 100644
--- a/C/Aes.c
+++ b/C/Aes.c
@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption
-2013-11-12 : Igor Pavlov : Public domain */
+2016-05-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -7,7 +7,7 @@
#include "CpuArch.h"
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,
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,
@@ -40,7 +40,7 @@ AES_CODE_FUNC g_AesCtr_Code;
static UInt32 D[256 * 4];
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)
@@ -56,6 +56,7 @@ void AesGenTables(void)
unsigned i;
for (i = 0; i < 256; i++)
InvS[Sbox[i]] = (Byte)i;
+
for (i = 0; i < 256; i++)
{
{
@@ -82,9 +83,11 @@ void AesGenTables(void)
D[0x300 + i] = Ui32(a9, aD, aB, aE);
}
}
+
g_AesCbc_Encode = AesCbc_Encode;
g_AesCbc_Decode = AesCbc_Decode;
g_AesCtr_Code = AesCtr_Code;
+
#ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported())
{
@@ -95,34 +98,38 @@ void AesGenTables(void)
#endif
}
+
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
+
#define HT4(m, i, s, p) m[i] = \
HT(i, 0, s) ^ \
HT(i, 1, s) ^ \
HT(i, 2, s) ^ \
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); \
+ 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 HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
+
#define HD4(m, i, s, p) m[i] = \
HD(i, 0, s) ^ \
HD(i, 1, s) ^ \
HD(i, 2, s) ^ \
HD(i, 3, s) ^ w[p + i];
-/* such order (0231) in HD16 is for VC6/K8 speed optimization) */
+
#define HD16(m, s, p) \
HD4(m, 0, s, p); \
+ HD4(m, 1, s, p); \
HD4(m, 2, s, p); \
HD4(m, 3, s, p); \
- HD4(m, 1, s, p); \
#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];
@@ -160,16 +167,16 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
{
UInt32 r = w[i];
w[i] =
- D[ Sbox[gb0(r)]] ^
- D[0x100 + Sbox[gb1(r)]] ^
- D[0x200 + Sbox[gb2(r)]] ^
- D[0x300 + Sbox[gb3(r)]];
+ D[ (unsigned)Sbox[gb0(r)]] ^
+ D[0x100 + (unsigned)Sbox[gb1(r)]] ^
+ D[0x200 + (unsigned)Sbox[gb2(r)]] ^
+ D[0x300 + (unsigned)Sbox[gb3(r)]];
}
}
/* Aes_Encode and Aes_Decode functions work with little-endian 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)
{
@@ -271,13 +278,17 @@ void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
UInt32 temp[4];
Byte buf[16];
int i;
+
if (++p[0] == 0)
p[1]++;
+
Aes_Encode(p + 4, temp, p);
+
SetUi32(buf, temp[0]);
SetUi32(buf + 4, temp[1]);
SetUi32(buf + 8, temp[2]);
SetUi32(buf + 12, temp[3]);
+
for (i = 0; i < 16; i++)
*data++ ^= buf[i];
}
diff --git a/C/Alloc.c b/C/Alloc.c
index 8e2839a..9f1d036 100644
--- a/C/Alloc.c
+++ b/C/Alloc.c
@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
-2013-11-12 : Igor Pavlov : Public domain */
+2015-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -125,3 +125,12 @@ void BigFree(void *address)
}
#endif
+
+
+static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
+static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
+static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
+ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
diff --git a/C/Alloc.h b/C/Alloc.h
index 6b3f034..73b282a 100644
--- a/C/Alloc.h
+++ b/C/Alloc.h
@@ -1,14 +1,12 @@
/* Alloc.h -- Memory allocation functions
-2009-02-07 : Igor Pavlov : Public domain */
+2015-02-21 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
-#include <stddef.h>
+#include "7zTypes.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
void *MyAlloc(size_t size);
void MyFree(void *address);
@@ -31,8 +29,9 @@ void BigFree(void *address);
#endif
-#ifdef __cplusplus
-}
-#endif
+extern ISzAlloc g_Alloc;
+extern ISzAlloc g_BigAlloc;
+
+EXTERN_C_END
#endif
diff --git a/C/Android.bp b/C/Android.bp
index 1ee4798..69cb5b6 100644
--- a/C/Android.bp
+++ b/C/Android.bp
@@ -58,6 +58,13 @@ cc_library {
},
windows: {
enabled: true,
+ srcs: [
+ "Bcj2Enc.c",
+ "DllSecur.c",
+ "LzFindMt.c",
+ "MtCoder.c",
+ "Threads.c",
+ ],
},
},
}
diff --git a/C/Bcj2.c b/C/Bcj2.c
index ac4ca0c..707362a 100644
--- a/C/Bcj2.c
+++ b/C/Bcj2.c
@@ -1,134 +1,256 @@
-/* Bcj2.c -- Converter for x86 code (BCJ2)
-2008-10-04 : Igor Pavlov : Public domain */
+/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
+2015-08-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bcj2.h"
+#include "CpuArch.h"
-#ifdef _LZMA_PROB32
-#define CProb UInt32
-#else
#define CProb UInt16
-#endif
-#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
-#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kTopValue ((UInt32)1 << 24)
+#define kNumModelBits 11
+#define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5
-#define RC_READ_BYTE (*buffer++)
-#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
-#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
- { 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; }
+#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
+#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
-#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)
+void Bcj2Dec_Init(CBcj2Dec *p)
{
- CProb p[256 + 2];
- SizeT inPos = 0, outPos = 0;
-
- const Byte *buffer, *bufferLim;
- UInt32 range, code;
- Byte prevByte = 0;
-
- unsigned int i;
- for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
- p[i] = kBitModelTotal >> 1;
+ unsigned i;
- buffer = buf3;
- bufferLim = buffer + size3;
- RC_INIT2
+ p->state = BCJ2_DEC_STATE_OK;
+ p->ip = 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;
+}
- if (outSize == 0)
- return SZ_OK;
+SRes Bcj2Dec_Decode(CBcj2Dec *p)
+{
+ if (p->range <= 5)
+ {
+ p->state = BCJ2_DEC_STATE_OK;
+ for (; p->range != 5; p->range++)
+ {
+ if (p->range == 1 && p->code != 0)
+ return SZ_ERROR_DATA;
+
+ if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
+ {
+ p->state = BCJ2_STREAM_RC;
+ return SZ_OK;
+ }
- for (;;)
+ p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
+ }
+
+ if (p->code == 0xFFFFFFFF)
+ return SZ_ERROR_DATA;
+
+ p->range = 0xFFFFFFFF;
+ }
+ else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{
- Byte b;
- CProb *prob;
- UInt32 bound;
- UInt32 ttt;
-
- SizeT limit = size0 - inPos;
- if (outSize - outPos < limit)
- limit = outSize - outPos;
- while (limit != 0)
+ while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{
- Byte b = buf0[inPos];
- outBuf[outPos++] = b;
- if (IsJ(prevByte, b))
- break;
- inPos++;
- prevByte = b;
- limit--;
+ Byte *dest = p->dest;
+ if (dest == p->destLim)
+ return SZ_OK;
+ *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
+ p->dest = dest + 1;
}
+ }
- if (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)
+ /*
+ 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;
+
{
- UPDATE_0(prob)
- prevByte = b;
+ 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 (;;)
+ {
+ if (BCJ2_IS_32BIT_STREAM(p->state))
+ p->state = BCJ2_DEC_STATE_OK;
else
{
- UInt32 dest;
- const Byte *v;
- UPDATE_1(prob)
- if (b == 0xE8)
+ if (p->range < kTopValue)
{
- v = buf1;
- if (size1 < 4)
- return SZ_ERROR_DATA;
- buf1 += 4;
- size1 -= 4;
+ if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
+ {
+ p->state = BCJ2_STREAM_RC;
+ return SZ_OK;
+ }
+ p->range <<= 8;
+ p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
- else
+
{
- v = buf2;
- if (size2 < 4)
- return SZ_ERROR_DATA;
- buf2 += 4;
- size2 -= 4;
+ const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
+ const Byte *srcLim;
+ Byte *dest;
+ SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
+
+ 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)
- break;
- outBuf[outPos++] = (Byte)(dest >> 8);
- 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;
- outBuf[outPos++] = (Byte)(dest >> 16);
- if (outPos == outSize)
+ }
+
+ val = GetBe32(cur);
+ p->bufs[cj] = cur + 4;
+
+ p->ip += 4;
+ val -= p->ip;
+ dest = p->dest;
+ rem = p->destLim - dest;
+
+ if (rem < 4)
+ {
+ SizeT i;
+ SetUi32(p->temp, val);
+ for (i = 0; i < rem; i++)
+ dest[i] = p->temp[i];
+ p->dest = dest + rem;
+ p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break;
- outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+ }
+
+ SetUi32(dest, val);
+ 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;
}
diff --git a/C/Bcj2.h b/C/Bcj2.h
index e8304c5..68893d2 100644
--- a/C/Bcj2.h
+++ b/C/Bcj2.h
@@ -1,5 +1,5 @@
-/* Bcj2.h -- Converter for x86 code (BCJ2)
-2013-01-18 : Igor Pavlov : Public domain */
+/* Bcj2.h -- BCJ2 Converter for x86 code
+2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H
#define __BCJ2_H
@@ -8,26 +8,138 @@
EXTERN_C_BEGIN
-/*
-Conditions:
- outSize <= FullOutputSize,
- where FullOutputSize is full size of output stream of x86_2 filter.
+#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
+};
-If buf0 overlaps outBuf, there are two required conditions:
- 1) (buf0 >= outBuf)
- 2) (buf0 + size0 >= outBuf + FullOutputSize).
-Returns:
- SZ_OK
- SZ_ERROR_DATA - Data error
+#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
+
+/*
+CBcj2Dec / CBcj2Enc
+bufs sizes:
+ BUF_SIZE(n) = lims[n] - bufs[n]
+bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
+ (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
+ (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
*/
-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);
+/*
+CBcj2Dec:
+dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
+ bufs[BCJ2_STREAM_MAIN] >= dest &&
+ bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
+ 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
diff --git a/C/Bcj2Enc.c b/C/Bcj2Enc.c
new file mode 100644
index 0000000..6a21015
--- /dev/null
+++ b/C/Bcj2Enc.c
@@ -0,0 +1,312 @@
+/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
+2014-11-10 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
+
+/* #define SHOW_STAT */
+
+#ifdef SHOW_STAT
+#include <stdio.h>
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+#include <windows.h>
+#include <string.h>
+
+#include "Bcj2.h"
+#include "CpuArch.h"
+
+#define CProb UInt16
+
+#define kTopValue ((UInt32)1 << 24)
+#define kNumModelBits 11
+#define kBitModelTotal (1 << kNumModelBits)
+#define kNumMoveBits 5
+
+void Bcj2Enc_Init(CBcj2Enc *p)
+{
+ unsigned i;
+
+ p->state = BCJ2_ENC_STATE_OK;
+ p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ p->prevByte = 0;
+
+ p->cache = 0;
+ p->range = 0xFFFFFFFF;
+ p->low = 0;
+ p->cacheSize = 1;
+
+ p->ip = 0;
+
+ p->fileIp = 0;
+ p->fileSize = 0;
+ p->relatLimit = BCJ2_RELAT_LIMIT;
+
+ p->tempPos = 0;
+
+ p->flushPos = 0;
+
+ for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
+ p->probs[i] = kBitModelTotal >> 1;
+}
+
+static Bool MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p)
+{
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0)
+ {
+ Byte *buf = p->bufs[BCJ2_STREAM_RC];
+ do
+ {
+ if (buf == p->lims[BCJ2_STREAM_RC])
+ {
+ p->state = BCJ2_STREAM_RC;
+ p->bufs[BCJ2_STREAM_RC] = buf;
+ return True;
+ }
+ *buf++ = (Byte)(p->cache + (Byte)(p->low >> 32));
+ p->cache = 0xFF;
+ }
+ while (--p->cacheSize);
+ p->bufs[BCJ2_STREAM_RC] = buf;
+ p->cache = (Byte)((UInt32)p->low >> 24);
+ }
+ p->cacheSize++;
+ p->low = (UInt32)p->low << 8;
+ return False;
+}
+
+static void Bcj2Enc_Encode_2(CBcj2Enc *p)
+{
+ if (BCJ2_IS_32BIT_STREAM(p->state))
+ {
+ Byte *cur = p->bufs[p->state];
+ if (cur == p->lims[p->state])
+ return;
+ SetBe32(cur, p->tempTarget);
+ p->bufs[p->state] = cur + 4;
+ }
+
+ p->state = BCJ2_ENC_STATE_ORIG;
+
+ for (;;)
+ {
+ if (p->range < kTopValue)
+ {
+ if (RangeEnc_ShiftLow(p))
+ return;
+ p->range <<= 8;
+ }
+
+ {
+ {
+ const Byte *src = p->src;
+ const Byte *srcLim;
+ Byte *dest;
+ SizeT num = p->srcLim - src;
+
+ if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE)
+ {
+ if (num <= 4)
+ return;
+ num -= 4;
+ }
+ else if (num == 0)
+ break;
+
+ dest = p->bufs[BCJ2_STREAM_MAIN];
+ if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest))
+ {
+ num = p->lims[BCJ2_STREAM_MAIN] - dest;
+ if (num == 0)
+ {
+ p->state = BCJ2_STREAM_MAIN;
+ return;
+ }
+ }
+
+ srcLim = src + num;
+
+ if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80)
+ *dest = src[0];
+ else for (;;)
+ {
+ Byte b = *src;
+ *dest = b;
+ if (b != 0x0F)
+ {
+ if ((b & 0xFE) == 0xE8)
+ break;
+ dest++;
+ if (++src != srcLim)
+ continue;
+ break;
+ }
+ dest++;
+ if (++src == srcLim)
+ break;
+ if ((*src & 0xF0) != 0x80)
+ continue;
+ *dest = *src;
+ break;
+ }
+
+ num = src - p->src;
+
+ if (src == srcLim)
+ {
+ p->prevByte = src[-1];
+ p->bufs[BCJ2_STREAM_MAIN] = dest;
+ p->src = src;
+ p->ip += (UInt32)num;
+ continue;
+ }
+
+ {
+ Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]);
+ Bool needConvert;
+
+ p->bufs[BCJ2_STREAM_MAIN] = dest + 1;
+ p->ip += (UInt32)num + 1;
+ src++;
+
+ needConvert = False;
+
+ if ((SizeT)(p->srcLim - src) >= 4)
+ {
+ UInt32 relatVal = GetUi32(src);
+ if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize)
+ && ((relatVal + p->relatLimit) >> 1) < p->relatLimit)
+ needConvert = True;
+ }
+
+ {
+ UInt32 bound;
+ unsigned ttt;
+ Byte b = src[-1];
+ CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0));
+
+ ttt = *prob;
+ bound = (p->range >> kNumModelBits) * ttt;
+
+ if (!needConvert)
+ {
+ p->range = bound;
+ *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+ p->src = src;
+ p->prevByte = b;
+ continue;
+ }
+
+ p->low += bound;
+ p->range -= bound;
+ *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
+
+ {
+ UInt32 relatVal = GetUi32(src);
+ UInt32 absVal;
+ p->ip += 4;
+ absVal = p->ip + relatVal;
+ p->prevByte = src[3];
+ src += 4;
+ p->src = src;
+ {
+ unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
+ Byte *cur = p->bufs[cj];
+ if (cur == p->lims[cj])
+ {
+ p->state = cj;
+ p->tempTarget = absVal;
+ return;
+ }
+ SetBe32(cur, absVal);
+ p->bufs[cj] = cur + 4;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM)
+ return;
+
+ for (; p->flushPos < 5; p->flushPos++)
+ if (RangeEnc_ShiftLow(p))
+ return;
+ p->state = BCJ2_ENC_STATE_OK;
+}
+
+
+void Bcj2Enc_Encode(CBcj2Enc *p)
+{
+ PRF(printf("\n"));
+ PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
+
+ if (p->tempPos != 0)
+ {
+ unsigned extra = 0;
+
+ for (;;)
+ {
+ const Byte *src = p->src;
+ const Byte *srcLim = p->srcLim;
+ unsigned finishMode = p->finishMode;
+
+ p->src = p->temp;
+ p->srcLim = p->temp + p->tempPos;
+ if (src != srcLim)
+ p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
+
+ PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
+
+ Bcj2Enc_Encode_2(p);
+
+ {
+ unsigned num = (unsigned)(p->src - p->temp);
+ unsigned tempPos = p->tempPos - num;
+ unsigned i;
+ p->tempPos = tempPos;
+ for (i = 0; i < tempPos; i++)
+ p->temp[i] = p->temp[i + num];
+
+ p->src = src;
+ p->srcLim = srcLim;
+ p->finishMode = finishMode;
+
+ if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim)
+ return;
+
+ if (extra >= tempPos)
+ {
+ p->src = src - tempPos;
+ p->tempPos = 0;
+ break;
+ }
+
+ p->temp[tempPos] = src[0];
+ p->tempPos = tempPos + 1;
+ p->src = src + 1;
+ extra++;
+ }
+ }
+ }
+
+ PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
+
+ Bcj2Enc_Encode_2(p);
+
+ if (p->state == BCJ2_ENC_STATE_ORIG)
+ {
+ const Byte *src = p->src;
+ unsigned rem = (unsigned)(p->srcLim - src);
+ unsigned i;
+ for (i = 0; i < rem; i++)
+ p->temp[i] = src[i];
+ p->tempPos = rem;
+ p->src = src + rem;
+ }
+}
diff --git a/C/Compiler.h b/C/Compiler.h
index 0f76670..de8fab3 100644
--- a/C/Compiler.h
+++ b/C/Compiler.h
@@ -1,5 +1,5 @@
-/* Compiler.h -- Compiler ypes
-2013-11-12 : Igor Pavlov : Public domain */
+/* Compiler.h
+2015-08-02 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
@@ -18,6 +18,7 @@
#else
#pragma warning(disable : 4511) // copy constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated
+ #pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
@@ -25,4 +26,7 @@
#endif
+#define UNUSED_VAR(x) (void)x;
+/* #define UNUSED_VAR(x) x=x; */
+
#endif
diff --git a/C/CpuArch.c b/C/CpuArch.c
index f8ac0c2..f835c2b 100644
--- a/C/CpuArch.c
+++ b/C/CpuArch.c
@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
-2012-05-29: Igor Pavlov : Public domain */
+2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t"
"popf\n\t"
"andl %%EAX, %0\n\t":
- "=c" (flag) : "c" (flag));
+ "=c" (flag) : "c" (flag) :
+ "%eax", "%edx");
#endif
return flag;
}
@@ -54,7 +55,7 @@ static UInt32 CheckFlag(UInt32 flag)
#define CHECK_CPUID_IS_SUPPORTED
#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
@@ -79,7 +80,13 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else
__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;"
"cpuid;"
"xchgl %%ebx, %%edi;"
@@ -116,7 +123,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
return True;
}
-static UInt32 kVendors[][3] =
+static const UInt32 kVendors[][3] =
{
{ 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
@@ -144,18 +151,21 @@ Bool CPU_Is_InOrder()
UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p))
return True;
- family = x86cpuid_GetFamily(&p);
- model = x86cpuid_GetModel(&p);
+
+ family = x86cpuid_GetFamily(p.ver);
+ model = x86cpuid_GetModel(p.ver);
+
firm = x86cpuid_GetFirm(&p);
+
switch (firm)
{
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
- /* Atom CPU */
- model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
- || model == 0x2006 /* 45 nm, Z6xx */
- || model == 0x2007 /* 32 nm, Z2460 */
- || model == 0x3005 /* 32 nm, Z2760 */
- || model == 0x3006 /* 32 nm, N2xxx, D2xxx */
+ /* In-Order Atom CPU */
+ model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
+ || model == 0x26 /* 45 nm, Z6xx */
+ || model == 0x27 /* 32 nm, Z2460 */
+ || model == 0x35 /* 32 nm, Z2760 */
+ || model == 0x36 /* 32 nm, N2xxx, D2xxx */
)));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
diff --git a/C/CpuArch.h b/C/CpuArch.h
index 2316205..ef6083c 100644
--- a/C/CpuArch.h
+++ b/C/CpuArch.h
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
-2013-11-12: Igor Pavlov : Public domain */
+2016-06-09: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -10,18 +10,25 @@ EXTERN_C_BEGIN
/*
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.
-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__)
-#define MY_CPU_AMD64
+#if defined(_M_X64) \
+ || defined(_M_AMD64) \
+ || defined(__x86_64__) \
+ || defined(__AMD64__) \
+ || defined(__amd64__)
+ #define MY_CPU_AMD64
#endif
-#if defined(MY_CPU_AMD64) || defined(_M_IA64)
-#define MY_CPU_64BIT
+#if defined(MY_CPU_AMD64) \
+ || defined(_M_IA64) \
+ || defined(__AARCH64EL__) \
+ || defined(__AARCH64EB__)
+ #define MY_CPU_64BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
@@ -32,8 +39,13 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_X86_OR_AMD64
#endif
-#if defined(MY_CPU_X86) || defined(_M_ARM)
-#define MY_CPU_32BIT
+#if defined(MY_CPU_X86) \
+ || defined(_M_ARM) \
+ || defined(__ARMEL__) \
+ || defined(__THUMBEL__) \
+ || defined(__ARMEB__) \
+ || defined(__THUMBEB__)
+ #define MY_CPU_32BIT
#endif
#if defined(_WIN32) && defined(_M_ARM)
@@ -44,34 +56,64 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_IA64_LE
#endif
-#if defined(MY_CPU_X86_OR_AMD64)
-#define MY_CPU_LE_UNALIGN
+#if defined(MY_CPU_X86_OR_AMD64) \
+ || defined(MY_CPU_ARM_LE) \
+ || defined(MY_CPU_IA64_LE) \
+ || defined(__LITTLE_ENDIAN__) \
+ || defined(__ARMEL__) \
+ || defined(__THUMBEL__) \
+ || defined(__AARCH64EL__) \
+ || defined(__MIPSEL__) \
+ || defined(__MIPSEL) \
+ || defined(_MIPSEL) \
+ || defined(__BFIN__) \
+ || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
+ #define MY_CPU_LE
#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
+#if defined(__BIG_ENDIAN__) \
+ || 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
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#endif
+
+#ifdef MY_CPU_LE
+ #if defined(MY_CPU_X86_OR_AMD64) \
+ /* || defined(__AARCH64EL__) */
+ #define MY_CPU_LE_UNALIGN
+ #endif
+#endif
+
+
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(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 SetUi64(p, d) *(UInt64 *)(p) = (d);
+
+#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
+#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
+#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#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) ( \
((const Byte *)(p))[0] | \
@@ -81,23 +123,26 @@ Stop_Compiling_Bad_Endian
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
-#define SetUi16(p, d) { UInt32 _x_ = (d); \
- ((Byte *)(p))[0] = (Byte)_x_; \
- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
+#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); }
-#define SetUi32(p, d) { UInt32 _x_ = (d); \
- ((Byte *)(p))[0] = (Byte)_x_; \
- ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
- ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
- ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
+#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
+ _ppp_[0] = (Byte)_vvv_; \
+ _ppp_[1] = (Byte)(_vvv_ >> 8); \
+ _ppp_[2] = (Byte)(_vvv_ >> 16); \
+ _ppp_[3] = (Byte)(_vvv_ >> 24); }
-#define SetUi64(p, d) { UInt64 _x64_ = (d); \
- SetUi32(p, (UInt32)_x64_); \
- SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
+#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
+ SetUi32(_ppp2_ , (UInt32)_vvv2_); \
+ SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
-#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
+
+#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
+
+/* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h>
@@ -106,6 +151,15 @@ Stop_Compiling_Bad_Endian
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
+
+#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+
+#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
+
+#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
+
#else
#define GetBe32(p) ( \
@@ -116,9 +170,19 @@ Stop_Compiling_Bad_Endian
#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
-#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]))
+
+#define GetBe16(p) ( (UInt16) ( \
+ ((UInt16)((const Byte *)(p))[0] << 8) | \
+ ((const Byte *)(p))[1] ))
+
#ifdef MY_CPU_X86_OR_AMD64
@@ -140,12 +204,14 @@ enum
CPU_FIRM_VIA
};
+void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
+
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
-#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
-#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
-#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
+#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
+#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
+#define x86cpuid_GetStepping(ver) (ver & 0xF)
Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported();
diff --git a/C/DllSecur.c b/C/DllSecur.c
new file mode 100644
index 0000000..8745421
--- /dev/null
+++ b/C/DllSecur.c
@@ -0,0 +1,87 @@
+/* DllSecur.c -- DLL loading security
+2016-10-04 : 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"
+ ;
+
+#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] = c;
+ k++;
+ if (c == 0)
+ break;
+ }
+
+ lstrcatW(buf, L".dll");
+ LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ }
+ }
+
+ #endif
+}
+
+#endif
diff --git a/C/DllSecur.h b/C/DllSecur.h
new file mode 100644
index 0000000..023c509
--- /dev/null
+++ b/C/DllSecur.h
@@ -0,0 +1,19 @@
+/* DllSecur.h -- DLL loading for security
+2016-06-08 : Igor Pavlov : Public domain */
+
+#ifndef __DLL_SECUR_H
+#define __DLL_SECUR_H
+
+#include "7zTypes.h"
+
+EXTERN_C_BEGIN
+
+#ifdef _WIN32
+
+void LoadSecurityDlls();
+
+#endif
+
+EXTERN_C_END
+
+#endif
diff --git a/C/LzFind.c b/C/LzFind.c
index df79867..c335d36 100644
--- a/C/LzFind.c
+++ b/C/LzFind.c
@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms
-2009-04-22 : Igor Pavlov : Public domain */
+2015-10-15 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -11,8 +11,8 @@
#define kEmptyHashValue 0
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-#define kNormalizeMask (~(kNormalizeStepMin - 1))
-#define kMaxHistorySize ((UInt32)3 << 30)
+#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)7 << 29)
#define kStartMaxLen 3
@@ -21,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
if (!p->directInput)
{
alloc->Free(alloc, p->bufferBase);
- p->bufferBase = 0;
+ p->bufferBase = NULL;
}
}
@@ -35,17 +35,16 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
p->blockSize = blockSize;
return 1;
}
- if (p->bufferBase == 0 || p->blockSize != blockSize)
+ if (!p->bufferBase || p->blockSize != blockSize)
{
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
}
- return (p->bufferBase != 0);
+ return (p->bufferBase != NULL);
}
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
@@ -60,9 +59,12 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
+
+ /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
+
if (p->directInput)
{
- UInt32 curSize = 0xFFFFFFFF - p->streamPos;
+ UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
if (curSize > p->directInputRem)
curSize = (UInt32)p->directInputRem;
p->directInputRem -= curSize;
@@ -71,12 +73,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
p->streamEndWasReached = 1;
return;
}
+
for (;;)
{
Byte *dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest);
if (size == 0)
return;
+
p->result = p->stream->Read(p->stream, dest, &size);
if (p->result != SZ_OK)
return;
@@ -94,8 +98,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
void MatchFinder_MoveBlock(CMatchFinder *p)
{
memmove(p->bufferBase,
- p->buffer - p->keepSizeBefore,
- (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+ p->buffer - p->keepSizeBefore,
+ (size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
p->buffer = p->bufferBase + p->keepSizeBefore;
}
@@ -135,15 +139,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
void MatchFinder_Construct(CMatchFinder *p)
{
UInt32 i;
- p->bufferBase = 0;
+ p->bufferBase = NULL;
p->directInput = 0;
- p->hash = 0;
+ p->hash = NULL;
MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++)
{
UInt32 r = i;
- int j;
+ unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r;
@@ -153,7 +157,7 @@ void MatchFinder_Construct(CMatchFinder *p)
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hash);
- p->hash = 0;
+ p->hash = NULL;
}
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
@@ -162,11 +166,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
LzInWindow_Free(p, alloc);
}
-static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
- return 0;
+ return NULL;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
}
@@ -175,19 +179,24 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
ISzAlloc *alloc)
{
UInt32 sizeReserv;
+
if (historySize > kMaxHistorySize)
{
MatchFinder_Free(p, alloc);
return 0;
}
+
sizeReserv = historySize >> 1;
- if (historySize > ((UInt32)2 << 30))
- sizeReserv = historySize >> 2;
+ if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
+ else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
+
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+
if (LzInWindow_Create(p, sizeReserv, alloc))
{
UInt32 newCyclicBufferSize = historySize + 1;
@@ -212,6 +221,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
hs = (1 << 24) - 1;
else
hs >>= 1;
+ /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
}
}
p->hashMask = hs;
@@ -223,24 +233,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
}
{
- UInt32 prevSize = p->hashSizeSum + p->numSons;
- UInt32 newSize;
+ size_t newSize;
+ size_t numSons;
p->historySize = historySize;
p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize;
- p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
- newSize = p->hashSizeSum + p->numSons;
- if (p->hash != 0 && prevSize == newSize)
+
+ numSons = newCyclicBufferSize;
+ if (p->btMode)
+ numSons <<= 1;
+ newSize = hs + numSons;
+
+ if (p->hash && p->numRefs == newSize)
return 1;
+
MatchFinder_FreeThisClassMemory(p, alloc);
+ p->numRefs = newSize;
p->hash = AllocRefs(newSize, alloc);
- if (p->hash != 0)
+
+ if (p->hash)
{
p->son = p->hash + p->hashSizeSum;
return 1;
}
}
}
+
MatchFinder_Free(p, alloc);
return 0;
}
@@ -249,9 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
{
UInt32 limit = kMaxValForNormalize - p->pos;
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+
if (limit2 < limit)
limit = limit2;
limit2 = p->streamPos - p->pos;
+
if (limit2 <= p->keepSizeAfter)
{
if (limit2 > 0)
@@ -259,8 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
}
else
limit2 -= p->keepSizeAfter;
+
if (limit2 < limit)
limit = limit2;
+
{
UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
@@ -270,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
p->posLimit = p->pos + limit;
}
-void MatchFinder_Init(CMatchFinder *p)
+void MatchFinder_Init_2(CMatchFinder *p, int readData)
{
UInt32 i;
- for (i = 0; i < p->hashSizeSum; i++)
- p->hash[i] = kEmptyHashValue;
+ UInt32 *hash = p->hash;
+ UInt32 num = p->hashSizeSum;
+ for (i = 0; i < num; i++)
+ hash[i] = kEmptyHashValue;
+
p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK;
p->streamEndWasReached = 0;
- MatchFinder_ReadBlock(p);
+
+ if (readData)
+ MatchFinder_ReadBlock(p);
+
MatchFinder_SetLimits(p);
}
+void MatchFinder_Init(CMatchFinder *p)
+{
+ MatchFinder_Init_2(p, True);
+}
+
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{
return (p->pos - p->historySize - 1) & kNormalizeMask;
}
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems)
{
- UInt32 i;
+ size_t i;
for (i = 0; i < numItems; i++)
{
UInt32 value = items[i];
@@ -306,7 +339,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
static void MatchFinder_Normalize(CMatchFinder *p)
{
UInt32 subValue = MatchFinder_GetSubValue(p);
- MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+ MatchFinder_Normalize3(subValue, p->hash, p->numRefs);
MatchFinder_ReduceOffsets(p, subValue);
}
@@ -467,7 +500,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \
- UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+ UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
cur = p->buffer;
@@ -483,13 +516,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+#define UPDATE_maxLen { \
+ ptrdiff_t diff = (ptrdiff_t)0 - d2; \
+ const Byte *c = cur + maxLen; \
+ const Byte *lim = cur + lenLimit; \
+ for (; c != lim; c++) if (*(c + diff) != *c) break; \
+ maxLen = (UInt32)(c - cur); }
+
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(2)
HASH2_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 1)
}
@@ -499,35 +539,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 2)
}
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
- UInt32 hash2Value, delta2, maxLen, offset;
+ UInt32 h2, d2, maxLen, offset, pos;
+ UInt32 *hash;
GET_MATCHES_HEADER(3)
HASH3_CALC;
- delta2 = p->pos - p->hash[hash2Value];
- curMatch = p->hash[kFix3HashSize + hashValue];
-
- p->hash[hash2Value] =
- p->hash[kFix3HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ pos = p->pos;
+ d2 = pos - hash[h2];
+
+ curMatch = hash[kFix3HashSize + hv];
+
+ hash[h2] = pos;
+ hash[kFix3HashSize + hv] = pos;
maxLen = 2;
offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
+ UPDATE_maxLen
distances[0] = maxLen;
- distances[1] = delta2 - 1;
+ distances[1] = d2 - 1;
offset = 2;
if (maxLen == lenLimit)
{
@@ -535,44 +578,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
+
GET_MATCHES_FOOTER(offset, maxLen)
}
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ UInt32 h2, h3, d2, d3, maxLen, offset, pos;
+ UInt32 *hash;
GET_MATCHES_HEADER(4)
HASH4_CALC;
- delta2 = p->pos - p->hash[ hash2Value];
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
- curMatch = p->hash[kFix4HashSize + hashValue];
-
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ pos = p->pos;
- maxLen = 1;
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+
+ curMatch = hash[kFix4HashSize + hv];
+
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + hv] = pos;
+
+ maxLen = 0;
offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
- distances[1] = delta2 - 1;
+ distances[1] = d2 - 1;
offset = 2;
}
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
- distances[offset + 1] = delta3 - 1;
+ distances[offset + 1] = d3 - 1;
offset += 2;
- delta2 = delta3;
+ d2 = d3;
}
+
if (offset != 0)
{
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
+ UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
@@ -580,46 +630,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
+
if (maxLen < 3)
maxLen = 3;
+
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+/*
+static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos;
+ UInt32 *hash;
+ GET_MATCHES_HEADER(5)
+
+ HASH5_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+ d4 = pos - hash[kFix4HashSize + h4];
+
+ curMatch = hash[kFix5HashSize + hv];
+
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + h4] = pos;
+ hash[kFix5HashSize + hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (*(cur - d2 + 2) == cur[2])
+ distances[0] = maxLen = 3;
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[2] = maxLen = 3;
+ distances[3] = d3 - 1;
+ offset = 4;
+ d2 = d3;
+ }
+ }
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[0] = maxLen = 3;
+ distances[1] = d3 - 1;
+ offset = 2;
+ d2 = d3;
+ }
+
+ if (d2 != d4 && d4 < p->cyclicBufferSize
+ && *(cur - d4) == *cur
+ && *(cur - d4 + 3) == *(cur + 3))
+ {
+ maxLen = 4;
+ distances[offset + 1] = d4 - 1;
+ offset += 2;
+ d2 = d4;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 4)
+ maxLen = 4;
+
GET_MATCHES_FOOTER(offset, maxLen)
}
+*/
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ UInt32 h2, h3, d2, d3, maxLen, offset, pos;
+ UInt32 *hash;
GET_MATCHES_HEADER(4)
HASH4_CALC;
- delta2 = p->pos - p->hash[ hash2Value];
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
- curMatch = p->hash[kFix4HashSize + hashValue];
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+
+ curMatch = hash[kFix4HashSize + hv];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + hv] = pos;
- maxLen = 1;
+ maxLen = 0;
offset = 0;
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
- distances[1] = delta2 - 1;
+ distances[1] = d2 - 1;
offset = 2;
}
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
- distances[offset + 1] = delta3 - 1;
+ distances[offset + 1] = d3 - 1;
offset += 2;
- delta2 = delta3;
+ d2 = d3;
}
+
if (offset != 0)
{
- for (; maxLen != lenLimit; maxLen++)
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
- break;
+ UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
@@ -627,22 +762,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
+
if (maxLen < 3)
maxLen = 3;
+
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
- distances + offset, maxLen) - (distances));
+ distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
+/*
+static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos
+ UInt32 *hash;
+ GET_MATCHES_HEADER(5)
+
+ HASH5_CALC;
+
+ hash = p->hash;
+ pos = p->pos;
+
+ d2 = pos - hash[ h2];
+ d3 = pos - hash[kFix3HashSize + h3];
+ d4 = pos - hash[kFix4HashSize + h4];
+
+ curMatch = hash[kFix5HashSize + hv];
+
+ hash[ h2] = pos;
+ hash[kFix3HashSize + h3] = pos;
+ hash[kFix4HashSize + h4] = pos;
+ hash[kFix5HashSize + hv] = pos;
+
+ maxLen = 0;
+ offset = 0;
+
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = d2 - 1;
+ offset = 2;
+ if (*(cur - d2 + 2) == cur[2])
+ distances[0] = maxLen = 3;
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[2] = maxLen = 3;
+ distances[3] = d3 - 1;
+ offset = 4;
+ d2 = d3;
+ }
+ }
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
+ {
+ distances[0] = maxLen = 3;
+ distances[1] = d3 - 1;
+ offset = 2;
+ d2 = d3;
+ }
+
+ if (d2 != d4 && d4 < p->cyclicBufferSize
+ && *(cur - d4) == *cur
+ && *(cur - d4 + 3) == *(cur + 3))
+ {
+ maxLen = 4;
+ distances[offset + 1] = d4 - 1;
+ offset += 2;
+ d2 = d4;
+ }
+
+ if (offset != 0)
+ {
+ UPDATE_maxLen
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+
+ if (maxLen < 4)
+ maxLen = 4;
+
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+*/
+
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
- distances, 2) - (distances));
+ distances, 2) - (distances));
MOVE_POS_RET
}
@@ -652,8 +868,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
SKIP_HEADER(2)
HASH2_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -665,8 +881,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -676,12 +892,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
- UInt32 hash2Value;
+ UInt32 h2;
+ UInt32 *hash;
SKIP_HEADER(3)
HASH3_CALC;
- curMatch = p->hash[kFix3HashSize + hashValue];
- p->hash[hash2Value] =
- p->hash[kFix3HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ curMatch = hash[kFix3HashSize + hv];
+ hash[h2] =
+ hash[kFix3HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -691,43 +909,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
- UInt32 hash2Value, hash3Value;
+ UInt32 h2, h3;
+ UInt32 *hash;
SKIP_HEADER(4)
HASH4_CALC;
- curMatch = p->hash[kFix4HashSize + hashValue];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] = p->pos;
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ curMatch = hash[kFix4HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + hv] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+/*
+static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3, h4;
+ UInt32 *hash;
+ SKIP_HEADER(5)
+ HASH5_CALC;
+ hash = p->hash;
+ curMatch = hash[kFix5HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + h4] =
+ hash[kFix5HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
+*/
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
- UInt32 hash2Value, hash3Value;
+ UInt32 h2, h3;
+ UInt32 *hash;
SKIP_HEADER(4)
HASH4_CALC;
- curMatch = p->hash[kFix4HashSize + hashValue];
- p->hash[ hash2Value] =
- p->hash[kFix3HashSize + hash3Value] =
- p->hash[kFix4HashSize + hashValue] = p->pos;
+ hash = p->hash;
+ curMatch = hash[kFix4HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
+/*
+static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 h2, h3, h4;
+ UInt32 *hash;
+ SKIP_HEADER(5)
+ HASH5_CALC;
+ hash = p->hash;
+ curMatch = p->hash[kFix5HashSize + hv];
+ hash[ h2] =
+ hash[kFix3HashSize + h3] =
+ hash[kFix4HashSize + h4] =
+ hash[kFix5HashSize + hv] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+*/
+
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
- curMatch = p->hash[hashValue];
- p->hash[hashValue] = p->pos;
+ curMatch = p->hash[hv];
+ p->hash[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
@@ -737,13 +1002,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
if (!p->btMode)
{
- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ /* if (p->numHashBytes <= 4) */
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ }
+ /*
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
+ }
+ */
}
else if (p->numHashBytes == 2)
{
@@ -755,9 +1029,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
}
- else
+ else /* if (p->numHashBytes == 4) */
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
}
+ /*
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
+ }
+ */
}
diff --git a/C/LzFind.h b/C/LzFind.h
index bad5000..2ff6673 100644
--- a/C/LzFind.h
+++ b/C/LzFind.h
@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms
-2013-01-18 : Igor Pavlov : Public domain */
+2015-10-15 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
@@ -21,6 +21,11 @@ typedef struct _CMatchFinder
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+ Byte streamEndWasReached;
+ Byte btMode;
+ Byte bigHash;
+ Byte directInput;
+
UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
@@ -29,30 +34,30 @@ typedef struct _CMatchFinder
Byte *bufferBase;
ISeqInStream *stream;
- int streamEndWasReached;
-
+
UInt32 blockSize;
UInt32 keepSizeBefore;
UInt32 keepSizeAfter;
UInt32 numHashBytes;
- int directInput;
size_t directInputRem;
- int btMode;
- int bigHash;
UInt32 historySize;
UInt32 fixedHashSize;
UInt32 hashSizeSum;
- UInt32 numSons;
SRes result;
UInt32 crc[256];
+ size_t numRefs;
} CMatchFinder;
#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_IsFinishedOK(p) \
+ ((p)->streamEndWasReached \
+ && (p)->streamPos == (p)->pos \
+ && (!(p)->directInput || (p)->directInputRem == 0))
+
int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p);
@@ -68,7 +73,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
@@ -82,7 +87,6 @@ Conditions:
*/
typedef void (*Mf_Init_Func)(void *object);
-typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
@@ -91,7 +95,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder
{
Mf_Init_Func Init;
- Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;
@@ -100,9 +103,12 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+void MatchFinder_Init_2(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p);
+
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
diff --git a/C/LzFindMt.c b/C/LzFindMt.c
index 5356d4a..cb61e09 100644
--- a/C/LzFindMt.c
+++ b/C/LzFindMt.c
@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2014-12-29 : Igor Pavlov : Public domain */
+2015-10-15 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -7,7 +7,7 @@
#include "LzFindMt.h"
-void MtSync_Construct(CMtSync *p)
+static void MtSync_Construct(CMtSync *p)
{
p->wasCreated = False;
p->csWasInitialized = False;
@@ -20,7 +20,7 @@ void MtSync_Construct(CMtSync *p)
Semaphore_Construct(&p->filledSemaphore);
}
-void MtSync_GetNextBlock(CMtSync *p)
+static void MtSync_GetNextBlock(CMtSync *p)
{
if (p->needStart)
{
@@ -48,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p)
/* MtSync_StopWriting must be called if Writing was started */
-void MtSync_StopWriting(CMtSync *p)
+static void MtSync_StopWriting(CMtSync *p)
{
UInt32 myNumBlocks = p->numProcessedBlocks;
if (!Thread_WasCreated(&p->thread) || p->needStart)
@@ -71,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p)
p->needStart = True;
}
-void MtSync_Destruct(CMtSync *p)
+static void MtSync_Destruct(CMtSync *p)
{
if (Thread_WasCreated(&p->thread))
{
@@ -134,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; }
#define kMtMaxValForNormalize 0xFFFFFFFF
#define DEF_GetHeads2(name, v, action) \
-static void GetHeads ## name(const Byte *p, UInt32 pos, \
-UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
-{ action; for (; numHeads != 0; numHeads--) { \
-const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
+ static void GetHeads ## name(const Byte *p, UInt32 pos, \
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
+ { action; for (; numHeads != 0; numHeads--) { \
+ const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
#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(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(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;
for (;;)
@@ -173,12 +173,12 @@ void HashThreadFunc(CMatchFinderMt *mt)
CriticalSection_Enter(&mt->btSync.cs);
CriticalSection_Enter(&mt->hashSync.cs);
{
- const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
- const Byte *afterPtr;
+ const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ ptrdiff_t offset;
MatchFinder_MoveBlock(mf);
- afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
- mt->pointerToCurPos -= beforePtr - afterPtr;
- mt->buffer -= beforePtr - afterPtr;
+ offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
+ mt->pointerToCurPos -= offset;
+ mt->buffer -= offset;
}
CriticalSection_Leave(&mt->btSync.cs);
CriticalSection_Leave(&mt->hashSync.cs);
@@ -192,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
{
UInt32 subValue = (mf->pos - mf->historySize - 1);
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;
@@ -217,7 +217,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
}
}
-void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
+static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
{
MtSync_GetNextBlock(&p->hashSync);
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -233,7 +233,7 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
#define NO_INLINE MY_FAST_CALL
-Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
+static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
{
@@ -310,12 +310,14 @@ Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CL
#endif
-void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
+static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{
UInt32 numProcessed = 0;
UInt32 curPos = 2;
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
+
distances[1] = p->hashNumAvail;
+
while (curPos < limit)
{
if (p->hashBufPos == p->hashBufPosLimit)
@@ -324,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
distances[1] = numProcessed + p->hashNumAvail;
if (p->hashNumAvail >= p->numHashBytes)
continue;
+ distances[0] = curPos + p->hashNumAvail;
+ distances += curPos;
for (; p->hashNumAvail != 0; p->hashNumAvail--)
- distances[curPos++] = 0;
- break;
+ *distances++ = 0;
+ return;
}
{
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
@@ -343,13 +347,14 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
if (size2 < size)
size = size2;
}
+
#ifndef MFMT_GM_INLINE
while (curPos < limit && size-- != 0)
{
UInt32 *startDistances = distances + curPos;
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
- pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
- startDistances + 1, p->numHashBytes - 1) - startDistances);
+ pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
+ startDistances + 1, p->numHashBytes - 1) - startDistances);
*startDistances = num - 1;
curPos += num;
cyclicBufferPos++;
@@ -360,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{
UInt32 posRes;
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
- distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
+ distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes);
p->hashBufPos += posRes - pos;
cyclicBufferPos += posRes - pos;
p->buffer += posRes - pos;
@@ -376,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
p->cyclicBufferPos = cyclicBufferPos;
}
}
+
distances[0] = curPos;
}
-void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
+static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
{
CMtSync *sync = &p->hashSync;
if (!sync->needStart)
@@ -393,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
{
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;
}
@@ -432,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt)
void MatchFinderMt_Construct(CMatchFinderMt *p)
{
- p->hashBuf = 0;
+ p->hashBuf = NULL;
MtSync_Construct(&p->hashSync);
MtSync_Construct(&p->btSync);
}
-void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hashBuf);
- p->hashBuf = 0;
+ p->hashBuf = NULL;
}
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
@@ -457,9 +463,11 @@ 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)
{
Byte allocaDummy[0x180];
- allocaDummy[0] = 0;
- allocaDummy[1] = allocaDummy[0];
- BtThreadFunc((CMatchFinderMt *)p);
+ unsigned i = 0;
+ for (i = 0; i < 16; i++)
+ allocaDummy[i] = (Byte)0;
+ if (allocaDummy[0] == 0)
+ BtThreadFunc((CMatchFinderMt *)p);
return 0;
}
@@ -470,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
p->historySize = historySize;
if (kMtBtBlockSize <= matchMaxLen * 4)
return SZ_ERROR_PARAM;
- if (p->hashBuf == 0)
+ if (!p->hashBuf)
{
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
- if (p->hashBuf == 0)
+ if (!p->hashBuf)
return SZ_ERROR_MEM;
p->btBuf = p->hashBuf + kHashBufferSize;
}
@@ -493,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
CMatchFinder *mf = p->MatchFinder;
p->btBufPos = p->btBufPosLimit = 0;
p->hashBufPos = p->hashBufPosLimit = 0;
- MatchFinder_Init(mf);
- p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
+
+ /* Init without data reading. We don't want to read data in this thread */
+ MatchFinder_Init_2(mf, False);
+
+ p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
p->btNumAvailBytes = 0;
p->lzPos = p->historySize + 1;
@@ -519,13 +530,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
/* 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);
p->lzPos = p->historySize + 1;
}
-void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
+static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
{
UInt32 blockIndex;
MtSync_GetNextBlock(&p->btSync);
@@ -537,34 +548,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
MatchFinderMt_Normalize(p);
}
-const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
{
return p->pointerToCurPos;
}
#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;
return p->btNumAvailBytes;
}
-Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
-{
- return p->pointerToCurPos[index];
-}
-
-UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
- UInt32 hash2Value, curMatch2;
+ UInt32 h2, curMatch2;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH2_CALC
- curMatch2 = hash[hash2Value];
- hash[hash2Value] = lzPos;
+ curMatch2 = hash[h2];
+ hash[h2] = lzPos;
if (curMatch2 >= matchMinPos)
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
@@ -572,23 +578,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 2;
*distances++ = lzPos - curMatch2 - 1;
}
+
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;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH3_CALC
- curMatch2 = hash[ hash2Value];
- curMatch3 = hash[kFix3HashSize + hash3Value];
+ curMatch2 = hash[ h2];
+ curMatch3 = hash[kFix3HashSize + h3];
- hash[ hash2Value] =
- hash[kFix3HashSize + hash3Value] =
- lzPos;
+ hash[ h2] = lzPos;
+ hash[kFix3HashSize + h3] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
@@ -601,43 +607,45 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
distances[0] = 2;
distances += 2;
}
+
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{
*distances++ = 3;
*distances++ = lzPos - curMatch3 - 1;
}
+
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;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH4_CALC
- curMatch2 = hash[ hash2Value];
- curMatch3 = hash[kFix3HashSize + hash3Value];
- curMatch4 = hash[kFix4HashSize + hash4Value];
+ curMatch2 = hash[ h2];
+ curMatch3 = hash[kFix3HashSize + h3];
+ curMatch4 = hash[kFix4HashSize + h4];
- hash[ hash2Value] =
- hash[kFix3HashSize + hash3Value] =
- hash[kFix4HashSize + hash4Value] =
- lzPos;
+ hash[ h2] = lzPos;
+ hash[kFix3HashSize + h3] = lzPos;
+ hash[kFix4HashSize + h4] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
distances[1] = lzPos - curMatch2 - 1;
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;
}
distances[0] = 2;
distances += 2;
}
+
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{
distances[1] = lzPos - curMatch3 - 1;
@@ -659,13 +667,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 4;
*distances++ = lzPos - curMatch4 - 1;
}
+
return distances;
}
*/
#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;
UInt32 len = *btBuf++;
@@ -683,7 +692,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
return len;
}
-UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{
const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++;
@@ -691,6 +700,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
if (len == 0)
{
+ /* change for bt5 ! */
if (p->btNumAvailBytes-- >= 4)
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
}
@@ -706,7 +716,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
*distances2++ = *btBuf++;
}
while ((len -= 2) != 0);
- len = (UInt32)(distances2 - (distances));
+ len = (UInt32)(distances2 - (distances));
}
INCREASE_LZ_POS
return len;
@@ -716,41 +726,41 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
#define SKIP_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_FOOTER_MT
}
-void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(2)
- UInt32 hash2Value;
+ UInt32 h2;
MT_HASH2_CALC
- hash[hash2Value] = p->lzPos;
+ hash[h2] = p->lzPos;
SKIP_FOOTER_MT
}
-void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(3)
- UInt32 hash2Value, hash3Value;
+ UInt32 h2, h3;
MT_HASH3_CALC
- hash[kFix3HashSize + hash3Value] =
- hash[ hash2Value] =
+ hash[kFix3HashSize + h3] =
+ hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
}
/*
-void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(4)
- UInt32 hash2Value, hash3Value, hash4Value;
+ UInt32 h2, h3, h4;
MT_HASH4_CALC
- hash[kFix4HashSize + hash4Value] =
- hash[kFix3HashSize + hash3Value] =
- hash[ hash2Value] =
+ hash[kFix4HashSize + h4] =
+ hash[kFix3HashSize + h3] =
+ hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
}
@@ -759,11 +769,11 @@ void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
- switch(p->MatchFinder->numHashBytes)
+
+ switch (p->MatchFinder->numHashBytes)
{
case 2:
p->GetHeadsFunc = GetHeads2;
@@ -779,7 +789,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
default:
/* case 4: */
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
- /* p->GetHeadsFunc = GetHeads4; */
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
break;
diff --git a/C/LzFindMt.h b/C/LzFindMt.h
index 320d87c..46b6924 100644
--- a/C/LzFindMt.h
+++ b/C/LzFindMt.h
@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2013-01-18 : Igor Pavlov : Public domain */
+2015-05-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H
@@ -75,7 +75,7 @@ typedef struct _CMatchFinderMt
UInt32 matchMaxLen;
UInt32 numHashBytes;
UInt32 pos;
- Byte *buffer;
+ const Byte *buffer;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
UInt32 cutValue;
diff --git a/C/LzHash.h b/C/LzHash.h
index b2f0e3c..2191444 100644
--- a/C/LzHash.h
+++ b/C/LzHash.h
@@ -1,5 +1,5 @@
/* 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
#define __LZ_HASH_H
@@ -12,43 +12,46 @@
#define kFix4HashSize (kHash2Size + kHash3Size)
#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 { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+ h2 = temp & (kHash2Size - 1); \
+ hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
- hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
- hash4Value &= (kHash4Size - 1); }
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ temp ^= (p->crc[cur[3]] << 5); \
+ 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 hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define 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 { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+ h2 = temp & (kHash2Size - 1); \
+ h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
- hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+ h2 = temp & (kHash2Size - 1); \
+ temp ^= ((UInt32)cur[2] << 8); \
+ h3 = temp & (kHash3Size - 1); \
+ h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
#endif
diff --git a/C/Lzma2Dec.c b/C/Lzma2Dec.c
index ed91619..b688457 100644
--- a/C/Lzma2Dec.c
+++ b/C/Lzma2Dec.c
@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder
-2010-12-15 : Igor Pavlov : Public domain */
+2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
@@ -99,12 +99,12 @@ void Lzma2Dec_Init(CLzma2Dec *p)
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{
- switch(p->state)
+ switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->control = b;
- PRF(printf("\n %4X ", p->decoder.dicPos));
- PRF(printf(" %2X", b));
+ PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
+ PRF(printf(" %2X", (unsigned)b));
if (p->control == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
@@ -124,7 +124,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
- PRF(printf(" %8d", p->unpackSize));
+ PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
@@ -134,13 +134,13 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
- PRF(printf(" %8d", p->packSize));
+ PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP:
{
- int lc, lp;
+ unsigned lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
@@ -179,13 +179,16 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
while (p->state != LZMA2_STATE_FINISHED)
{
SizeT dicPos = p->decoder.dicPos;
+
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
+
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
+
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
@@ -195,8 +198,15 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
}
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
+
+ if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
+ {
+ p->state = LZMA2_STATE_ERROR;
+ return SZ_ERROR_DATA;
+ }
continue;
}
+
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
@@ -222,7 +232,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
@@ -231,7 +244,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
@@ -247,17 +263,21 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA)
{
- int mode = LZMA2_GET_LZMA_MODE(p);
+ unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
- Bool initState = (mode > 0);
+ Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = False;
p->needInitState = False;
p->state = LZMA2_STATE_DATA_CONT;
}
+
if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize;
@@ -276,16 +296,22 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (srcSizeCur == 0 && outSizeProcessed == 0)
{
- if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
- p->unpackSize != 0 || p->packSize != 0)
+ if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ || p->unpackSize != 0
+ || p->packSize != 0)
+ {
+ p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
+ }
p->state = LZMA2_STATE_CONTROL;
}
+
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
+
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
diff --git a/C/Lzma2Dec.h b/C/Lzma2Dec.h
index 9254523..026cdef 100644
--- a/C/Lzma2Dec.h
+++ b/C/Lzma2Dec.h
@@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder
-2013-01-18 : Igor Pavlov : Public domain */
+2015-05-13 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
@@ -15,7 +15,7 @@ typedef struct
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
- int state;
+ unsigned state;
Byte control;
Bool needInitDic;
Bool needInitState;
diff --git a/C/Lzma2Enc.c b/C/Lzma2Enc.c
index 1627bae..cba0134 100644
--- a/C/Lzma2Enc.c
+++ b/C/Lzma2Enc.c
@@ -1,5 +1,5 @@
/* Lzma2Enc.c -- LZMA2 Encoder
-2012-06-19 : Igor Pavlov : Public domain */
+2015-10-04 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -109,6 +109,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
{
size_t destPos = 0;
PRF(printf("################# COPY "));
+
while (unpackSize > 0)
{
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
@@ -121,6 +122,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
unpackSize -= u;
destPos += u;
p->srcPos += u;
+
if (outStream)
{
*packSizeRes += destPos;
@@ -132,9 +134,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
*packSizeRes = destPos;
/* needInitState = True; */
}
+
LzmaEnc_RestoreState(p->enc);
return SZ_OK;
}
+
{
size_t destPos = 0;
UInt32 u = unpackSize - 1;
@@ -160,11 +164,13 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
if (outStream)
if (outStream->Write(outStream, outBuf, destPos) != destPos)
return SZ_ERROR_WRITE;
+
*packSizeRes = destPos;
return SZ_OK;
}
}
+
/* ---------- Lzma2 Props ---------- */
void Lzma2EncProps_Init(CLzma2EncProps *p)
@@ -221,6 +227,8 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
LzmaEncProps_Normalize(&p->lzmaProps);
+ t1 = p->lzmaProps.numThreads;
+
if (p->blockSize == 0)
{
UInt32 dictSize = p->lzmaProps.dictSize;
@@ -232,28 +240,34 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
if (blockSize < dictSize) blockSize = dictSize;
p->blockSize = (size_t)blockSize;
}
- if (t2 > 1)
+
+ if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1)
{
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
if (temp > p->lzmaProps.reduceSize)
{
UInt64 numBlocks = temp / p->blockSize;
- if (t2 >= 0 && numBlocks < (UInt64) t2)
+ if (numBlocks < (unsigned)t2)
{
- t2 = (UInt32)numBlocks;
+ t2 = (unsigned)numBlocks;
+ if (t2 == 0)
+ t2 = 1;
t3 = t1 * t2;
}
}
}
+
p->numBlockThreads = t2;
p->numTotalThreads = t3;
}
+
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
{
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
}
+
/* ---------- Lzma2 ---------- */
typedef struct
@@ -283,15 +297,17 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
UInt64 packTotal = 0;
SRes res = SZ_OK;
- if (mainEncoder->outBuf == 0)
+ if (!mainEncoder->outBuf)
{
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
- if (mainEncoder->outBuf == 0)
+ if (!mainEncoder->outBuf)
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;
@@ -305,16 +321,20 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
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
@@ -362,10 +382,12 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
break;
}
}
+
LzmaEnc_Finish(p->enc);
if (res != SZ_OK)
return res;
}
+
if (finished)
{
if (*destSize == destLim)
@@ -378,12 +400,13 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
#endif
+
/* ---------- Lzma2Enc ---------- */
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
- if (p == 0)
+ if (!p)
return NULL;
Lzma2EncProps_Init(&p->props);
Lzma2EncProps_Normalize(&p->props);
@@ -395,6 +418,7 @@ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
p->coders[i].enc = 0;
}
+
#ifndef _7ZIP_ST
MtCoder_Construct(&p->mtCoder);
#endif
@@ -455,22 +479,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
for (i = 0; i < p->props.numBlockThreads; i++)
{
- CLzma2EncInt *t = &p->coders[i];
- if (t->enc == NULL)
+ CLzma2EncInt *t = &p->coders[(unsigned)i];
+ if (!t->enc)
{
t->enc = LzmaEnc_Create(p->alloc);
- if (t->enc == NULL)
+ if (!t->enc)
return SZ_ERROR_MEM;
}
}
#ifndef _7ZIP_ST
- if (p->props.numBlockThreads <= 1)
- #endif
- return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
-
- #ifndef _7ZIP_ST
-
+ if (p->props.numBlockThreads > 1)
{
CMtCallbackImp mtCallback;
@@ -485,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
p->mtCoder.blockSize = p->props.blockSize;
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
+ if (p->mtCoder.destBlockSize < p->props.blockSize)
+ {
+ p->mtCoder.destBlockSize = (size_t)0 - 1;
+ if (p->mtCoder.destBlockSize < p->props.blockSize)
+ return SZ_ERROR_FAIL;
+ }
p->mtCoder.numThreads = p->props.numBlockThreads;
return MtCoder_Code(&p->mtCoder);
}
#endif
+
+ return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
}
diff --git a/C/Lzma86Dec.c b/C/Lzma86Dec.c
index 760a447..20ac5e7 100644
--- a/C/Lzma86Dec.c
+++ b/C/Lzma86Dec.c
@@ -1,5 +1,7 @@
/* 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"
@@ -7,9 +9,6 @@
#include "Bra.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)
{
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)
{
- ISzAlloc g_Alloc = { SzAlloc, SzFree };
SRes res;
int useFilter;
SizeT inSizePure;
diff --git a/C/Lzma86Enc.c b/C/Lzma86Enc.c
index 41b488c..ee59fb7 100644
--- a/C/Lzma86Enc.c
+++ b/C/Lzma86Enc.c
@@ -1,5 +1,7 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
-2009-08-14 : Igor Pavlov : Public domain */
+2016-05-16 : Igor Pavlov : Public domain */
+
+#include "Precomp.h"
#include <string.h>
@@ -11,13 +13,9 @@
#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 level, UInt32 dictSize, int filterMode)
{
- ISzAlloc g_Alloc = { SzAlloc, SzFree };
size_t outSize2 = *destLen;
Byte *filteredStream;
Bool useFilter;
diff --git a/C/LzmaDec.c b/C/LzmaDec.c
index 38cd9d6..64f1164 100644
--- a/C/LzmaDec.c
+++ b/C/LzmaDec.c
@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder
-2015-01-01 : Igor Pavlov : Public domain */
+2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -114,14 +114,14 @@
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+#define LZMA_LIT_SIZE 0x300
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
+#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
@@ -133,8 +133,8 @@ Out:
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
- = kMatchSpecLenStart + 1 : Flush marker
- = kMatchSpecLenStart + 2 : State Init Marker
+ = kMatchSpecLenStart + 1 : Flush marker (unused now)
+ = kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
@@ -172,9 +172,10 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
unsigned symbol;
UPDATE_0(prob);
prob = probs + Literal;
- if (checkDicSize != 0 || processedPos != 0)
- prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
- (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+ if (processedPos != 0 || checkDicSize != 0)
+ prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+ processedPos++;
if (state < kNumLitStates)
{
@@ -195,7 +196,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
else
{
- unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6;
symbol = 1;
@@ -222,11 +223,11 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
#endif
}
+
dic[dicPos++] = (Byte)symbol;
- processedPos++;
continue;
}
- else
+
{
UPDATE_1(prob);
prob = probs + IsRep + state;
@@ -249,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(prob)
{
UPDATE_0(prob);
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
processedPos++;
state = state < kNumLitStates ? 9 : 11;
@@ -290,15 +291,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state = state < kNumLitStates ? 8 : 11;
prob = probs + RepLenCoder;
}
+
+ #ifdef _LZMA_SIZE_OPT
{
- unsigned limit, offset;
+ unsigned lim, offset;
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
- limit = (1 << kLenNumLowBits);
+ lim = (1 << kLenNumLowBits);
}
else
{
@@ -309,19 +312,55 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
- limit = (1 << kLenNumMidBits);
+ lim = (1 << kLenNumMidBits);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
- limit = (1 << kLenNumHighBits);
+ lim = (1 << kLenNumHighBits);
}
}
- TREE_DECODE(probLen, limit, len);
+ TREE_DECODE(probLen, lim, len);
len += offset;
}
+ #else
+ {
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ len = 1;
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ len -= 8;
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ len = 1;
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ TREE_GET_BIT(probLen, len);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
+ len += kLenNumLowSymbols + kLenNumMidSymbols;
+ }
+ }
+ }
+ #endif
if (state >= kNumStates)
{
@@ -332,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (distance >= kStartPosModelIndex)
{
unsigned posSlot = (unsigned)distance;
- int numDirectBits = (int)(((distance >> 1) - 1));
+ unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex)
{
@@ -391,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
}
+
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
@@ -398,26 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (checkDicSize == 0)
{
if (distance >= processedPos)
+ {
+ p->dicPos = dicPos;
return SZ_ERROR_DATA;
+ }
}
else if (distance >= checkDicSize)
+ {
+ p->dicPos = dicPos;
return SZ_ERROR_DATA;
+ }
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
}
len += kMatchMinLen;
- if (limit == dicPos)
- return SZ_ERROR_DATA;
{
- SizeT rem = limit - dicPos;
- unsigned curLen = ((rem < len) ? (unsigned)rem : len);
- SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+ SizeT rem;
+ unsigned curLen;
+ SizeT pos;
+
+ if ((rem = limit - dicPos) == 0)
+ {
+ p->dicPos = dicPos;
+ return SZ_ERROR_DATA;
+ }
+
+ curLen = ((rem < len) ? (unsigned)rem : len);
+ pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
processedPos += curLen;
len -= curLen;
- if (pos + curLen <= dicBufSize)
+ if (curLen <= dicBufSize - pos)
{
Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
@@ -441,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
while (dicPos < limit && buf < bufLimit);
+
NORMALIZE;
+
p->buf = buf;
p->range = range;
p->code = code;
@@ -465,9 +520,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen;
- UInt32 rep0 = p->reps[0];
- if (limit - dicPos < len)
- len = (unsigned)(limit - dicPos);
+ SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
+ SizeT rem = limit - dicPos;
+ if (rem < len)
+ len = (unsigned)(rem);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize;
@@ -477,7 +533,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
while (len != 0)
{
len--;
- dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
}
p->dicPos = dicPos;
@@ -495,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem;
}
+
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
- if (p->processedPos >= p->prop.dicSize)
+
+ if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize;
+
LzmaDec_WriteRem(p, limit);
}
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
- {
p->remainLen = kMatchSpecLenStart;
- }
+
return 0;
}
@@ -522,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range;
UInt32 code = p->code;
const Byte *bufLimit = buf + inSize;
- CLzmaProb *probs = p->probs;
+ const CLzmaProb *probs = p->probs;
unsigned state = p->state;
ELzmaDummy res;
{
- CLzmaProb *prob;
+ const CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
@@ -541,9 +599,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
- prob += (LZMA_LIT_SIZE *
- ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
- (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+ prob += ((UInt32)LZMA_LIT_SIZE *
+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates)
{
@@ -553,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
else
{
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
- ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+ (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
- CLzmaProb *probLit;
+ const CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
@@ -629,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
{
unsigned limit, offset;
- CLzmaProb *probLen = prob + LenChoice;
+ const CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
@@ -669,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
- int numDirectBits = ((posSlot >> 1) - 1);
+ unsigned numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
@@ -708,13 +766,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-{
- p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
- p->range = 0xFFFFFFFF;
- p->needFlush = 0;
-}
-
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
@@ -739,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
- UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
- UInt32 i;
+ SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
+ SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
@@ -762,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{
int checkEndMarkNow;
- if (p->needFlush != 0)
+ if (p->needFlush)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
@@ -773,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
-
- LzmaDec_InitRc(p, p->tempBuf);
+ p->code =
+ ((UInt32)p->tempBuf[1] << 24)
+ | ((UInt32)p->tempBuf[2] << 16)
+ | ((UInt32)p->tempBuf[3] << 8)
+ | ((UInt32)p->tempBuf[4]);
+ p->range = 0xFFFFFFFF;
+ p->needFlush = 0;
p->tempBufSize = 0;
}
@@ -858,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA;
- lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+
+ {
+ unsigned kkk = (unsigned)(p->buf - p->tempBuf);
+ if (rem < kkk)
+ return SZ_ERROR_FAIL; /* some internal error */
+ rem -= kkk;
+ if (lookAhead < rem)
+ return SZ_ERROR_FAIL; /* some internal error */
+ lookAhead -= rem;
+ }
(*srcLen) += lookAhead;
src += lookAhead;
inSize -= lookAhead;
@@ -913,13 +978,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->probs);
- p->probs = 0;
+ p->probs = NULL;
}
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->dic);
- p->dic = 0;
+ p->dic = NULL;
}
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
@@ -957,12 +1022,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
- if (p->probs == 0 || numProbs != p->numProbs)
+ if (!p->probs || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
- if (p->probs == 0)
+ if (!p->probs)
return SZ_ERROR_MEM;
}
return SZ_OK;
@@ -983,12 +1048,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
- dicBufSize = propNew.dicSize;
- if (p->dic == 0 || dicBufSize != p->dicBufSize)
+
+ {
+ UInt32 dictSize = propNew.dicSize;
+ SizeT mask = ((UInt32)1 << 12) - 1;
+ if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
+ else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
+ dicBufSize = ((SizeT)dictSize + mask) & ~mask;
+ if (dicBufSize < dictSize)
+ dicBufSize = dictSize;
+ }
+
+ if (!p->dic || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
- if (p->dic == 0)
+ if (!p->dic)
{
LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM;
diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c
index 40ee6a4..462ca67 100644
--- a/C/LzmaEnc.c
+++ b/C/LzmaEnc.c
@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
-2014-12-29 : Igor Pavlov : Public domain */
+2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -23,6 +23,9 @@
static unsigned g_STAT_OFFSET = 0;
#endif
+#define kMaxHistorySize ((UInt32)3 << 29)
+/* #define kMaxHistorySize ((UInt32)7 << 29) */
+
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
#define kBlockSize (9 << 10)
@@ -58,6 +61,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
int level = p->level;
if (level < 0) level = 5;
p->level = level;
+
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
if (p->dictSize > p->reduceSize)
{
@@ -68,14 +72,17 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
}
}
+
if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
+
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
if (p->numHashBytes < 0) p->numHashBytes = 4;
- if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+
if (p->numThreads < 0)
p->numThreads =
#ifndef _7ZIP_ST
@@ -92,17 +99,18 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
return props.dictSize;
}
+#if (_MSC_VER >= 1400)
+/* BSR code is fast for some new CPUs */
/* #define LZMA_LOG_BSR */
-/* Define it for Intel's CPU */
-
+#endif
#ifdef LZMA_LOG_BSR
-#define kDicLogSizeMaxCompress 30
+#define kDicLogSizeMaxCompress 32
-#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
+#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
-UInt32 GetPosSlot1(UInt32 pos)
+static UInt32 GetPosSlot1(UInt32 pos)
{
UInt32 res;
BSR2_RET(pos, res);
@@ -113,27 +121,44 @@ UInt32 GetPosSlot1(UInt32 pos)
#else
-#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kNumLogBits (9 + sizeof(size_t) / 2)
+/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
+
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-void LzmaEnc_FastPosInit(Byte *g_FastPos)
+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
{
- int c = 2, slotFast;
+ unsigned slot;
g_FastPos[0] = 0;
g_FastPos[1] = 1;
+ g_FastPos += 2;
- for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+ for (slot = 2; slot < kNumLogBits * 2; slot++)
{
- UInt32 k = (1 << ((slotFast >> 1) - 1));
- UInt32 j;
- for (j = 0; j < k; j++, c++)
- g_FastPos[c] = (Byte)slotFast;
+ size_t k = ((size_t)1 << ((slot >> 1) - 1));
+ size_t j;
+ for (j = 0; j < k; j++)
+ g_FastPos[j] = (Byte)slot;
+ g_FastPos += k;
}
}
-#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
+/*
+#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
- res = p->g_FastPos[pos >> i] + (i * 2); }
+ res = p->g_FastPos[pos >> zz] + (zz * 2); }
+*/
+
+/*
+#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
+ res = p->g_FastPos[pos >> zz] + (zz * 2); }
+*/
+
+#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
+ res = p->g_FastPos[pos >> zz] + (zz * 2); }
+
/*
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
p->g_FastPos[pos >> 6] + 12 : \
@@ -213,6 +238,7 @@ typedef struct
#define kNumStates 12
+
typedef struct
{
CLzmaProb choice;
@@ -222,14 +248,16 @@ typedef struct
CLzmaProb high[kLenNumHighSymbols];
} CLenEnc;
+
typedef struct
{
CLenEnc p;
- UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 tableSize;
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 counters[LZMA_NUM_PB_STATES_MAX];
} CLenPriceEnc;
+
typedef struct
{
UInt32 range;
@@ -244,10 +272,14 @@ typedef struct
SRes res;
} CRangeEnc;
+
typedef struct
{
CLzmaProb *litProbs;
+ UInt32 state;
+ UInt32 reps[LZMA_NUM_REPS];
+
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates];
CLzmaProb isRepG0[kNumStates];
@@ -261,15 +293,49 @@ typedef struct
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
-
- UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
} CSaveState;
+
typedef struct
{
- IMatchFinder matchFinder;
void *matchFinderObj;
+ IMatchFinder matchFinder;
+
+ UInt32 optimumEndIndex;
+ UInt32 optimumCurrentIndex;
+
+ UInt32 longestMatchLength;
+ UInt32 numPairs;
+ UInt32 numAvail;
+
+ UInt32 numFastBytes;
+ UInt32 additionalOffset;
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+
+ unsigned lc, lp, pb;
+ unsigned lpMask, pbMask;
+ unsigned lclp;
+
+ CLzmaProb *litProbs;
+
+ Bool fastMode;
+ Bool writeEndMark;
+ Bool finished;
+ Bool multiThread;
+ Bool needInit;
+
+ UInt64 nowPos64;
+
+ UInt32 matchPriceCount;
+ UInt32 alignPriceCount;
+
+ UInt32 distTableSize;
+
+ UInt32 dictSize;
+ SRes result;
+
+ CRangeEnc rc;
#ifndef _7ZIP_ST
Bool mtMode;
@@ -282,12 +348,6 @@ typedef struct
Byte pad[128];
#endif
- UInt32 optimumEndIndex;
- UInt32 optimumCurrentIndex;
-
- UInt32 longestMatchLength;
- UInt32 numPairs;
- UInt32 numAvail;
COptimal opt[kNumOpts];
#ifndef LZMA_LOG_BSR
@@ -296,22 +356,10 @@ typedef struct
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
- UInt32 numFastBytes;
- UInt32 additionalOffset;
- UInt32 reps[LZMA_NUM_REPS];
- UInt32 state;
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
UInt32 alignPrices[kAlignTableSize];
- UInt32 alignPriceCount;
-
- UInt32 distTableSize;
-
- unsigned lc, lp, pb;
- unsigned lpMask, pbMask;
-
- CLzmaProb *litProbs;
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates];
@@ -327,26 +375,14 @@ typedef struct
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
- unsigned lclp;
-
- Bool fastMode;
-
- CRangeEnc rc;
-
- Bool writeEndMark;
- UInt64 nowPos64;
- UInt32 matchPriceCount;
- Bool finished;
- Bool multiThread;
-
- SRes result;
- UInt32 dictSize;
-
- int needInit;
-
CSaveState saveState;
+
+ #ifndef _7ZIP_ST
+ Byte pad2[128];
+ #endif
} CLzmaEnc;
+
void LzmaEnc_SaveState(CLzmaEncHandle pp)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -370,7 +406,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps));
- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
}
void LzmaEnc_RestoreState(CLzmaEncHandle pp)
@@ -396,7 +432,7 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps));
- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
}
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
@@ -405,9 +441,13 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
CLzmaEncProps props = *props2;
LzmaEncProps_Normalize(&props);
- if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
- props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
+ if (props.lc > LZMA_LC_MAX
+ || props.lp > LZMA_LP_MAX
+ || props.pb > LZMA_PB_MAX
+ || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
+ || props.dictSize > kMaxHistorySize)
return SZ_ERROR_PARAM;
+
p->dictSize = props.dictSize;
{
unsigned fb = props.fb;
@@ -421,7 +461,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->lp = props.lp;
p->pb = props.pb;
p->fastMode = (props.algo == 0);
- p->matchFinderBase.btMode = props.btMode;
+ p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
{
UInt32 numHashBytes = 4;
if (props.btMode)
@@ -465,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11,
static void RangeEnc_Construct(CRangeEnc *p)
{
- p->outStream = 0;
- p->bufBase = 0;
+ p->outStream = NULL;
+ p->bufBase = NULL;
}
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
@@ -474,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p)
#define RC_BUF_SIZE (1 << 16)
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
{
- if (p->bufBase == 0)
+ if (!p->bufBase)
{
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
- if (p->bufBase == 0)
+ if (!p->bufBase)
return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE;
}
@@ -607,7 +647,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol,
while (symbol < 0x10000);
}
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
{
UInt32 i;
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
@@ -643,7 +683,7 @@ void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= 0x100;
@@ -656,7 +696,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro
return price;
}
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 offs = 0x100;
@@ -700,7 +740,7 @@ static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLeve
}
}
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= (1 << numBitLevels);
@@ -712,7 +752,7 @@ static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 s
return price;
}
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 m = 1;
@@ -763,7 +803,7 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posSt
}
}
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)
{
UInt32 a0 = GET_PRICE_0a(p->choice);
UInt32 a1 = GET_PRICE_1a(p->choice);
@@ -786,20 +826,20 @@ static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UIn
prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
}
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)
{
LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
p->counters[posState] = p->tableSize;
}
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)
{
UInt32 posState;
for (posState = 0; posState < numPosStates; posState++)
LenPriceEnc_UpdateTable(p, posState, ProbPrices);
}
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)
{
LenEnc_Encode(&p->p, rc, symbol, posState);
if (updatePrice)
@@ -814,7 +854,7 @@ static void MovePos(CLzmaEnc *p, UInt32 num)
{
#ifdef SHOW_STAT
g_STAT_OFFSET += num;
- printf("\n MovePos %d", num);
+ printf("\n MovePos %u", num);
#endif
if (num != 0)
@@ -831,12 +871,12 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
#ifdef SHOW_STAT
- printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2);
+ printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
g_STAT_OFFSET++;
{
UInt32 i;
for (i = 0; i < numPairs; i += 2)
- printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
+ printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
}
#endif
@@ -845,14 +885,16 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
lenRes = p->matches[numPairs - 2];
if (lenRes == p->numFastBytes)
{
- const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
- UInt32 distance = p->matches[numPairs - 1] + 1;
UInt32 numAvail = p->numAvail;
if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX;
{
- const Byte *pby2 = pby - distance;
- for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+ const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ const Byte *pby = pbyCur + lenRes;
+ ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
+ const Byte *pbyLim = pbyCur + numAvail;
+ for (; pby != pbyLim && *pby == pby[dif]; pby++);
+ lenRes = (UInt32)(pby - pbyCur);
}
}
}
@@ -937,16 +979,21 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
return p->optimumCurrentIndex;
}
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{
- UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
- UInt32 matchPrice, repMatchPrice, normalMatchPrice;
+ UInt32 lenEnd, cur;
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
UInt32 *matches;
+
+ {
+
+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
+ UInt32 matchPrice, repMatchPrice, normalMatchPrice;
const Byte *data;
Byte curByte, matchByte;
+
if (p->optimumEndIndex != p->optimumCurrentIndex)
{
const COptimal *opt = &p->opt[p->optimumCurrentIndex];
@@ -981,7 +1028,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest;
const Byte *data2;
reps[i] = p->reps[i];
- data2 = data - (reps[i] + 1);
+ data2 = data - reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
{
repLens[i] = 0;
@@ -1125,17 +1172,20 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
cur = 0;
#ifdef SHOW_STAT2
- if (position >= 0)
+ /* if (position >= 0) */
{
unsigned i;
printf("\n pos = %4X", position);
for (i = cur; i <= lenEnd; i++)
- printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
+ printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
}
#endif
+ }
+
for (;;)
{
+ UInt32 numAvail;
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
Bool nextIsChar;
@@ -1282,7 +1332,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
/* try Literal + rep0 */
UInt32 temp;
UInt32 lenTest2;
- const Byte *data2 = data - (reps[0] + 1);
+ const Byte *data2 = data - reps[0] - 1;
UInt32 limit = p->numFastBytes + 1;
if (limit > numAvailFull)
limit = numAvailFull;
@@ -1325,7 +1375,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest;
UInt32 lenTestTemp;
UInt32 price;
- const Byte *data2 = data - (reps[repIndex] + 1);
+ const Byte *data2 = data - reps[repIndex] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
@@ -1355,13 +1405,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{
UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes;
- UInt32 nextRepMatchPrice;
if (limit > numAvailFull)
limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1;
if (lenTest2 >= 2)
{
+ UInt32 nextRepMatchPrice;
UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice =
@@ -1423,6 +1473,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
for (lenTest = /*2*/ startLen; ; lenTest++)
{
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+ {
UInt32 lenToPosState = GetLenToPosState(lenTest);
COptimal *opt;
if (curBack < kNumFullDistances)
@@ -1438,20 +1489,21 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
opt->backPrev = curBack + LZMA_NUM_REPS;
opt->prev1IsChar = False;
}
+ }
if (/*_maxMode && */lenTest == matches[offs])
{
/* Try Match + Literal + Rep0 */
- const Byte *data2 = data - (curBack + 1);
+ const Byte *data2 = data - curBack - 1;
UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes;
- UInt32 nextRepMatchPrice;
if (limit > numAvailFull)
limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1;
if (lenTest2 >= 2)
{
+ UInt32 nextRepMatchPrice;
UInt32 state2 = kMatchNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice +
@@ -1467,15 +1519,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
/* for (; lenTest2 >= 2; lenTest2--) */
{
UInt32 offset = cur + lenTest + 1 + lenTest2;
- UInt32 curAndLenPrice;
+ UInt32 curAndLenPrice2;
COptimal *opt;
while (lenEnd < offset)
p->opt[++lenEnd].price = kInfinityPrice;
- curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
opt = &p->opt[offset];
- if (curAndLenPrice < opt->price)
+ if (curAndLenPrice2 < opt->price)
{
- opt->price = curAndLenPrice;
+ opt->price = curAndLenPrice2;
opt->posPrev = cur + lenTest + 1;
opt->backPrev = 0;
opt->prev1IsChar = True;
@@ -1525,7 +1577,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++)
{
UInt32 len;
- const Byte *data2 = data - (p->reps[i] + 1);
+ const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (len = 2; len < numAvail && data[len] == data2[len]; len++);
@@ -1594,7 +1646,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++)
{
UInt32 len, limit;
- const Byte *data2 = data - (p->reps[i] + 1);
+ const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
limit = mainLen - 1;
@@ -1676,7 +1728,6 @@ static void FillDistancesPrices(CLzmaEnc *p)
{
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
- UInt32 i;
for (i = 0; i < kStartPosModelIndex; i++)
distancesPrices[i] = posSlotPrices[i];
for (; i < kNumFullDistances; i++)
@@ -1690,6 +1741,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
{
RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase);
+
#ifndef _7ZIP_ST
MatchFinderMt_Construct(&p->matchFinderMt);
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
@@ -1706,15 +1758,15 @@ void LzmaEnc_Construct(CLzmaEnc *p)
#endif
LzmaEnc_InitPriceTables(p->ProbPrices);
- p->litProbs = 0;
- p->saveState.litProbs = 0;
+ p->litProbs = NULL;
+ p->saveState.litProbs = NULL;
}
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
{
void *p;
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
- if (p != 0)
+ if (p)
LzmaEnc_Construct((CLzmaEnc *)p);
return p;
}
@@ -1723,8 +1775,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->litProbs);
alloc->Free(alloc, p->saveState.litProbs);
- p->litProbs = 0;
- p->saveState.litProbs = 0;
+ p->litProbs = NULL;
+ p->saveState.litProbs = NULL;
}
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
@@ -1732,6 +1784,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
#ifndef _7ZIP_ST
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
#endif
+
MatchFinder_Free(&p->matchFinderBase, allocBig);
LzmaEnc_FreeLits(p, alloc);
RangeEnc_Free(&p->rc, alloc);
@@ -1768,7 +1821,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
ReadMatchDistances(p, &numPairs);
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
p->state = kLiteralNextStates[p->state];
- curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
+ curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
LitEnc_Encode(&p->rc, p->litProbs, curByte);
p->additionalOffset--;
nowPos32++;
@@ -1785,7 +1838,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
len = GetOptimum(p, nowPos32, &pos);
#ifdef SHOW_STAT2
- printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
+ printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
#endif
posState = nowPos32 & p->pbMask;
@@ -1894,7 +1947,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
break;
}
- else if (processed >= (1 << 15))
+ else if (processed >= (1 << 17))
{
p->nowPos64 += nowPos32 - startPos32;
return CheckErrors(p);
@@ -1912,18 +1965,19 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
UInt32 beforeSize = kNumOpts;
if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM;
+
#ifndef _7ZIP_ST
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
#endif
{
unsigned lclp = p->lc + p->lp;
- if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+ if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
{
LzmaEnc_FreeLits(p, alloc);
- p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
- p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
- if (p->litProbs == 0 || p->saveState.litProbs == 0)
+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+ if (!p->litProbs || !p->saveState.litProbs)
{
LzmaEnc_FreeLits(p, alloc);
return SZ_ERROR_MEM;
@@ -1932,7 +1986,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
}
}
- p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+ p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
if (beforeSize + p->dictSize < keepWindowSize)
beforeSize = keepWindowSize - p->dictSize;
@@ -1952,6 +2006,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
p->matchFinderObj = &p->matchFinderBase;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
}
+
return SZ_OK;
}
@@ -1980,9 +2035,10 @@ void LzmaEnc_Init(CLzmaEnc *p)
}
{
- UInt32 num = 0x300 << (p->lp + p->lc);
+ UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
+ CLzmaProb *probs = p->litProbs;
for (i = 0; i < num; i++)
- p->litProbs[i] = kProbInitValue;
+ probs[i] = kProbInitValue;
}
{
@@ -2089,10 +2145,11 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
if (p->mtMode)
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
#else
- pp = pp;
+ UNUSED_VAR(pp);
#endif
}
+
typedef struct
{
ISeqOutStream funcTable;
@@ -2122,12 +2179,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
}
+
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
{
const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
}
+
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
{
@@ -2162,6 +2221,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
return res;
}
+
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
{
SRes res = SZ_OK;
@@ -2175,9 +2235,9 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
for (;;)
{
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
- if (res != SZ_OK || p->finished != 0)
+ if (res != SZ_OK || p->finished)
break;
- if (progress != 0)
+ if (progress)
{
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK)
@@ -2187,10 +2247,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
}
}
}
+
LzmaEnc_Finish(p);
+
+ /*
+ if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
+ res = SZ_ERROR_FAIL;
+ }
+ */
+
return res;
}
+
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
ISzAlloc *alloc, ISzAlloc *allocBig)
{
@@ -2198,28 +2267,27 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
}
+
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
- int i;
+ unsigned i;
UInt32 dictSize = p->dictSize;
if (*size < LZMA_PROPS_SIZE)
return SZ_ERROR_PARAM;
*size = LZMA_PROPS_SIZE;
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
- for (i = 11; i <= 30; i++)
+ if (dictSize >= ((UInt32)1 << 22))
{
- if (dictSize <= ((UInt32)2 << i))
- {
- dictSize = (2 << i);
- break;
- }
- if (dictSize <= ((UInt32)3 << i))
- {
- dictSize = (3 << i);
- break;
- }
+ UInt32 kDictMask = ((UInt32)1 << 20) - 1;
+ if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
+ dictSize = (dictSize + kDictMask) & ~kDictMask;
+ }
+ else for (i = 11; i <= 30; i++)
+ {
+ if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; }
+ if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; }
}
for (i = 0; i < 4; i++)
@@ -2227,6 +2295,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
return SZ_OK;
}
+
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{
@@ -2235,19 +2304,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
CSeqOutStreamBuf outStream;
- LzmaEnc_SetInputBuf(p, src, srcLen);
-
outStream.funcTable.Write = MyWrite;
outStream.data = dest;
outStream.rem = *destLen;
outStream.overflow = False;
p->writeEndMark = writeEndMark;
-
p->rc.outStream = &outStream.funcTable;
+
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
+
if (res == SZ_OK)
+ {
res = LzmaEnc_Encode2(p, progress);
+ if (res == SZ_OK && p->nowPos64 != srcLen)
+ res = SZ_ERROR_FAIL;
+ }
*destLen -= outStream.rem;
if (outStream.overflow)
@@ -2255,13 +2327,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
return res;
}
+
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
SRes res;
- if (p == 0)
+ if (!p)
return SZ_ERROR_MEM;
res = LzmaEnc_SetProps(p, props);
diff --git a/C/LzmaLib.c b/C/LzmaLib.c
index 3e3cf40..c10cf1a 100644
--- a/C/LzmaLib.c
+++ b/C/LzmaLib.c
@@ -1,18 +1,12 @@
/* LzmaLib.c -- LZMA library wrapper
-2008-08-05
-Igor Pavlov
-Public domain */
+2015-06-13 : Igor Pavlov : Public domain */
-#include "LzmaEnc.h"
-#include "LzmaDec.h"
#include "Alloc.h"
+#include "LzmaDec.h"
+#include "LzmaEnc.h"
#include "LzmaLib.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); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
-MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
+MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize,
int level, /* 0 <= level <= 9, default = 5 */
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)
{
ELzmaStatus status;
diff --git a/C/MtCoder.c b/C/MtCoder.c
index 303b435..8c0d9b3 100644
--- a/C/MtCoder.c
+++ b/C/MtCoder.c
@@ -1,10 +1,8 @@
/* MtCoder.c -- Multi-thread Coder
-2010-09-24 : Igor Pavlov : Public domain */
+2015-10-13 : Igor Pavlov : Public domain */
#include "Precomp.h"
-#include <stdio.h>
-
#include "MtCoder.h"
void LoopThread_Construct(CLoopThread *p)
@@ -120,7 +118,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
LoopThread_Construct(&p->thread);
}
-#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }
+#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
static void CMtThread_CloseEvents(CMtThread *p)
{
diff --git a/C/Ppmd.h b/C/Ppmd.h
index 25ce2d2..e807ca1 100644
--- a/C/Ppmd.h
+++ b/C/Ppmd.h
@@ -1,5 +1,5 @@
/* Ppmd.h -- PPMD codec common code
-2013-01-18 : Igor Pavlov : Public domain
+2016-05-16 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H
@@ -77,8 +77,8 @@ typedef
CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \
- { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 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; }}
+ { unsigned z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
+ p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END
diff --git a/C/Ppmd7.c b/C/Ppmd7.c
index 798c118..ba5d329 100644
--- a/C/Ppmd7.c
+++ b/C/Ppmd7.c
@@ -1,10 +1,10 @@
/* Ppmd7.c -- PPMdH codec
-2010-03-12 : Igor Pavlov : Public domain
+2016-05-21 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
-#include <memory.h>
+#include <string.h>
#include "Ppmd7.h"
@@ -66,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{
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;
}
@@ -257,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
#define MyMem12Cpy(dest, src, 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)
{
@@ -639,10 +639,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256)
{
- see = p->See[p->NS2Indx[nonMasked - 1]] +
+ see = p->See[(unsigned)p->NS2Indx[nonMasked - 1]] +
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
- 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
- 4 * (numMasked > nonMasked) +
+ 2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
+ 4 * (unsigned)(numMasked > nonMasked) +
p->HiBitsFlag;
{
unsigned r = (see->Summ >> see->Shift);
diff --git a/C/Ppmd7.h b/C/Ppmd7.h
index 56e81eb..1c7870c 100644
--- a/C/Ppmd7.h
+++ b/C/Ppmd7.h
@@ -1,5 +1,5 @@
/* Ppmd7.h -- PPMdH compression codec
-2010-03-12 : Igor Pavlov : Public domain
+2016-05-21 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation
@@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \
- &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
+ &p->BinSumm[(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(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)]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
diff --git a/C/Ppmd7Enc.c b/C/Ppmd7Enc.c
index d82ea90..9b49e5d 100644
--- a/C/Ppmd7Enc.c
+++ b/C/Ppmd7Enc.c
@@ -1,5 +1,5 @@
/* Ppmd7Enc.c -- PPMdH Encoder
-2010-03-12 : Igor Pavlov : Public domain
+2015-09-28 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Precomp.h"
@@ -26,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
temp = 0xFF;
}
- while(--p->CacheSize != 0);
+ while (--p->CacheSize != 0);
p->Cache = (Byte)((UInt32)p->Low >> 24);
}
p->CacheSize++;
diff --git a/C/RotateDefs.h b/C/RotateDefs.h
index ad7d164..6c790e7 100644
--- a/C/RotateDefs.h
+++ b/C/RotateDefs.h
@@ -1,5 +1,5 @@
/* RotateDefs.h -- Rotate functions
-2013-11-12 : Igor Pavlov : Public domain */
+2015-03-25 : Igor Pavlov : Public domain */
#ifndef __ROTATE_DEFS_H
#define __ROTATE_DEFS_H
@@ -8,16 +8,20 @@
#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(_rotr)
-// #endif
+/* #endif */
#define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n))
#else
+/* new compilers can translate these macros to fast commands. */
+
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
diff --git a/C/Sha256.c b/C/Sha256.c
index 91208d3..47e2f42 100644
--- a/C/Sha256.c
+++ b/C/Sha256.c
@@ -1,14 +1,21 @@
/* Crypto/Sha256.c -- SHA-256 Hash
-2010-06-11 : Igor Pavlov : Public domain
+2015-11-14 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h"
+#include <string.h>
+
+#include "CpuArch.h"
#include "RotateDefs.h"
#include "Sha256.h"
/* define it for speed optimization */
-/* #define _SHA256_UNROLL */
+#ifndef _SFX
+#define _SHA256_UNROLL
+#define _SHA256_UNROLL2
+#endif
+
/* #define _SHA256_UNROLL2 */
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 s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
-#define blk0(i) (W[i] = data[i])
-#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
+#define blk0(i) (W[i])
+#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z)))
#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
-#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));\
- d += h; h += S0(a) + Maj(a, b, c)
+#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)); \
+ d += h; \
+ h += S0(a) + Maj(a, b, c)
#define RX_8(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(b,c,d,e,f,g,h,a, i+7)
+#define RX_16 RX_8(0); RX_8(8);
+
#else
-#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
- d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+#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]
+
+#define R(i) \
+ h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
+ d(i) += h(i); \
+ h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
#ifdef _SHA256_UNROLL
-#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
@@ -92,12 +109,30 @@ static const UInt32 K[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
-static void Sha256_Transform(UInt32 *state, const UInt32 *data)
+static void Sha256_WriteByteBlock(CSha256 *p)
{
UInt32 W[16];
unsigned j;
+ UInt32 *state;
+
#ifdef _SHA256_UNROLL2
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];
b = state[1];
c = state[2];
@@ -107,19 +142,13 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
g = state[6];
h = state[7];
#else
- UInt32 T[8];
for (j = 0; j < 8; j++)
T[j] = state[j];
#endif
for (j = 0; j < 64; j += 16)
{
- #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
- RX_8(0); RX_8(8);
- #else
- unsigned i;
- for (i = 0; i < 16; i++) { R(i); }
- #endif
+ RX_16
}
#ifdef _SHA256_UNROLL2
@@ -146,61 +175,74 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
#undef s0
#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)
{
- UInt32 curBufferPos = (UInt32)p->count & 0x3F;
- while (size > 0)
+ if (size == 0)
+ return;
+
{
- p->buffer[curBufferPos++] = *data++;
- p->count++;
- size--;
- if (curBufferPos == 64)
+ unsigned pos = (unsigned)p->count & 0x3F;
+ unsigned num;
+
+ p->count += size;
+
+ num = 64 - pos;
+ if (num > size)
{
- curBufferPos = 0;
- Sha256_WriteByteBlock(p);
+ memcpy(p->buffer + pos, data, size);
+ 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)
{
- UInt64 lenInBits = (p->count << 3);
- UInt32 curBufferPos = (UInt32)p->count & 0x3F;
+ unsigned pos = (unsigned)p->count & 0x3F;
unsigned i;
- p->buffer[curBufferPos++] = 0x80;
- while (curBufferPos != (64 - 8))
+
+ p->buffer[pos++] = 0x80;
+
+ while (pos != (64 - 8))
{
- curBufferPos &= 0x3F;
- if (curBufferPos == 0)
+ pos &= 0x3F;
+ if (pos == 0)
Sha256_WriteByteBlock(p);
- p->buffer[curBufferPos++] = 0;
+ p->buffer[pos++] = 0;
}
- for (i = 0; i < 8; i++)
+
{
- p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
- lenInBits <<= 8;
+ UInt64 numBits = (p->count << 3);
+ SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
+ SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
}
+
Sha256_WriteByteBlock(p);
- for (i = 0; i < 8; i++)
+ for (i = 0; i < 8; i += 2)
{
- *digest++ = (Byte)(p->state[i] >> 24);
- *digest++ = (Byte)(p->state[i] >> 16);
- *digest++ = (Byte)(p->state[i] >> 8);
- *digest++ = (Byte)(p->state[i]);
+ UInt32 v0 = p->state[i];
+ UInt32 v1 = p->state[i + 1];
+ SetBe32(digest , v0);
+ SetBe32(digest + 4, v1);
+ digest += 8;
}
+
Sha256_Init(p);
}
diff --git a/C/Threads.c b/C/Threads.c
index 18ba1e8..ece07e6 100644
--- a/C/Threads.c
+++ b/C/Threads.c
@@ -1,9 +1,9 @@
/* Threads.c -- multithreading library
-2013-11-12 : Igor Pavlov : Public domain */
+2014-09-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
-#ifndef _WIN32_WCE
+#ifndef UNDER_CE
#include <process.h>
#endif
diff --git a/C/Util/7z/7z.dsp b/C/Util/7z/7z.dsp
index 73122f7..d3bf0fe 100644
--- a/C/Util/7z/7z.dsp
+++ b/C/Util/7z/7z.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /Yu"Precomp.h" /FD /c
+# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -165,6 +165,10 @@ SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
+SOURCE=..\..\BraIA64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
@@ -173,6 +177,14 @@ SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
+SOURCE=..\..\Delta.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Delta.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
index 736a7fe..92bce0a 100644
--- a/C/Util/7z/7zMain.c
+++ b/C/Util/7z/7zMain.c
@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder
-2015-01-02 : Igor Pavlov : Public domain */
+2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -34,75 +34,117 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
}
#ifndef _WIN32
+#define _USE_UTF8
+#endif
+
+/* #define _USE_UTF8 */
+
+#ifdef _USE_UTF8
+
+#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
-static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
-static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
+#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 (;;)
{
- unsigned numAdds;
- UInt32 value;
- if (srcPos == srcLen)
+ UInt32 val;
+ if (src == srcLim)
+ return size;
+
+ size++;
+ val = *src++;
+
+ if (val < 0x80)
+ continue;
+
+ if (val < _UTF8_RANGE(1))
+ {
+ size++;
+ continue;
+ }
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
- *destLen = destPos;
- return True;
+ UInt32 c2 = *src;
+ if (c2 >= 0xDC00 && c2 < 0xE000)
+ {
+ src++;
+ size += 3;
+ continue;
+ }
}
- value = src[srcPos++];
- if (value < 0x80)
+
+ size += 2;
+ }
+}
+
+static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
+{
+ for (;;)
+ {
+ UInt32 val;
+ if (src == srcLim)
+ return dest;
+
+ val = *src++;
+
+ if (val < 0x80)
{
- if (dest)
- dest[destPos] = (char)value;
- destPos++;
+ *dest++ = (char)val;
continue;
}
- if (value >= 0xD800 && value < 0xE000)
+
+ if (val < _UTF8_RANGE(1))
{
- UInt32 c2;
- if (value >= 0xDC00 || srcPos == srcLen)
- break;
- c2 = src[srcPos++];
- if (c2 < 0xDC00 || c2 >= 0xE000)
- break;
- value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
+ dest[0] = _UTF8_HEAD(1, val);
+ dest[1] = _UTF8_CHAR(0, val);
+ dest += 2;
+ continue;
}
- for (numAdds = 1; numAdds < 5; numAdds++)
- if (value < (((UInt32)1) << (numAdds * 5 + 6)))
- break;
- if (dest)
- dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
- destPos++;
- do
+
+ if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
- numAdds--;
- if (dest)
- dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
- destPos++;
+ 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;
+ }
}
- while (numAdds != 0);
+
+ 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)
{
- size_t destLen = 0;
- Bool res;
- Utf16_To_Utf8(NULL, &destLen, src, srcLen);
+ size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
destLen += 1;
if (!Buf_EnsureSize(dest, destLen))
return SZ_ERROR_MEM;
- res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
- dest->data[destLen] = 0;
- return res ? SZ_OK : SZ_ERROR_FAIL;
+ *Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
+ return SZ_OK;
}
#endif
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
- #ifdef _WIN32
+ #ifndef _USE_UTF8
, UINT codePage
#endif
)
@@ -110,7 +152,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
unsigned len = 0;
for (len = 0; s[len] != 0; len++);
- #ifdef _WIN32
+ #ifndef _USE_UTF8
{
unsigned size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size))
@@ -191,7 +233,7 @@ static SRes PrintString(const UInt16 *s)
SRes res;
Buf_Init(&buf);
res = Utf16_To_Char(&buf, s
- #ifdef _WIN32
+ #ifndef _USE_UTF8
, CP_OEMCP
#endif
);
@@ -268,10 +310,10 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
ms[1] = 29;
for (mon = 0;; mon++)
{
- unsigned s = ms[mon];
- if (v < s)
+ unsigned d = ms[mon];
+ if (v < d)
break;
- v -= s;
+ v -= d;
}
s = UIntToStr(s, year, 4); *s++ = '-';
UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
@@ -281,27 +323,25 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
UIntToStr_2(s, sec); s[2] = 0;
}
-void PrintError(const char *sz)
+void PrintError(char *sz)
{
printf("\nERROR: %s\n", sz);
}
-#ifdef USE_WINDOWS_FILE
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
{
+ #ifdef USE_WINDOWS_FILE
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
- s[5] = '\0';
-}
-#else
-static void GetAttribString(UInt32, Bool, char *s)
-{
- s[0] = '\0';
+ s[5] = 0;
+ #else
+ s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.');
+ s[1] = 0;
+ #endif
}
-#endif
// #define NUM_PARENTS_MAX 128
@@ -318,6 +358,7 @@ int MY_CDECL main(int numargs, char *args[])
// UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
+
if (numargs == 1)
{
printf(
@@ -329,6 +370,7 @@ int MY_CDECL main(int numargs, char *args[])
" x: eXtract files with full paths\n");
return 0;
}
+
if (numargs < 3)
{
PrintError("incorrect command");
@@ -364,11 +406,14 @@ int MY_CDECL main(int numargs, char *args[])
CrcGenerateTable();
SzArEx_Init(&db);
+
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
+
if (res == SZ_OK)
{
char *command = args[1];
int listCommand = 0, testCommand = 0, fullPaths = 0;
+
if (strcmp(command, "l") == 0) listCommand = 1;
else if (strcmp(command, "t") == 0) testCommand = 1;
else if (strcmp(command, "e") == 0) { }
@@ -397,7 +442,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t outSizeProcessed = 0;
// const CSzFileItem *f = db.Files + i;
size_t len;
- int isDir = SzArEx_IsDir(&db, i);
+ unsigned isDir = SzArEx_IsDir(&db, i);
if (listCommand == 0 && isDir && !fullPaths)
continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
@@ -433,6 +478,7 @@ int MY_CDECL main(int numargs, char *args[])
fileSize = SzArEx_GetFileSize(&db, i);
UInt64ToStr(fileSize, s);
+
if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t);
else
@@ -452,6 +498,7 @@ int MY_CDECL main(int numargs, char *args[])
printf("\n");
continue;
}
+
fputs(testCommand ?
"Testing ":
"Extracting ",
@@ -459,6 +506,7 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp);
if (res != SZ_OK)
break;
+
if (isDir)
printf("/");
else
@@ -470,6 +518,7 @@ int MY_CDECL main(int numargs, char *args[])
if (res != SZ_OK)
break;
}
+
if (!testCommand)
{
CSzFile outFile;
@@ -477,6 +526,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t j;
UInt16 *name = (UInt16 *)temp;
const UInt16 *destPath = (const UInt16 *)name;
+
for (j = 0; name[j] != 0; j++)
if (name[j] == '/')
{
@@ -502,19 +552,23 @@ int MY_CDECL main(int numargs, char *args[])
res = SZ_ERROR_FAIL;
break;
}
+
processedSize = outSizeProcessed;
+
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZ_ERROR_FAIL;
break;
}
+
if (File_Close(&outFile))
{
PrintError("can not close output file");
res = SZ_ERROR_FAIL;
break;
}
+
#ifdef USE_WINDOWS_FILE
if (SzBitWithVals_Check(&db.Attribs, i))
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
@@ -525,15 +579,18 @@ int MY_CDECL main(int numargs, char *args[])
IAlloc_Free(&allocImp, outBuffer);
}
}
+
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
File_Close(&archiveStream.file);
+
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}
+
if (res == SZ_ERROR_UNSUPPORTED)
PrintError("decoder doesn't support this archive");
else if (res == SZ_ERROR_MEM)
@@ -542,5 +599,6 @@ int MY_CDECL main(int numargs, char *args[])
PrintError("CRC error");
else
printf("\nERROR #%d\n", res);
+
return 1;
}
diff --git a/C/Util/7z/makefile b/C/Util/7z/makefile
index 08e6f68..f4a54af 100644
--- a/C/Util/7z/makefile
+++ b/C/Util/7z/makefile
@@ -1,4 +1,3 @@
-# MY_STATIC_LINK=1
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe
@@ -15,7 +14,9 @@ C_OBJS = \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
+ $O\BraIA64.obj \
$O\CpuArch.obj \
+ $O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
$O\Ppmd7.obj \
diff --git a/C/Util/7z/makefile.gcc b/C/Util/7z/makefile.gcc
index 63c59ca..f707935 100644
--- a/C/Util/7z/makefile.gcc
+++ b/C/Util/7z/makefile.gcc
@@ -1,10 +1,10 @@
PROG = 7zDec
-CXX = g++
+CXX = gcc
LIB =
RM = rm -f
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)
@@ -38,6 +38,9 @@ $(PROG): $(OBJS)
CpuArch.o: ../../CpuArch.c
$(CXX) $(CFLAGS) ../../CpuArch.c
+Delta.o: ../../Delta.c
+ $(CXX) $(CFLAGS) ../../Delta.c
+
LzmaDec.o: ../../LzmaDec.c
$(CXX) $(CFLAGS) ../../LzmaDec.c
@@ -50,6 +53,9 @@ Bra.o: ../../Bra.c
Bra86.o: ../../Bra86.c
$(CXX) $(CFLAGS) ../../Bra86.c
+BraIA64.o: ../../BraIA64.c
+ $(CXX) $(CFLAGS) ../../BraIA64.c
+
Bcj2.o: ../../Bcj2.c
$(CXX) $(CFLAGS) ../../Bcj2.c
@@ -67,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
clean:
-$(RM) $(PROG) $(OBJS)
-
diff --git a/C/Util/Lzma/LzmaUtil.c b/C/Util/Lzma/LzmaUtil.c
index ee659ba..98331b4 100644
--- a/C/Util/Lzma/LzmaUtil.c
+++ b/C/Util/Lzma/LzmaUtil.c
@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression
-2014-12-31 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
#include "../../Precomp.h"
@@ -18,10 +18,6 @@ const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
const char *kDataErrorMessage = "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); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
void PrintHelp(char *buffer)
{
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
@@ -137,7 +133,7 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
SRes res;
CLzmaEncProps props;
- rs = rs;
+ UNUSED_VAR(rs);
enc = LzmaEnc_Create(&g_Alloc);
if (enc == 0)
diff --git a/C/Util/LzmaLib/LzmaLibExports.c b/C/Util/LzmaLib/LzmaLibExports.c
index 7434536..02600c7 100644
--- a/C/Util/LzmaLib/LzmaLibExports.c
+++ b/C/Util/LzmaLib/LzmaLibExports.c
@@ -1,12 +1,14 @@
/* LzmaLibExports.c -- LZMA library DLL Entry point
-2008-10-04 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
+
+#include "../../Precomp.h"
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
- hInstance = hInstance;
- dwReason = dwReason;
- lpReserved = lpReserved;
+ UNUSED_VAR(hInstance);
+ UNUSED_VAR(dwReason);
+ UNUSED_VAR(lpReserved);
return TRUE;
}
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
index 5714e43..50e57ae 100644
--- a/C/Util/SfxSetup/SfxSetup.c
+++ b/C/Util/SfxSetup/SfxSetup.c
@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup
-2014-12-07 : Igor Pavlov : Public domain */
+2016-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -20,10 +20,11 @@
#include "../../7zCrc.h"
#include "../../7zFile.h"
#include "../../CpuArch.h"
+#include "../../DllSecur.h"
#define k_EXE_ExtIndex 2
-static const char *kExts[] =
+static const char * const kExts[] =
{
"bat"
, "cmd"
@@ -37,7 +38,7 @@ static const char *kExts[] =
, "htm"
};
-static const char *kNames[] =
+static const char * const kNames[] =
{
"setup"
, "install"
@@ -63,7 +64,7 @@ static unsigned FindExt(const wchar_t *s, unsigned *extLen)
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
-static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)
+static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len)
{
unsigned i;
for (i = 0; i < num; i++)
@@ -75,7 +76,7 @@ static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, uns
continue;
for (j = 0; j < len; j++)
{
- unsigned c = item[j];
+ unsigned c = (Byte)item[j];
if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
break;
}
@@ -88,7 +89,7 @@ static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, uns
#ifdef _CONSOLE
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{
- ctrlType = ctrlType;
+ UNUSED_VAR(ctrlType);
return TRUE;
}
#endif
@@ -144,7 +145,7 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++)
{
- for (; buf[pos] != '7' && pos <= processed; pos++);
+ for (; pos <= processed && buf[pos] != '7'; pos++);
if (pos > processed)
break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
@@ -182,6 +183,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
path[len] = L'\0';
if (handle == INVALID_HANDLE_VALUE)
return GetLastError();
+
for (;;)
{
if (wcscmp(fd.cFileName, L".") != 0 &&
@@ -199,9 +201,11 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
if (DeleteFileW(path) == 0)
res = GetLastError();
}
+
if (res != 0)
break;
}
+
if (!FindNextFileW(handle, &fd))
{
res = GetLastError();
@@ -210,6 +214,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
break;
}
}
+
path[len] = L'\0';
FindClose(handle);
if (res == 0)
@@ -248,14 +253,17 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
const wchar_t *cmdLineParams;
const char *errorMessage = NULL;
Bool useShellExecute = True;
+ DWORD exitCode = 0;
+
+ LoadSecurityDlls();
#ifdef _CONSOLE
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else
- hInstance = hInstance;
- hPrevInstance = hPrevInstance;
- lpCmdLine = lpCmdLine;
- nCmdShow = nCmdShow;
+ UNUSED_VAR(hInstance);
+ UNUSED_VAR(hPrevInstance);
+ UNUSED_VAR(lpCmdLine);
+ UNUSED_VAR(nCmdShow);
#endif
CrcGenerateTable();
@@ -315,7 +323,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{
unsigned t = value & 0xF;
value >>= 4;
- s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
}
@@ -391,11 +399,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{
size_t offset = 0;
size_t outSizeProcessed = 0;
- size_t len;
WCHAR *temp;
- len = SzArEx_GetFileNameUtf16(&db, i, NULL);
-
- if (len >= MAX_PATH)
+
+ if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH)
{
res = SZ_ERROR_FAIL;
break;
@@ -584,6 +590,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (hProcess != 0)
{
WaitForSingleObject(hProcess, INFINITE);
+ if (!GetExitCodeProcess(hProcess, &exitCode))
+ exitCode = 1;
CloseHandle(hProcess);
}
@@ -596,7 +604,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
RemoveDirWithSubItems(path);
if (res == SZ_OK)
- return 0;
+ return (int)exitCode;
{
if (res == SZ_ERROR_UNSUPPORTED)
@@ -610,6 +618,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (!errorMessage)
errorMessage = "ERROR";
}
+
if (errorMessage)
PrintErrorMessage(errorMessage);
}
diff --git a/C/Util/SfxSetup/SfxSetup.dsp b/C/Util/SfxSetup/SfxSetup.dsp
index 1d5fdd8..be9de6d 100644
--- a/C/Util/SfxSetup/SfxSetup.dsp
+++ b/C/Util/SfxSetup/SfxSetup.dsp
@@ -167,6 +167,10 @@ SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
+SOURCE=..\..\BraIA64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
@@ -175,6 +179,22 @@ SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
+SOURCE=..\..\Delta.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Delta.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\DllSecur.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\DllSecur.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile
index cc9878a..6985944 100644
--- a/C/Util/SfxSetup/makefile
+++ b/C/Util/SfxSetup/makefile
@@ -13,7 +13,10 @@ C_OBJS = \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
+ $O\BraIA64.obj \
$O\CpuArch.obj \
+ $O\Delta.obj \
+ $O\DllSecur.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
diff --git a/C/Util/SfxSetup/makefile_con b/C/Util/SfxSetup/makefile_con
index f8bbb1f..cb2c1a4 100644
--- a/C/Util/SfxSetup/makefile_con
+++ b/C/Util/SfxSetup/makefile_con
@@ -14,7 +14,10 @@ C_OBJS = \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
+ $O\BraIA64.obj \
$O\CpuArch.obj \
+ $O\Delta.obj \
+ $O\DllSecur.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
diff --git a/C/Xz.c b/C/Xz.c
index f7b5c24..92144db 100644
--- a/C/Xz.c
+++ b/C/Xz.c
@@ -1,5 +1,5 @@
/* Xz.c - Xz
-2009-04-15 : Igor Pavlov : Public domain */
+2015-05-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -8,8 +8,8 @@
#include "Xz.h"
#include "XzCrc64.h"
-Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
-Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
+const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
+const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
{
@@ -40,11 +40,11 @@ void Xz_Free(CXzStream *p, ISzAlloc *alloc)
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
{
- int t = XzFlags_GetCheckType(f);
+ unsigned t = XzFlags_GetCheckType(f);
return (t == 0) ? 0 : (4 << ((t - 1) / 3));
}
-void XzCheck_Init(CXzCheck *p, int mode)
+void XzCheck_Init(CXzCheck *p, unsigned mode)
{
p->mode = mode;
switch (mode)
diff --git a/C/Xz.h b/C/Xz.h
index 2512fd1..6937bea 100644
--- a/C/Xz.h
+++ b/C/Xz.h
@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
-2014-12-30 : Igor Pavlov : Public domain */
+2015-05-01 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -59,8 +59,8 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt
#define XZ_SIG_SIZE 6
#define XZ_FOOTER_SIG_SIZE 2
-extern Byte XZ_SIG[XZ_SIG_SIZE];
-extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
+extern const Byte XZ_SIG[XZ_SIG_SIZE];
+extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
#define XZ_STREAM_FLAGS_SIZE 2
#define XZ_STREAM_CRC_SIZE 4
@@ -76,13 +76,13 @@ extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
typedef struct
{
- int mode;
+ unsigned mode;
UInt32 crc;
UInt64 crc64;
CSha256 sha;
} CXzCheck;
-void XzCheck_Init(CXzCheck *p, int mode);
+void XzCheck_Init(CXzCheck *p, unsigned mode);
void XzCheck_Update(CXzCheck *p, const void *data, size_t size);
int XzCheck_Final(CXzCheck *p, Byte *digest);
@@ -163,7 +163,7 @@ typedef struct
{
ISzAlloc *alloc;
Byte *buf;
- int numCoders;
+ unsigned numCoders;
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
size_t size[MIXCODER_NUM_FILTERS_MAX - 1];
@@ -174,7 +174,7 @@ typedef struct
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);
void MixCoder_Free(CMixCoder *p);
void MixCoder_Init(CMixCoder *p);
-SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId);
+SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, int srcWasFinished,
ECoderFinishMode finishMode, ECoderStatus *status);
diff --git a/C/XzCrc64.c b/C/XzCrc64.c
index 667e41b..bd0cf5a 100644
--- a/C/XzCrc64.c
+++ b/C/XzCrc64.c
@@ -1,5 +1,5 @@
/* XzCrc64.c -- CRC64 calculation
-2011-06-28 : Igor Pavlov : Public domain */
+2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -13,14 +13,15 @@
#else
#define CRC_NUM_TABLES 5
#define CRC_UINT64_SWAP(v) \
- ((v >> 56) | \
- ((v >> 40) & ((UInt64)0xFF << 8)) | \
- ((v >> 24) & ((UInt64)0xFF << 16)) | \
- ((v >> 8) & ((UInt64)0xFF << 24)) | \
- ((v << 8) & ((UInt64)0xFF << 32)) | \
- ((v << 24) & ((UInt64)0xFF << 40)) | \
- ((v << 40) & ((UInt64)0xFF << 48)) | \
- (v << 56))
+ ((v >> 56) \
+ | ((v >> 40) & ((UInt64)0xFF << 8)) \
+ | ((v >> 24) & ((UInt64)0xFF << 16)) \
+ | ((v >> 8) & ((UInt64)0xFF << 24)) \
+ | ((v << 8) & ((UInt64)0xFF << 32)) \
+ | ((v << 24) & ((UInt64)0xFF << 40)) \
+ | ((v << 40) & ((UInt64)0xFF << 48)) \
+ | ((v << 56)))
+
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
#endif
@@ -64,11 +65,6 @@ void MY_FAST_CALL Crc64GenerateTable()
g_Crc64Update = XzCrc64UpdateT4;
-
-
-
-
-
#else
{
#ifndef MY_CPU_BE
diff --git a/C/XzCrc64Opt.c b/C/XzCrc64Opt.c
index 65be5cd..97d086e 100644
--- a/C/XzCrc64Opt.c
+++ b/C/XzCrc64Opt.c
@@ -1,14 +1,14 @@
/* XzCrc64Opt.c -- CRC64 calculation
-2011-06-28 : Igor Pavlov : Public domain */
+2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
-#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
-
#ifndef MY_CPU_BE
+#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
{
const Byte *p = (const Byte *)data;
@@ -17,11 +17,11 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, con
for (; size >= 4; size -= 4, p += 4)
{
UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
- v = (v >> 32) ^
- table[0x300 + ((d ) & 0xFF)] ^
- table[0x200 + ((d >> 8) & 0xFF)] ^
- table[0x100 + ((d >> 16) & 0xFF)] ^
- table[0x000 + ((d >> 24))];
+ v = (v >> 32)
+ ^ 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);
@@ -34,36 +34,36 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, con
#ifndef MY_CPU_LE
#define CRC_UINT64_SWAP(v) \
- ((v >> 56) | \
- ((v >> 40) & ((UInt64)0xFF << 8)) | \
- ((v >> 24) & ((UInt64)0xFF << 16)) | \
- ((v >> 8) & ((UInt64)0xFF << 24)) | \
- ((v << 8) & ((UInt64)0xFF << 32)) | \
- ((v << 24) & ((UInt64)0xFF << 40)) | \
- ((v << 40) & ((UInt64)0xFF << 48)) | \
- (v << 56))
+ ((v >> 56) \
+ | ((v >> 40) & ((UInt64)0xFF << 8)) \
+ | ((v >> 24) & ((UInt64)0xFF << 16)) \
+ | ((v >> 8) & ((UInt64)0xFF << 24)) \
+ | ((v << 8) & ((UInt64)0xFF << 32)) \
+ | ((v << 24) & ((UInt64)0xFF << 40)) \
+ | ((v << 40) & ((UInt64)0xFF << 48)) \
+ | ((v << 56)))
+
+#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8))
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
{
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_UINT64_SWAP(v);
table += 0x100;
+ v = CRC_UINT64_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)
{
UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
- v = (v << 32) ^
- table[0x000 + ((d ) & 0xFF)] ^
- table[0x100 + ((d >> 8) & 0xFF)] ^
- table[0x200 + ((d >> 16) & 0xFF)] ^
- table[0x300 + ((d >> 24))];
+ v = (v << 32)
+ ^ table[0x000 + ((d ) & 0xFF)]
+ ^ table[0x100 + ((d >> 8) & 0xFF)]
+ ^ table[0x200 + ((d >> 16) & 0xFF)]
+ ^ table[0x300 + ((d >> 24))];
}
- table -= 0x100;
- v = CRC_UINT64_SWAP(v);
for (; size > 0; size--, p++)
- v = CRC_UPDATE_BYTE_2(v, *p);
- return v;
+ v = CRC_UPDATE_BYTE_2_BE(v, *p);
+ return CRC_UINT64_SWAP(v);
}
#endif
diff --git a/C/XzDec.c b/C/XzDec.c
index e23f221..29831b0 100644
--- a/C/XzDec.c
+++ b/C/XzDec.c
@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode
-2014-12-30 : Igor Pavlov : Public domain */
+2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -32,9 +32,9 @@
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
{
- int i, limit;
+ unsigned i, limit;
*value = 0;
- limit = (maxSize > 9) ? 9 : (int)maxSize;
+ limit = (maxSize > 9) ? 9 : (unsigned)maxSize;
for (i = 0; i < limit;)
{
@@ -66,15 +66,15 @@ typedef struct
Byte buf[BRA_BUF_SIZE];
} CBraState;
-void BraState_Free(void *pp, ISzAlloc *alloc)
+static void BraState_Free(void *pp, ISzAlloc *alloc)
{
alloc->Free(alloc, pp);
}
-SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
+static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{
CBraState *p = ((CBraState *)pp);
- alloc = alloc;
+ UNUSED_VAR(alloc);
p->ip = 0;
if (p->methodId == XZ_ID_Delta)
{
@@ -87,7 +87,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
if (propSize == 4)
{
UInt32 v = GetUi32(props);
- switch(p->methodId)
+ switch (p->methodId)
{
case XZ_ID_PPC:
case XZ_ID_ARM:
@@ -112,7 +112,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
return SZ_OK;
}
-void BraState_Init(void *pp)
+static void BraState_Init(void *pp)
{
CBraState *p = ((CBraState *)pp);
p->bufPos = p->bufConv = p->bufTotal = 0;
@@ -129,9 +129,9 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
CBraState *p = ((CBraState *)pp);
SizeT destLenOrig = *destLen;
SizeT srcLenOrig = *srcLen;
+ UNUSED_VAR(finishMode);
*destLen = 0;
*srcLen = 0;
- finishMode = finishMode;
*wasFinished = 0;
while (destLenOrig > 0)
{
@@ -163,7 +163,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
}
if (p->bufTotal == 0)
break;
- switch(p->methodId)
+ switch (p->methodId)
{
case XZ_ID_Delta:
if (p->encodeMode)
@@ -235,9 +235,9 @@ static void SbState_Free(void *pp, ISzAlloc *alloc)
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{
- pp = pp;
- props = props;
- alloc = alloc;
+ UNUSED_VAR(pp);
+ UNUSED_VAR(props);
+ UNUSED_VAR(alloc);
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
}
@@ -251,7 +251,7 @@ static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
{
CSbDec *p = (CSbDec *)pp;
SRes res;
- srcWasFinished = srcWasFinished;
+ UNUSED_VAR(srcWasFinished);
p->dest = dest;
p->destLen = *destLen;
p->src = src;
@@ -308,7 +308,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
ELzmaStatus status;
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status);
- srcWasFinished = srcWasFinished;
+ UNUSED_VAR(srcWasFinished);
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
return res;
}
@@ -330,9 +330,9 @@ static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
{
- int i;
+ unsigned i;
p->alloc = alloc;
- p->buf = 0;
+ p->buf = NULL;
p->numCoders = 0;
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
p->coders[i].p = NULL;
@@ -340,7 +340,7 @@ void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
void MixCoder_Free(CMixCoder *p)
{
- int i;
+ unsigned i;
for (i = 0; i < p->numCoders; i++)
{
IStateCoder *sc = &p->coders[i];
@@ -351,14 +351,14 @@ void MixCoder_Free(CMixCoder *p)
if (p->buf)
{
p->alloc->Free(p->alloc, p->buf);
- p->buf = 0; /* 9.31: the BUG was fixed */
+ p->buf = NULL; /* 9.31: the BUG was fixed */
}
}
void MixCoder_Init(CMixCoder *p)
{
- int i;
- for (i = 0; i < p->numCoders - 1; i++)
+ unsigned i;
+ for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++)
{
p->size[i] = 0;
p->pos[i] = 0;
@@ -371,11 +371,11 @@ void MixCoder_Init(CMixCoder *p)
}
}
-SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
+SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId)
{
IStateCoder *sc = &p->coders[coderIndex];
p->ids[coderIndex] = methodId;
- switch(methodId)
+ switch (methodId)
{
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
#ifdef USE_SUBBLOCK
@@ -398,10 +398,10 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
*srcLen = 0;
*status = CODER_STATUS_NOT_FINISHED;
- if (p->buf == 0)
+ if (!p->buf)
{
p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
- if (p->buf == 0)
+ if (!p->buf)
return SZ_ERROR_MEM;
}
@@ -411,7 +411,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
for (;;)
{
Bool processed = False;
- int i;
+ unsigned i;
/*
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
break;
@@ -520,8 +520,8 @@ static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *b
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
{
unsigned pos;
- int numFilters, i;
- UInt32 headerSize = (UInt32)header[0] << 2;
+ unsigned numFilters, i;
+ unsigned headerSize = (unsigned)header[0] << 2;
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
return SZ_ERROR_ARCHIVE;
@@ -555,9 +555,9 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
pos += (unsigned)size;
#ifdef XZ_DUMP
- printf("\nf[%d] = %2X: ", i, filter->id);
+ printf("\nf[%u] = %2X: ", i, (unsigned)filter->id);
{
- int i;
+ unsigned i;
for (i = 0; i < size; i++)
printf(" %2X", filter->props[i]);
}
@@ -572,9 +572,10 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
{
- int i;
+ unsigned i;
Bool needReInit = True;
- int numFilters = XzBlock_GetNumFilters(block);
+ unsigned numFilters = XzBlock_GetNumFilters(block);
+
if (numFilters == p->numCoders)
{
for (i = 0; i < numFilters; i++)
@@ -582,6 +583,7 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
break;
needReInit = (i != numFilters);
}
+
if (needReInit)
{
MixCoder_Free(p);
@@ -592,12 +594,14 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
RINOK(MixCoder_SetFromMethod(p, i, f->id));
}
}
+
for (i = 0; i < numFilters; i++)
{
const CXzFilter *f = &block->filters[numFilters - 1 - i];
IStateCoder *sc = &p->coders[i];
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
}
+
MixCoder_Init(p);
return SZ_OK;
}
diff --git a/C/XzEnc.c b/C/XzEnc.c
index 3263519..2e5a003 100644
--- a/C/XzEnc.c
+++ b/C/XzEnc.c
@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode
-2014-12-30 : Igor Pavlov : Public domain */
+2015-09-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -10,6 +10,7 @@
#include "Alloc.h"
#include "Bra.h"
#include "CpuArch.h"
+
#ifdef USE_SUBBLOCK
#include "Bcj3Enc.c"
#include "SbFind.c"
@@ -18,14 +19,6 @@
#include "XzEnc.h"
-static void *SzBigAlloc(void *p, size_t size) { p = p; return BigAlloc(size); }
-static void SzBigFree(void *p, void *address) { p = p; BigFree(address); }
-static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
-
-static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
-static void SzFree(void *p, void *address) { p = p; MyFree(address); }
-static ISzAlloc g_Alloc = { SzAlloc, SzFree };
-
#define XzBlock_ClearFlags(p) (p)->flags = 0;
#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);
#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE;
@@ -42,7 +35,7 @@ static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UIn
return WriteBytes(s, buf, size);
}
-SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
+static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
{
UInt32 crc;
Byte header[XZ_STREAM_HEADER_SIZE];
@@ -54,17 +47,19 @@ SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
}
-SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
+
+static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
{
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
unsigned pos = 1;
- int numFilters, i;
+ unsigned numFilters, i;
header[pos++] = p->flags;
if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
numFilters = XzBlock_GetNumFilters(p);
+
for (i = 0; i < numFilters; i++)
{
const CXzFilter *f = &p->filters[i];
@@ -73,14 +68,17 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
memcpy(header + pos, f->props, f->propsSize);
pos += f->propsSize;
}
- while((pos & 3) != 0)
+
+ while ((pos & 3) != 0)
header[pos++] = 0;
+
header[0] = (Byte)(pos >> 2);
SetUi32(header + pos, CrcCalc(header, pos));
return WriteBytes(s, header, pos + 4);
}
-SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
+
+static SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
{
Byte buf[32];
UInt64 globalPos;
@@ -92,6 +90,7 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
globalPos = pos;
buf[0] = 0;
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
+
for (i = 0; i < p->numBlocks; i++)
{
const CXzBlockSizes *block = &p->blocks[i];
@@ -100,7 +99,9 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
globalPos += pos;
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
}
+
pos = ((unsigned)globalPos & 3);
+
if (pos != 0)
{
buf[0] = buf[1] = buf[2] = 0;
@@ -125,34 +126,36 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
}
}
-SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
+
+static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
{
- if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks)
+ if (!p->blocks || p->numBlocksAllocated == p->numBlocks)
{
- size_t num = (p->numBlocks + 1) * 2;
+ size_t num = p->numBlocks * 2 + 1;
size_t newSize = sizeof(CXzBlockSizes) * num;
CXzBlockSizes *blocks;
if (newSize / sizeof(CXzBlockSizes) != num)
return SZ_ERROR_MEM;
blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
- if (blocks == 0)
+ if (!blocks)
return SZ_ERROR_MEM;
if (p->numBlocks != 0)
{
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
- Xz_Free(p, alloc);
+ alloc->Free(alloc, p->blocks);
}
p->blocks = blocks;
p->numBlocksAllocated = num;
}
{
CXzBlockSizes *block = &p->blocks[p->numBlocks++];
- block->totalSize = totalSize;
block->unpackSize = unpackSize;
+ block->totalSize = totalSize;
}
return SZ_OK;
}
+
/* ---------- CSeqCheckInStream ---------- */
typedef struct
@@ -163,13 +166,13 @@ typedef struct
CXzCheck check;
} CSeqCheckInStream;
-void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode)
+static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned mode)
{
p->processed = 0;
XzCheck_Init(&p->check, mode);
}
-void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
+static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
{
XzCheck_Final(&p->check, digest);
}
@@ -183,6 +186,7 @@ static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
return res;
}
+
/* ---------- CSeqSizeOutStream ---------- */
typedef struct
@@ -200,6 +204,7 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
return size;
}
+
/* ---------- CSeqInFilter ---------- */
#define FILTER_BUF_SIZE (1 << 20)
@@ -222,6 +227,7 @@ static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
if (sizeOriginal == 0)
return SZ_OK;
*size = 0;
+
for (;;)
{
if (!p->srcWasFinished && p->curPos == p->endPos)
@@ -279,6 +285,7 @@ static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
return SZ_OK;
}
+
/* ---------- CSbEncInStream ---------- */
#ifdef USE_SUBBLOCK
@@ -296,6 +303,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
size_t sizeOriginal = *size;
if (sizeOriginal == 0)
return S_OK;
+
for (;;)
{
if (p->enc.needRead && !p->enc.readWasFinished)
@@ -310,6 +318,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
}
p->enc.needRead = False;
}
+
*size = sizeOriginal;
RINOK(SbEnc_Read(&p->enc, data, size));
if (*size != 0 || !p->enc.needRead)
@@ -362,7 +371,7 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
{
p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);
- if (p->lzma2 == 0)
+ if (!p->lzma2)
return SZ_ERROR_MEM;
return SZ_OK;
}
@@ -380,10 +389,11 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
}
}
+
void XzProps_Init(CXzProps *p)
{
- p->lzma2Props = 0;
- p->filterProps = 0;
+ p->lzma2Props = NULL;
+ p->filterProps = NULL;
p->checkId = XZ_CHECK_CRC32;
}
@@ -391,10 +401,11 @@ void XzFilterProps_Init(CXzFilterProps *p)
{
p->id = 0;
p->delta = 0;
- p->ip= 0;
+ p->ip = 0;
p->ipDefined = False;
}
+
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
ISeqOutStream *outStream, ISeqInStream *inStream,
const CXzProps *props, ICompressProgress *progress)
@@ -408,7 +419,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
CSeqCheckInStream checkInStream;
CSeqSizeOutStream seqSizeOutStream;
CXzBlock block;
- int filterIndex = 0;
+ unsigned filterIndex = 0;
CXzFilter *filter = NULL;
const CXzFilterProps *fp = props->filterProps;
@@ -420,6 +431,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
filter = &block.filters[filterIndex++];
filter->id = fp->id;
filter->propsSize = 0;
+
if (fp->id == XZ_ID_Delta)
{
filter->props[0] = (Byte)(fp->delta - 1);
@@ -467,14 +479,16 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
{
UInt64 packPos = seqSizeOutStream.processed;
+
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
- fp ?
- #ifdef USE_SUBBLOCK
- (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
- #endif
- &lzmaf->filter.p:
- &checkInStream.p,
- progress);
+ fp ?
+ #ifdef USE_SUBBLOCK
+ (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
+ #endif
+ &lzmaf->filter.p:
+ &checkInStream.p,
+ progress);
+
RINOK(res);
block.unpackSize = checkInStream.processed;
block.packSize = seqSizeOutStream.processed - packPos;
@@ -483,7 +497,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
{
unsigned padSize = 0;
Byte buf[128];
- while((((unsigned)block.packSize + padSize) & 3) != 0)
+ while ((((unsigned)block.packSize + padSize) & 3) != 0)
buf[padSize++] = 0;
SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
@@ -493,6 +507,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
return Xz_WriteFooter(xz, outStream);
}
+
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
const CXzProps *props, ICompressProgress *progress)
{
@@ -509,6 +524,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
return res;
}
+
SRes Xz_EncodeEmpty(ISeqOutStream *outStream)
{
SRes res;
diff --git a/C/XzIn.c b/C/XzIn.c
index c99d71c..aaa0597 100644
--- a/C/XzIn.c
+++ b/C/XzIn.c
@@ -1,5 +1,5 @@
/* XzIn.c - Xz input
-2014-12-30 : Igor Pavlov : Public domain */
+2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -72,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
{
- size_t i, numBlocks, pos = 1;
+ size_t numBlocks, pos = 1;
UInt32 crc;
if (size < 5 || buf[0] != 0)
@@ -94,6 +94,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
Xz_Free(p, alloc);
if (numBlocks != 0)
{
+ size_t i;
p->numBlocks = numBlocks;
p->numBlocksAllocated = numBlocks;
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
@@ -134,55 +135,58 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
return res;
}
-static SRes SeekFromCur(ILookInStream *inStream, Int64 *res)
+static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size)
{
- return inStream->Seek(inStream, res, SZ_SEEK_CUR);
+ RINOK(LookInStream_SeekTo(stream, offset));
+ return LookInStream_Read(stream, buf, size);
+ /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
}
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
{
UInt64 indexSize;
Byte buf[XZ_STREAM_FOOTER_SIZE];
+ UInt64 pos = *startOffset;
- if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)
+ if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset = -XZ_STREAM_FOOTER_SIZE;
- RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ pos -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
UInt32 total = 0;
- *startOffset += XZ_STREAM_FOOTER_SIZE;
+ pos += XZ_STREAM_FOOTER_SIZE;
+
for (;;)
{
size_t i;
#define TEMP_BUF_SIZE (1 << 10)
- Byte tempBuf[TEMP_BUF_SIZE];
- if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
- return SZ_ERROR_NO_ARCHIVE;
- i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
+ Byte temp[TEMP_BUF_SIZE];
+
+ i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos;
+ pos -= i;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i));
total += (UInt32)i;
- *startOffset = -(Int64)i;
- RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
for (; i != 0; i--)
- if (tempBuf[i - 1] != 0)
+ if (temp[i - 1] != 0)
break;
if (i != 0)
{
if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset += i;
+ pos += i;
break;
}
+ if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
+ return SZ_ERROR_NO_ARCHIVE;
}
- if (*startOffset < XZ_STREAM_FOOTER_SIZE)
+
+ if (pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset -= XZ_STREAM_FOOTER_SIZE;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ pos -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
return SZ_ERROR_NO_ARCHIVE;
}
@@ -197,20 +201,22 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
- *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
- RINOK(SeekFromCur(stream, startOffset));
+ if (pos < indexSize)
+ return SZ_ERROR_ARCHIVE;
+ pos -= indexSize;
+ RINOK(LookInStream_SeekTo(stream, pos));
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
{
UInt64 totalSize = Xz_GetPackSize(p);
- UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
- if (totalSize == XZ_SIZE_OVERFLOW ||
- sum >= ((UInt64)1 << 63) ||
- totalSize >= ((UInt64)1 << 63))
+ if (totalSize == XZ_SIZE_OVERFLOW
+ || totalSize >= ((UInt64)1 << 63)
+ || pos < totalSize + XZ_STREAM_HEADER_SIZE)
return SZ_ERROR_ARCHIVE;
- *startOffset = -(Int64)sum;
- RINOK(SeekFromCur(stream, startOffset));
+ pos -= (totalSize + XZ_STREAM_HEADER_SIZE);
+ RINOK(LookInStream_SeekTo(stream, pos));
+ *startOffset = pos;
}
{
CXzStreamFlags headerFlags;
@@ -299,7 +305,7 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
p->streams[p->num++] = st;
if (*startOffset == 0)
break;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
+ RINOK(LookInStream_SeekTo(stream, *startOffset));
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
return SZ_ERROR_PROGRESS;
}