Third-Party: Update LZMA SDK to 15.14
jump to
@@ -194,7 +194,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format")
endif() if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII) - set(USE_LZMA OFF) set(USE_GDB_STUB OFF) endif()@@ -311,7 +310,6 @@ set(FEATURE_SRC)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") if(DISABLE_DEPS) - set(USE_LZMA OFF) set(USE_GDB_STUB OFF) endif()@@ -445,16 +443,18 @@ ${CMAKE_SOURCE_DIR}/src/third-party/lzma/7zCrc.c
${CMAKE_SOURCE_DIR}/src/third-party/lzma/7zCrcOpt.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/7zDec.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/CpuArch.c + ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Delta.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/LzmaDec.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Lzma2Dec.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Bra.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Bra86.c + ${CMAKE_SOURCE_DIR}/src/third-party/lzma/BraIA64.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Bcj2.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Ppmd7.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/Ppmd7Dec.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/7zFile.c ${CMAKE_SOURCE_DIR}/src/third-party/lzma/7zStream.c) - list(APPEND FEATURE_SRC ${LZMA_SRC}) + list(APPEND VFS_SRC ${LZMA_SRC}) list(APPEND FEATURES LZMA) endif()
@@ -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 @@
#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 @@ {
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 @@ UInt64 dataPos;
UInt32 NumFiles; - UInt64 *UnpackPositions; + UInt64 *UnpackPositions; // NumFiles + 1 // Byte *IsEmptyFiles; Byte *IsDirs; CSzBitUi32s CRCs;@@ -154,9 +119,8 @@ // CSzBitUi32s Parents;
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 */@@ -182,6 +146,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(
@@ -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 @@ #endif
void *SzAlloc(void *p, size_t size) { - (void) 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 SzFree(void *p, void *address) { - (void) p; + UNUSED_VAR(p); #ifdef _SZ_ALLOC_DEBUG if (address != 0) {@@ -47,11 +47,11 @@ }
void *SzAllocTemp(void *p, size_t size) { - (void) 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 SzFreeTemp(void *p, void *address) { - (void) p; + UNUSED_VAR(p); #ifdef _SZ_ALLOC_DEBUG if (address != 0) {
@@ -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
@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions -2014-06-16 : Igor Pavlov : Public domain */ +2015-11-18 : Igor Pavlov : Public domain */ #include "Precomp.h"@@ -10,8 +10,16 @@ #include "7zBuf.h"
#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 @@ // k7zParent,
// 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->FoCodersOffsets = NULL; + p->FoStartPackStreamIndex = NULL; + p->FoToCoderUnpackSizes = NULL; + p->FoToMainUnpackSizeIndex = NULL; + p->CoderUnpackSizes = NULL; - p->CodersData = 0; - // p->CoderUnpackSizes = 0; - p->UnpackSizesData = 0; + 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 @@
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_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->Attribs, 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); - + 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 @@ {
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 @@ }
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 @@ SKIP_DATA(sd, size);
return SZ_OK; } -static SRes WaitId(CSzData *sd, UInt64 id) +static SRes WaitId(CSzData *sd, UInt32 id) { for (;;) {@@ -361,29 +302,29 @@ }
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 @@ UInt32 i;
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 @@ return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
} */ -#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 @@ Byte mainByte;
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,108 +471,130 @@ if (id > (UInt32)0xFFFFFFFF)
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) + { + f->NumPackStreams = 1; + f->PackStreams[0] = 0; + } + else + */ { - Byte outStreamUsed[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX]; - - if (numBindPairs > SZ_NUM_BINDS_IN_FOLDER_MAX) + 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; + 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) + { + Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX]; - for (i = 0; i < numOutStreams; i++) - outStreamUsed[i] = False; - - for (i = 0; i < numBindPairs; i++) + 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; + } + + if (numPackStreams == 1) { - CSzBindPair *bp = f->BindPairs + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); - if (bp->InIndex >= numInStreams) - return SZ_ERROR_ARCHIVE; - inStreamUsed[bp->InIndex] = True; - RINOK(SzReadNumber32(sd, &bp->OutIndex)); - if (bp->OutIndex >= numInStreams) + 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) {@@ -658,24 +626,27 @@ *sd2 = sd;
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 @@ sd = *sd2;
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 @@ sd.Size = tempBufs[index].size;
} 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 @@ numCodersOutStreams = 0;
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 @@ return SZ_ERROR_ARCHIVE;
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,86 @@
{ 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) + p->FoToCoderUnpackSizes[fo] = numCodersOutStreams; + p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; + numCodersOutStreams += numCoders; + if (numCodersOutStreams < numCoders) return SZ_ERROR_UNSUPPORTED; + packStreamIndex += numPackStreams; if (packStreamIndex < numPackStreams) return SZ_ERROR_UNSUPPORTED; + if (packStreamIndex > p->NumPackStreams) return SZ_ERROR_ARCHIVE; } } + + 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 +816,13 @@ }
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 (;;)@@ -872,6 +842,13 @@ }
RINOK(SkipData(&sd)); } } + + +UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex) +{ + return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]]; +} + typedef struct {@@ -882,12 +859,10 @@ CSzData sdSizes;
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 +873,7 @@ {
RINOK(ReadID(sd, &type)); if (type == k7zIdNumUnpackStream) { + UInt32 i; ssi->sdNumSubStreams.Data = sd->Data; numUnpackStreams = 0; numSubDigests = 0;@@ -1009,7 +985,6 @@ {
UInt64 dataStartPos; UInt32 fo; CSubStreamInfo ssi; - CSzData sdCodersUnpSizes; RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));@@ -1017,49 +992,26 @@ dataStartPos += baseOffset;
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 +1021,8 @@ size_t pos = 0;
*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 +1054,23 @@ UInt32 i;
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,22 +1084,22 @@ SKIP_DATA2(sd, 8);
} 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 )@@ -1150,10 +1107,9 @@ {
UInt64 type; UInt32 numFiles = 0; UInt32 numEmptyStreams = 0; - UInt32 i; CSubStreamInfo ssi; - const Byte *emptyStreams = 0; - const Byte *emptyFiles = 0; + const Byte *emptyStreams = NULL; + const Byte *emptyFiles = NULL; SzData_Clear(&ssi.sdSizes); SzData_Clear(&ssi.sdCRCs);@@ -1177,22 +1133,19 @@ }
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,9 +1159,9 @@ }
if (type == k7zIdEnd) { - // *sd2 = sd; return SZ_OK; } + if (type != k7zIdFilesInfo) return SZ_ERROR_ARCHIVE;@@ -1225,11 +1178,12 @@ break;
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 +1200,7 @@ }
else { UInt32 index; - SzReadNumber32(sd, &index); + RINOK(SzReadNumber32(sd, &index)); if (index >= *numTempBufs) return SZ_ERROR_ARCHIVE; namesData = (tempBufs)[index].data;@@ -1255,9 +1209,8 @@ }
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 +1222,7 @@ case k7zIdEmptyStream:
{ RINOK(RememberBitVector(sd, numFiles, &emptyStreams)); numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); + emptyFiles = NULL; break; } case k7zIdEmptyFile:@@ -1290,7 +1244,7 @@ sdPtr = sd;
else { UInt32 index; - SzReadNumber32(sd, &index); + RINOK(SzReadNumber32(sd, &index)); if (index >= *numTempBufs) return SZ_ERROR_ARCHIVE; sdSwitch.Data = (tempBufs)[index].data;@@ -1332,35 +1286,31 @@ RINOK(SkipData(sd));
} { + 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 +1322,7 @@ }
} digestIndex = 0; + for (i = 0; i < numFiles; i++, mask >>= 1) { if (mask == 0)@@ -1386,79 +1337,66 @@ }
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 +1407,16 @@ p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
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 +1425,55 @@ crcMask |= mask;
} } } + 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 +1481,21 @@ CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX];
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; - - // return p->CoderUnpackSizes[f->StartCoderUnpackSizesIndex + f->IndexOfMainOutStream]; + if (sd->Size != 0) + return SZ_ERROR_FAIL; - 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 +1554,7 @@ if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp))
return SZ_ERROR_MEM; res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT); + if (res == SZ_OK) { res = SZ_ERROR_ARCHIVE;@@ -1631,7 +1564,9 @@ CSzData sd;
UInt64 type; sd.Data = buf.data; sd.Size = buf.size; + res = ReadID(&sd, &type); + if (res == SZ_OK && type == k7zIdEncodedHeader) { CSzAr tempAr;@@ -1656,35 +1591,35 @@ sd.Size = buf.size;
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,9 +1627,9 @@ {
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,@@ -1708,34 +1643,36 @@ size_t *outSizeProcessed,
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 +1680,30 @@ *outBufferSize = unpackSize;
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; }
@@ -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 @@ memcpy(data, p->data, p->pos);
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; }
@@ -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 @@ #include "CpuArch.h"
#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 @@ {
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 @@ {
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 @@ {
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 }
@@ -1,13 +1,13 @@
/* 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) {@@ -18,10 +18,10 @@ for (; size >= 4; size -= 4, p += 4)
{ 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 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 @@ #ifndef MY_CPU_LE
#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; + table += 0x100; + v = CRC_UINT32_SWAP(v); 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_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
@@ -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 @@ #include "Ppmd7.h"
#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 @@ LzmaDec_Init(&state);
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 @@ lookahead -= inProcessed;
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;@@ -173,6 +187,9 @@
LzmaDec_FreeProbs(&state, allocMain); 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 @@ Lzma2Dec_Init(&state);
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 @@ lookahead -= inProcessed;
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;@@ -222,16 +246,19 @@
Lzma2Dec_FreeProbs(&state, allocMain); 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 @@ switch (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_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 @@ if (!IS_SUPPORTED_CODER(&f->Coders[0]))
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 @@ outSizeCur = (SizeT)unpackSize;
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,65 +434,117 @@ else if (coder->MethodID == k_LZMA)
{ 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 + } + #endif + else return SZ_ERROR_UNSUPPORTED; - #endif - } } 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) + + 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; - res = Bcj2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - tempBuf[2], tempSizes[2], - outBuffer, outSize); - RINOK(res) + 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,@@ -461,33 +554,38 @@ {
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; } }
@@ -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 15 +#define MY_VER_MINOR 14 +#define MY_VER_BUILD 0 +#define MY_VERSION_NUMBERS "15.14" +#define MY_VERSION "15.14" +#define MY_DATE "2015-12-31" #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-2015 Igor Pavlov" + +#ifdef USE_COPYRIGHT_CR + #define MY_COPYRIGHT MY_COPYRIGHT_CR +#else + #define MY_COPYRIGHT MY_COPYRIGHT_PD +#endif + +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption -2013-11-12 : Igor Pavlov : Public domain */ +2015-02-23 : Igor Pavlov : Public domain */ #include "Precomp.h"@@ -7,7 +7,7 @@ #include "Aes.h"
#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 @@
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 @@ {
unsigned i; for (i = 0; i < 256; i++) InvS[Sbox[i]] = (Byte)i; + for (i = 0; i < 256; i++) { {@@ -82,9 +83,11 @@ D[0x200 + i] = Ui32(aD, aB, aE, a9);
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 @@ }
#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, 0, s, p); \ + HT4(m, 1, s, p); \ HT4(m, 2, s, p); \ - HT4(m, 0, s, p); \ HT4(m, 3, s, p); \ - HT4(m, 1, s, p); \ #define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])] #define 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];@@ -169,7 +176,7 @@ }
/* 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 @@ {
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]; }
@@ -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 @@ VirtualFree(address, 0, MEM_RELEASE);
} #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 };
@@ -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 @@ #define BigFree(address) MyFree(address)
#endif -#ifdef __cplusplus -} -#endif +extern ISzAlloc g_Alloc; +extern ISzAlloc g_BigAlloc; + +EXTERN_C_END #endif
@@ -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(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; +#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)); -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; + unsigned i; - const Byte *buffer, *bufferLim; - UInt32 range, code; - Byte prevByte = 0; + 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; +} - unsigned int i; - for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) - p[i] = kBitModelTotal >> 1; - - buffer = buf3; - bufferLim = buffer + size3; - RC_INIT2 - - if (outSize == 0) - return SZ_OK; - - for (;;) +SRes Bcj2Dec_Decode(CBcj2Dec *p) +{ + if (p->range <= 5) { - Byte b; - CProb *prob; - UInt32 bound; - UInt32 ttt; + 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; + } - SizeT limit = size0 - inPos; - if (outSize - outPos < limit) - limit = outSize - outPos; - while (limit != 0) + 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) + { + 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; }
@@ -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 @@ #include "7zTypes.h"
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 +}; -If buf0 overlaps outBuf, there are two required conditions: - 1) (buf0 >= outBuf) - 2) (buf0 + size0 >= outBuf + FullOutputSize). +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 +}; -Returns: - SZ_OK - SZ_ERROR_DATA - Data error +enum +{ + BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, + BCJ2_ENC_STATE_OK +}; + + +#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) + +/* +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
@@ -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; + } +}
@@ -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,11 +18,15 @@ #pragma warning(disable : 4996) // This function or variable may be unsafe
#else #pragma warning(disable : 4511) // copy constructor could not be generated #pragma warning(disable : 4512) // assignment operator could not be generated + #pragma warning(disable : 4514) // unreferenced inline function has been removed #pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 4710) // not inlined #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information #endif #endif + +#define UNUSED_VAR(x) (void)x; +/* #define UNUSED_VAR(x) x=x; */ #endif
@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code -2012-05-29: Igor Pavlov : Public domain */ +2015-03-25: Igor Pavlov : Public domain */ #include "Precomp.h"@@ -54,7 +54,7 @@ #else
#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@@ -116,7 +116,7 @@ MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
return True; } -static UInt32 kVendors[][3] = +static const UInt32 kVendors[][3] = { { 0x756E6547, 0x49656E69, 0x6C65746E}, { 0x68747541, 0x69746E65, 0x444D4163},@@ -144,18 +144,21 @@ int firm;
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));
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code -2013-11-12: Igor Pavlov : Public domain */ +2015-12-01: 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 defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#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,63 @@ #if defined(_WIN32) && defined(_M_IA64)
#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(__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 +#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(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) -#define MY_CPU_BE +#if defined(MY_CPU_LE) && defined(MY_CPU_BE) +Stop_Compiling_Bad_Endian #endif -#if defined(MY_CPU_LE) && defined(MY_CPU_BE) -Stop_Compiling_Bad_Endian + +#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 +122,26 @@ ((UInt32)((const Byte *)(p))[3] << 24))
#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 +150,15 @@ #pragma intrinsic(_byteswap_uint64)
#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 +169,19 @@ ((const Byte *)(p))[3] )
#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 +203,14 @@ CPU_FIRM_AMD,
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();
@@ -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 @@ {
if (!p->directInput) { alloc->Free(alloc, p->bufferBase); - p->bufferBase = 0; + p->bufferBase = NULL; } }@@ -35,17 +35,16 @@ {
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 @@ if (p->directInputRem == 0)
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 @@
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 @@
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 @@
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 @@ MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc); } -static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) { size_t sizeInBytes = (size_t)num * sizeof(CLzRef); if (sizeInBytes / sizeof(CLzRef) != num) - return 0; + return NULL; return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); }@@ -175,19 +179,24 @@ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
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 @@ if (p->numHashBytes == 3)
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 @@ hs += p->fixedHashSize;
} { - 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 @@ limit2 = 1;
} else limit2 -= p->keepSizeAfter; + if (limit2 < limit) limit = limit2; + { UInt32 lenLimit = p->streamPos - p->pos; if (lenLimit > p->matchMaxLen)@@ -270,28 +292,39 @@ }
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 @@
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 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 @@
#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 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]; + hash = p->hash; + pos = p->pos; + + d2 = pos - hash[h2]; + + curMatch = hash[kFix3HashSize + hv]; - p->hash[hash2Value] = - p->hash[kFix3HashSize + hashValue] = p->pos; - + 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 @@ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
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; + + d2 = pos - hash[ h2]; + d3 = pos - hash[kFix3HashSize + h3]; + + curMatch = hash[kFix4HashSize + hv]; - maxLen = 1; + 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 @@ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
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 @@ p->son[p->cyclicBufferPos] = curMatch;
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 @@ do
{ 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 @@ 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; 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 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 @@ {
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; + } + */ }
@@ -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@@ -20,6 +20,11 @@ UInt32 lenLimit;
UInt32 cyclicBufferPos; UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + Byte streamEndWasReached; + Byte btMode; + Byte bigHash; + Byte directInput; UInt32 matchMaxLen; CLzRef *hash;@@ -29,30 +34,30 @@ UInt32 cutValue;
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 @@ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
*/ 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 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 @@ } 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);
@@ -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 "LzHash.h"
#include "LzFindMt.h" -void MtSync_Construct(CMtSync *p) +static void MtSync_Construct(CMtSync *p) { p->wasCreated = False; p->csWasInitialized = False;@@ -20,7 +20,7 @@ Semaphore_Construct(&p->freeSemaphore);
Semaphore_Construct(&p->filledSemaphore); } -void MtSync_GetNextBlock(CMtSync *p) +static void MtSync_GetNextBlock(CMtSync *p) { if (p->needStart) {@@ -48,7 +48,7 @@ }
/* 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 @@ }
p->needStart = True; } -void MtSync_Destruct(CMtSync *p) +static void MtSync_Destruct(CMtSync *p) { if (Thread_WasCreated(&p->thread)) {@@ -134,20 +134,20 @@
#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 @@ {
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 @@ if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
{ 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 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 @@ #ifdef MFMT_GM_INLINE
#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 @@ }
#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 @@ MatchFinderMt_GetNextBlock_Hash(p);
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 @@ size2 = p->cyclicBufferSize - cyclicBufferPos;
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 @@ #else
{ 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 @@ cyclicBufferPos = 0;
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 @@
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 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) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
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 @@ CMatchFinder *mf = p->MatchFinder;
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 @@ {
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 @@ MtSync_StopWriting(&p->btSync);
/* 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 @@ if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
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 @@ {
*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 @@ }
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 @@ {
*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 @@ INCREASE_LZ_POS
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 @@ p->btBufPos += 1 + len;
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 @@ *distances2++ = *btBuf++;
*distances2++ = *btBuf++; } while ((len -= 2) != 0); - len = (UInt32)(distances2 - (distances)); + len = (UInt32)(distances2 - (distances)); } INCREASE_LZ_POS return len;@@ -716,41 +726,41 @@ #define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED
#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 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 @@ break;
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;
@@ -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 @@ CLzRef *son;
UInt32 matchMaxLen; UInt32 numHashBytes; UInt32 pos; - Byte *buffer; + const Byte *buffer; UInt32 cyclicBufferPos; UInt32 cyclicBufferSize; /* it must be historySize + 1 */ UInt32 cutValue;
@@ -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 kFix3HashSize (kHash2Size)
#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
@@ -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 @@ }
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 @@
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 @@
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 @@
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 @@ return SZ_OK;
} (*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 @@ Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
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 @@ if (srcSizeCur > destSizeCur)
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 res;
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 @@ return res;
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; }
@@ -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 @@ {
CLzmaDec decoder; UInt32 packSize; UInt32 unpackSize; - int state; + unsigned state; Byte control; Bool needInitDic; Bool needInitState;
@@ -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 @@ if (useCopyBlock)
{ 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 @@ memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u);
unpackSize -= u; destPos += u; p->srcPos += u; + if (outStream) { *packSizeRes += destPos;@@ -132,9 +134,11 @@ else
*packSizeRes = destPos; /* needInitState = True; */ } + LzmaEnc_RestoreState(p->enc); return SZ_OK; } + { size_t destPos = 0; UInt32 u = unpackSize - 1;@@ -160,10 +164,12 @@
if (outStream) if (outStream->Write(outStream, outBuf, destPos) != destPos) return SZ_ERROR_WRITE; + *packSizeRes = destPos; return SZ_OK; } } + /* ---------- Lzma2 Props ---------- */@@ -221,6 +227,8 @@ p->lzmaProps.numThreads = t1;
LzmaEncProps_Normalize(&p->lzmaProps); + t1 = p->lzmaProps.numThreads; + if (p->blockSize == 0) { UInt32 dictSize = p->lzmaProps.dictSize;@@ -232,27 +240,33 @@ if (blockSize > kMaxSize) blockSize = kMaxSize;
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 (numBlocks < 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 ---------- */@@ -283,15 +297,17 @@ {
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,15 +321,19 @@ break;
if (packSize == 0) break; } + LzmaEnc_Finish(p->enc); + if (res == SZ_OK) { Byte b = 0; if (outStream->Write(outStream, &b, 1) != 1) return SZ_ERROR_WRITE; } + return res; } + #ifndef _7ZIP_ST@@ -362,10 +382,12 @@ res = SZ_ERROR_PROGRESS;
break; } } + LzmaEnc_Finish(p->enc); if (res != SZ_OK) return res; } + if (finished) { if (*destSize == destLim)@@ -377,13 +399,14 @@ return res;
} #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 @@ unsigned i;
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 @@ int i;
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 @@ p->mtCoder.mtCallback = &mtCallback.funcTable;
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); }
@@ -1,5 +1,7 @@
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder -2009-08-14 : Igor Pavlov : Public domain */ +2015-11-08 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include "Lzma86.h"@@ -7,8 +9,8 @@ #include "Alloc.h"
#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); } +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); } SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) {
@@ -1,5 +1,7 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder -2009-08-14 : Igor Pavlov : Public domain */ +2015-11-08 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include <string.h>@@ -11,8 +13,8 @@ #include "LzmaEnc.h"
#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); } +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); } int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int level, UInt32 dictSize, int filterMode)
@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder -2015-01-01 : Igor Pavlov : Public domain */ +2015-06-23 : Igor Pavlov : Public domain */ #include "Precomp.h"@@ -114,13 +114,13 @@ #define RepLenCoder (LenCoder + kNumLenProbs)
#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)@@ -133,8 +133,8 @@ SZ_ERROR_DATA - Error
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 @@ {
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 @@ #endif
} 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 @@ MATCHED_LITER_DEC
} #endif } + dic[dicPos++] = (Byte)symbol; - processedPos++; continue; } - else + { UPDATE_1(prob); prob = probs + IsRep + state;@@ -249,7 +250,7 @@ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
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,6 +291,8 @@ }
state = state < kNumLitStates ? 8 : 11; prob = probs + RepLenCoder; } + + #ifdef _LZMA_SIZE_OPT { unsigned limit, offset; CLzmaProb *probLen = prob + LenChoice;@@ -322,6 +325,42 @@ }
TREE_DECODE(probLen, limit, 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 @@ TREE_6_DECODE(prob, distance);
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 @@ break;
} } } + rep3 = rep2; rep2 = rep1; rep1 = rep0;@@ -398,26 +438,39 @@ rep0 = distance + 1;
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 @@ }
} } while (dicPos < limit && buf < bufLimit); + NORMALIZE; + p->buf = buf; p->range = range; p->code = code;@@ -465,9 +520,10 @@ Byte *dic = p->dic;
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 @@ p->remainLen -= len;
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 @@ UInt32 rem = p->prop.dicSize - p->processedPos;
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 @@ {
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 @@ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
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 @@ }
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 @@ prob = probs + RepLenCoder;
} { unsigned limit, offset; - CLzmaProb *probLen = prob + LenChoice; + const CLzmaProb *probLen = prob + LenChoice; IF_BIT_0_CHECK(probLen) { UPDATE_0_CHECK;@@ -669,7 +727,7 @@ kNumPosSlotBits);
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 @@ return res;
} -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 @@ }
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 @@ while (p->remainLen != kMatchSpecLenStart)
{ 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 @@ return SZ_OK;
} 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 @@ }
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 @@
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 @@
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 @@ CLzmaProps propNew;
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;
@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder -2014-12-29 : Igor Pavlov : Public domain */ +2015-11-08 : Igor Pavlov : Public domain */ #include "Precomp.h"@@ -22,6 +22,9 @@
#ifdef SHOW_STAT 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)@@ -58,6 +61,7 @@ {
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 @@ if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
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 @@ LzmaEncProps_Normalize(&props);
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); } -UInt32 GetPosSlot1(UInt32 pos) +static UInt32 GetPosSlot1(UInt32 pos) { UInt32 res; BSR2_RET(pos, res);@@ -113,27 +121,44 @@ #define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
#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; } } +/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ +/* #define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ res = p->g_FastPos[pos >> i] + (i * 2); } +*/ + +/* +#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ + res = p->g_FastPos[pos >> i] + (i * 2); } +*/ + +#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ + res = p->g_FastPos[pos >> i] + (i * 2); } + /* #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ p->g_FastPos[pos >> 6] + 12 : \@@ -213,6 +238,7 @@ #define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
#define kNumStates 12 + typedef struct { CLzmaProb choice;@@ -222,13 +248,15 @@ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
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 {@@ -243,11 +271,15 @@ ISeqOutStream *outStream;
UInt64 processed; 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 @@ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
CLenPriceEnc lenEnc; CLenPriceEnc repLenEnc; - - UInt32 reps[LZMA_NUM_REPS]; - UInt32 state; } CSaveState; + typedef struct { + void *matchFinderObj; IMatchFinder matchFinder; - void *matchFinderObj; + + 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 @@ #ifndef _7ZIP_ST
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 @@ #endif
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,25 +375,13 @@
CLenPriceEnc lenEnc; CLenPriceEnc repLenEnc; - unsigned lclp; + CSaveState saveState; - Bool fastMode; - - CRangeEnc rc; + #ifndef _7ZIP_ST + Byte pad2[128]; + #endif +} CLzmaEnc; - Bool writeEndMark; - UInt64 nowPos64; - UInt32 matchPriceCount; - Bool finished; - Bool multiThread; - - SRes result; - UInt32 dictSize; - - int needInit; - - CSaveState saveState; -} CLzmaEnc; void LzmaEnc_SaveState(CLzmaEncHandle pp) {@@ -370,7 +406,7 @@ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
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 @@ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
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 @@ CLzmaEnc *p = (CLzmaEnc *)pp;
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 @@ p->lc = props.lc;
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 @@ #define kInfinityPrice (1 << 30)
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 @@
#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 @@ }
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 @@
#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 @@ while (symbol < 0x10000);
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 @@ symbol >>= 1;
} } -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 @@ }
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_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 @@ for (; i < numSymbols; i++)
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 @@ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
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 @@ {
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,7 +979,7 @@ p->optimumCurrentIndex = p->opt[0].posPrev;
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) {@@ -981,7 +1023,7 @@ {
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,12 +1167,12 @@
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@@ -1282,7 +1324,7 @@ {
/* 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 +1367,7 @@ {
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 +1397,13 @@ /* if (_maxMode) */
{ 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 =@@ -1442,16 +1484,16 @@
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 +@@ -1525,7 +1567,7 @@ repLen = repIndex = 0;
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 +1636,7 @@ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
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;@@ -1690,6 +1732,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 +1749,15 @@ LzmaEnc_FastPosInit(p->g_FastPos);
#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 +1766,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 +1775,7 @@ {
#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 +1812,7 @@ return Flush(p, nowPos32);
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 +1829,7 @@ else
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 +1938,7 @@ if (processed + kNumOpts + 300 >= maxUnpackSize ||
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 +1956,19 @@ {
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 +1977,7 @@ p->lclp = lclp;
} } - 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 +1997,7 @@ return SZ_ERROR_MEM;
p->matchFinderObj = &p->matchFinderBase; MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); } + return SZ_OK; }@@ -1980,9 +2026,10 @@ p->isRepG2[i] = kProbInitValue;
} { - 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,9 +2136,10 @@ CLzmaEnc *p = (CLzmaEnc *)pp;
if (p->mtMode) MatchFinderMt_ReleaseStream(&p->matchFinderMt); #else - pp = pp; + UNUSED_VAR(pp); #endif } + typedef struct {@@ -2121,6 +2169,7 @@ {
const CLzmaEnc *p = (CLzmaEnc *)pp; return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); } + const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) {@@ -2128,6 +2177,7 @@ 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 +2212,7 @@
return res; } + static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) { SRes res = SZ_OK;@@ -2175,9 +2226,9 @@
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,9 +2238,18 @@ break;
} } } + 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,34 +2258,34 @@ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
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++) props[1 + i] = (Byte)(dictSize >> (8 * i)); 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,25 +2295,29 @@ CLzmaEnc *p = (CLzmaEnc *)pp;
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; - 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) return SZ_ERROR_OUTPUT_EOF; return res; } + SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,@@ -2261,7 +2325,7 @@ 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);
@@ -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 "Alloc.h" #include "LzmaDec.h" -#include "Alloc.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 @@ NULL, &g_Alloc, &g_Alloc);
} -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;
@@ -1,9 +1,7 @@
/* 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"@@ -120,7 +118,7 @@ Event_Construct(&p->canWrite);
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) {
@@ -1,10 +1,10 @@
/* Ppmd7.c -- PPMdH codec -2010-03-12 : Igor Pavlov : Public domain +2015-09-28 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" -#include <memory.h> +#include <string.h> #include "Ppmd7.h"@@ -66,7 +66,7 @@
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 @@ }
#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) {
@@ -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 @@ {
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++;
@@ -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,15 +8,19 @@ #ifdef _MSC_VER
#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))))
@@ -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 @@ #define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
#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 @@ R(d,e,f,g,h,a,b,c, i+5); \
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 @@ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
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 @@ f = state[5];
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 @@ #undef S1
#undef s0 #undef s1 -static void Sha256_WriteByteBlock(CSha256 *p) +void Sha256_Update(CSha256 *p, const Byte *data, size_t size) { - 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); -} + if (size == 0) + return; -void Sha256_Update(CSha256 *p, const Byte *data, size_t size) -{ - UInt32 curBufferPos = (UInt32)p->count & 0x3F; - while (size > 0) { - 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); }
@@ -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
@@ -42,7 +42,7 @@ # PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /Yu"Precomp.h" /FD /c +# ADD 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,11 +165,23 @@ SOURCE=..\..\Bra86.c
# End Source File # Begin Source File +SOURCE=..\..\BraIA64.c +# End Source File +# Begin Source File + SOURCE=..\..\CpuArch.c # End Source File # Begin Source File SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.c +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.h # End Source File # Begin Source File
@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder -2015-01-02 : Igor Pavlov : Public domain */ +2015-08-02 : Igor Pavlov : Public domain */ #include "Precomp.h"@@ -34,75 +34,117 @@ return Buf_Create(dest, size, &g_Alloc);
} #ifndef _WIN32 +#define _USE_UTF8 +#endif + +/* #define _USE_UTF8 */ + +#ifdef _USE_UTF8 + +#define _UTF8_START(n) (0x100 - (1 << (7 - (n)))) + +#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6)) -static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +#define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n))))) +#define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F))) -static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen) +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)) { - *destLen = destPos; - return True; + size++; + continue; } - value = src[srcPos++]; - if (value < 0x80) + + if (val >= 0xD800 && val < 0xDC00 && src != srcLim) { - if (dest) - dest[destPos] = (char)value; - destPos++; + UInt32 c2 = *src; + if (c2 >= 0xDC00 && c2 < 0xE000) + { + src++; + size += 3; + continue; + } + } + + 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) + { + *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 @@ {
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 @@ CBuf buf;
SRes res; Buf_Init(&buf); res = Utf16_To_Char(&buf, s - #ifdef _WIN32 + #ifndef _USE_UTF8 , CP_OEMCP #endif );@@ -281,27 +323,25 @@ UIntToStr_2(s, min); s[2] = ':'; s += 3;
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 @@ size_t tempSize = 0;
// UInt32 parents[NUM_PARENTS_MAX]; printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n"); + if (numargs == 1) { printf(@@ -329,6 +370,7 @@ " t: Test integrity of archive\n"
" x: eXtract files with full paths\n"); return 0; } + if (numargs < 3) { PrintError("incorrect command");@@ -364,11 +406,14 @@
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 @@ size_t offset = 0;
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 @@ GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
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 @@ printf("/");
printf("\n"); continue; } + fputs(testCommand ? "Testing ": "Extracting ",@@ -459,6 +506,7 @@ stdout);
res = PrintString(temp); if (res != SZ_OK) break; + if (isDir) printf("/"); else@@ -470,6 +518,7 @@ &allocImp, &allocTempImp);
if (res != SZ_OK) break; } + if (!testCommand) { CSzFile outFile;@@ -477,6 +526,7 @@ size_t processedSize;
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 @@ PrintError("can not open output file");
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 @@ }
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 @@ else if (res == SZ_ERROR_CRC)
PrintError("CRC error"); else printf("\nERROR #%d\n", res); + return 1; }
@@ -1,4 +1,3 @@
-# MY_STATIC_LINK=1 CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT PROG = 7zDec.exe@@ -15,7 +14,9 @@ $O\7zStream.obj \
$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 \
@@ -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 @@
CpuArch.o: ../../CpuArch.c $(CXX) $(CFLAGS) ../../CpuArch.c +Delta.o: ../../Delta.c + $(CXX) $(CFLAGS) ../../Delta.c + LzmaDec.o: ../../LzmaDec.c $(CXX) $(CFLAGS) ../../LzmaDec.c@@ -49,6 +52,9 @@ $(CXX) $(CFLAGS) ../../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 @@ $(CXX) $(CFLAGS) ../../7zStream.c
clean: -$(RM) $(PROG) $(OBJS) -
@@ -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"@@ -17,10 +17,6 @@ const char *kCantReadMessage = "Can not read input file";
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) {@@ -137,7 +133,7 @@ CLzmaEncHandle enc;
SRes res; CLzmaEncProps props; - rs = rs; + UNUSED_VAR(rs); enc = LzmaEnc_Create(&g_Alloc); if (enc == 0)
@@ -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; }
@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup -2014-12-07 : Igor Pavlov : Public domain */ +2015-11-08 : Igor Pavlov : Public domain */ #include "Precomp.h"@@ -23,7 +23,7 @@ #include "../../CpuArch.h"
#define k_EXE_ExtIndex 2 -static const char *kExts[] = +static const char * const kExts[] = { "bat" , "cmd"@@ -37,7 +37,7 @@ , "html"
, "htm" }; -static const char *kNames[] = +static const char * const kNames[] = { "setup" , "install"@@ -63,7 +63,7 @@ }
#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 +75,7 @@ if (len != itemLen)
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 +88,7 @@
#ifdef _CONSOLE static BOOL WINAPI HandlerRoutine(DWORD ctrlType) { - ctrlType = ctrlType; + UNUSED_VAR(ctrlType); return TRUE; } #endif@@ -144,7 +144,7 @@ return False;
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 +182,7 @@ handle = FindFirstFileW(path, &fd);
path[len] = L'\0'; if (handle == INVALID_HANDLE_VALUE) return GetLastError(); + for (;;) { if (wcscmp(fd.cFileName, L".") != 0 &&@@ -199,9 +200,11 @@ SetFileAttributesW(path, 0);
if (DeleteFileW(path) == 0) res = GetLastError(); } + if (res != 0) break; } + if (!FindNextFileW(handle, &fd)) { res = GetLastError();@@ -210,6 +213,7 @@ res = 0;
break; } } + path[len] = L'\0'; FindClose(handle); if (res == 0)@@ -248,14 +252,15 @@ DWORD winRes;
const wchar_t *cmdLineParams; const char *errorMessage = NULL; Bool useShellExecute = True; + DWORD exitCode = 0; #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 +320,7 @@ for (k = 0; k < 8; k++)
{ 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'; }@@ -584,6 +589,8 @@
if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); + if (!GetExitCodeProcess(hProcess, &exitCode)) + exitCode = 1; CloseHandle(hProcess); }@@ -596,7 +603,7 @@ path[pathLen] = L'\0';
RemoveDirWithSubItems(path); if (res == SZ_OK) - return 0; + return (int)exitCode; { if (res == SZ_ERROR_UNSUPPORTED)@@ -610,6 +617,7 @@ {
if (!errorMessage) errorMessage = "ERROR"; } + if (errorMessage) PrintErrorMessage(errorMessage); }
@@ -167,11 +167,23 @@ SOURCE=..\..\Bra86.c
# End Source File # Begin Source File +SOURCE=..\..\BraIA64.c +# End Source File +# Begin Source File + SOURCE=..\..\CpuArch.c # End Source File # Begin Source File SOURCE=..\..\CpuArch.h +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.c +# End Source File +# Begin Source File + +SOURCE=..\..\Delta.h # End Source File # Begin Source File
@@ -13,7 +13,9 @@ $O\7zStream.obj \
$O\Bcj2.obj \ $O\Bra.obj \ $O\Bra86.obj \ + $O\BraIA64.obj \ $O\CpuArch.obj \ + $O\Delta.obj \ $O\Lzma2Dec.obj \ $O\LzmaDec.obj \
@@ -14,7 +14,9 @@ $O\7zStream.obj \
$O\Bcj2.obj \ $O\Bra.obj \ $O\Bra86.obj \ + $O\BraIA64.obj \ $O\CpuArch.obj \ + $O\Delta.obj \ $O\Lzma2Dec.obj \ $O\LzmaDec.obj \
@@ -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 "CpuArch.h"
#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 @@ }
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)
@@ -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 @@
#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 @@ #define XZ_CHECK_SHA256 10
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 @@
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);
@@ -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 @@ #define CRC_NUM_TABLES 4
#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@@ -63,11 +64,6 @@
#ifdef MY_CPU_LE g_Crc64Update = XzCrc64UpdateT4; - - - - - #else {
@@ -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" + +#ifndef MY_CPU_BE #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -#ifndef MY_CPU_BE - 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 @@ v = CRC_UPDATE_BYTE_2(v, *p);
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 @@
#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); + table += 0x100; v = CRC_UINT64_SWAP(v); - table += 0x100; + 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
@@ -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 @@ #define CODER_BUF_SIZE (1 << 17)
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 @@
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 @@ {
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 @@ }
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 @@ {
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 @@ p->bufTotal += curSize;
} if (p->bufTotal == 0) break; - switch(p->methodId) + switch (p->methodId) { case XZ_ID_Delta: if (p->encodeMode)@@ -235,9 +235,9 @@ }
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 @@ int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
{ CSbDec *p = (CSbDec *)pp; SRes res; - srcWasFinished = srcWasFinished; + UNUSED_VAR(srcWasFinished); p->dest = dest; p->destLen = *destLen; p->src = src;@@ -308,7 +308,7 @@ {
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 @@
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_Free(CMixCoder *p) { - int i; + unsigned i; for (i = 0; i < p->numCoders; i++) { IStateCoder *sc = &p->coders[i];@@ -351,14 +351,14 @@ p->numCoders = 0;
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 @@ coder->Init(coder->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 @@ *destLen = 0;
*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 @@
for (;;) { Bool processed = False; - int i; + unsigned i; /* if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) break;@@ -520,8 +520,8 @@
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 @@ memcpy(filter->props, header + pos, (size_t)size);
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 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 @@ if (p->ids[i] != block->filters[numFilters - 1 - i].id)
break; needReInit = (i != numFilters); } + if (needReInit) { MixCoder_Free(p);@@ -592,12 +594,14 @@ const CXzFilter *f = &block->filters[numFilters - 1 - i];
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; }
@@ -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 "7zCrc.h"
#include "Alloc.h" #include "Bra.h" #include "CpuArch.h" + #ifdef USE_SUBBLOCK #include "Bcj3Enc.c" #include "SbFind.c"@@ -17,14 +18,6 @@ #include "SbEnc.c"
#endif #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);@@ -42,7 +35,7 @@ *crc = CrcUpdate(*crc, buf, size);
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 @@ SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc);
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 @@ pos += Xz_WriteVarInt(header + pos, f->propsSize);
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 @@
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 @@ pos += Xz_WriteVarInt(buf + pos, block->unpackSize);
globalPos += pos; RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); } + pos = ((unsigned)globalPos & 3); + if (pos != 0) { buf[0] = buf[1] = buf[2] = 0;@@ -125,33 +126,35 @@ return WriteBytes(s, buf, 12);
} } -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->unpackSize = unpackSize; block->totalSize = totalSize; - block->unpackSize = unpackSize; } return SZ_OK; } + /* ---------- CSeqCheckInStream ---------- */@@ -163,13 +166,13 @@ UInt64 processed;
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); }@@ -182,6 +185,7 @@ XzCheck_Update(&p->check, data, *size);
p->processed += *size; return res; } + /* ---------- CSeqSizeOutStream ---------- */@@ -199,6 +203,7 @@ size = p->realStream->Write(p->realStream, data, size);
p->processed += size; return size; } + /* ---------- CSeqInFilter ---------- */@@ -222,6 +227,7 @@ size_t sizeOriginal = *size;
if (sizeOriginal == 0) return SZ_OK; *size = 0; + for (;;) { if (!p->srcWasFinished && p->curPos == p->endPos)@@ -279,6 +285,7 @@ p->StateCoder.Init(p->StateCoder.p);
return SZ_OK; } + /* ---------- CSbEncInStream ---------- */ #ifdef USE_SUBBLOCK@@ -296,6 +303,7 @@ CSbEncInStream *p = (CSbEncInStream *)pp;
size_t sizeOriginal = *size; if (sizeOriginal == 0) return S_OK; + for (;;) { if (p->enc.needRead && !p->enc.readWasFinished)@@ -310,6 +318,7 @@ p->enc.isFinalFinished = True;
} p->enc.needRead = False; } + *size = sizeOriginal; RINOK(SbEnc_Read(&p->enc, data, size)); if (*size != 0 || !p->enc.needRead)@@ -362,7 +371,7 @@
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 @@ p->lzma2 = NULL;
} } + void XzProps_Init(CXzProps *p) { - p->lzma2Props = 0; - p->filterProps = 0; + p->lzma2Props = NULL; + p->filterProps = NULL; p->checkId = XZ_CHECK_CRC32; }@@ -391,9 +401,10 @@ 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,@@ -408,7 +419,7 @@ {
CSeqCheckInStream checkInStream; CSeqSizeOutStream seqSizeOutStream; CXzBlock block; - int filterIndex = 0; + unsigned filterIndex = 0; CXzFilter *filter = NULL; const CXzFilterProps *fp = props->filterProps;@@ -420,6 +431,7 @@ {
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 @@ }
{ 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 @@
{ 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 @@ }
return Xz_WriteFooter(xz, outStream); } + SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream, const CXzProps *props, ICompressProgress *progress) {@@ -508,6 +523,7 @@ Lzma2WithFilters_Free(&lzmaf);
Xz_Free(&xz, &g_Alloc); return res; } + SRes Xz_EncodeEmpty(ISeqOutStream *outStream) {
@@ -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 @@ */
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 @@
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 @@ alloc->Free(alloc, buf);
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 @@ return SZ_ERROR_ARCHIVE;
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 @@ }
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; }