Update 7z code to SDK 9.22

This fixes some Linux compile errors
This commit is contained in:
EoD 2016-07-30 23:53:39 +02:00
parent 0573351a65
commit 3f5f9adbe9
26 changed files with 4758 additions and 4524 deletions

View File

@ -13,62 +13,66 @@ EXTERN_C_BEGIN
extern Byte k7zSignature[k7zSignatureSize]; extern Byte k7zSignature[k7zSignatureSize];
#define k7zMajorVersion 0 #define k7zMajorVersion 0
enum EIdEnum { enum EIdEnum
k7zIdEnd, {
k7zIdHeader, k7zIdEnd,
k7zIdArchiveProperties, k7zIdHeader,
k7zIdAdditionalStreamsInfo, k7zIdArchiveProperties,
k7zIdMainStreamsInfo, k7zIdAdditionalStreamsInfo,
k7zIdFilesInfo, k7zIdMainStreamsInfo,
k7zIdPackInfo, k7zIdFilesInfo,
k7zIdUnpackInfo, k7zIdPackInfo,
k7zIdSubStreamsInfo, k7zIdUnpackInfo,
k7zIdSize, k7zIdSubStreamsInfo,
k7zIdCRC, k7zIdSize,
k7zIdFolder, k7zIdCRC,
k7zIdCodersUnpackSize, k7zIdFolder,
k7zIdNumUnpackStream, k7zIdCodersUnpackSize,
k7zIdEmptyStream, k7zIdNumUnpackStream,
k7zIdEmptyFile, k7zIdEmptyStream,
k7zIdAnti, k7zIdEmptyFile,
k7zIdName, k7zIdAnti,
k7zIdCTime, k7zIdName,
k7zIdATime, k7zIdCTime,
k7zIdMTime, k7zIdATime,
k7zIdWinAttributes, k7zIdMTime,
k7zIdComment, k7zIdWinAttributes,
k7zIdEncodedHeader, k7zIdComment,
k7zIdStartPos, k7zIdEncodedHeader,
k7zIdDummy k7zIdStartPos,
k7zIdDummy
}; };
typedef struct { typedef struct
UInt32 NumInStreams; {
UInt32 NumOutStreams; UInt32 NumInStreams;
UInt64 MethodID; UInt32 NumOutStreams;
CBuf Props; UInt64 MethodID;
CBuf Props;
} CSzCoderInfo; } CSzCoderInfo;
void SzCoderInfo_Init(CSzCoderInfo *p); void SzCoderInfo_Init(CSzCoderInfo *p);
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
typedef struct { typedef struct
UInt32 InIndex; {
UInt32 OutIndex; UInt32 InIndex;
UInt32 OutIndex;
} CSzBindPair; } CSzBindPair;
typedef struct { typedef struct
CSzCoderInfo *Coders; {
CSzBindPair *BindPairs; CSzCoderInfo *Coders;
UInt32 *PackStreams; CSzBindPair *BindPairs;
UInt64 *UnpackSizes; UInt32 *PackStreams;
UInt32 NumCoders; UInt64 *UnpackSizes;
UInt32 NumBindPairs; UInt32 NumCoders;
UInt32 NumPackStreams; UInt32 NumBindPairs;
int UnpackCRCDefined; UInt32 NumPackStreams;
UInt32 UnpackCRC; int UnpackCRCDefined;
UInt32 UnpackCRC;
UInt32 NumUnpackStreams; UInt32 NumUnpackStreams;
} CSzFolder; } CSzFolder;
void SzFolder_Init(CSzFolder *p); void SzFolder_Init(CSzFolder *p);
@ -77,43 +81,48 @@ int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
UInt64 SzFolder_GetUnpackSize(CSzFolder *p); UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *stream, SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
typedef struct { typedef struct
UInt32 Low; {
UInt32 High; UInt32 Low;
UInt32 High;
} CNtfsFileTime; } CNtfsFileTime;
typedef struct { typedef struct
CNtfsFileTime MTime; {
UInt64 Size; CNtfsFileTime MTime;
UInt32 Crc; UInt64 Size;
UInt32 Attrib; UInt32 Crc;
Byte HasStream; UInt32 Attrib;
Byte IsDir; Byte HasStream;
Byte IsAnti; Byte IsDir;
Byte CrcDefined; Byte IsAnti;
Byte MTimeDefined; Byte CrcDefined;
Byte AttribDefined; Byte MTimeDefined;
Byte AttribDefined;
} CSzFileItem; } CSzFileItem;
void SzFile_Init(CSzFileItem *p); void SzFile_Init(CSzFileItem *p);
typedef struct { typedef struct
UInt64 *PackSizes; {
Byte *PackCRCsDefined; UInt64 *PackSizes;
UInt32 *PackCRCs; Byte *PackCRCsDefined;
CSzFolder *Folders; UInt32 *PackCRCs;
CSzFileItem *Files; CSzFolder *Folders;
UInt32 NumPackStreams; CSzFileItem *Files;
UInt32 NumFolders; UInt32 NumPackStreams;
UInt32 NumFiles; UInt32 NumFolders;
UInt32 NumFiles;
} CSzAr; } CSzAr;
void SzAr_Init(CSzAr *p); void SzAr_Init(CSzAr *p);
void SzAr_Free(CSzAr *p, ISzAlloc *alloc); void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
/* /*
SzExtract extracts file from archive SzExtract extracts file from archive
@ -127,26 +136,27 @@ void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
*outBufferSize *outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid, You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed. it will increase decompression speed.
If you use external function, you can declare these 3 cache variables If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function. (blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache. Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/ */
typedef struct { typedef struct
CSzAr db; {
CSzAr db;
UInt64 startPosAfterHeader;
UInt64 dataPos;
UInt64 startPosAfterHeader; UInt32 *FolderStartPackStreamIndex;
UInt64 dataPos; UInt64 *PackStreamStartPositions;
UInt32 *FolderStartFileIndex;
UInt32 *FileIndexToFolderIndexMap;
UInt32 *FolderStartPackStreamIndex; size_t *FileNameOffsets; /* in 2-byte steps */
UInt64 *PackStreamStartPositions; CBuf FileNames; /* UTF-16-LE */
UInt32 *FolderStartFileIndex;
UInt32 *FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */
CBuf FileNames; /* UTF-16-LE */
} CSzArEx; } CSzArEx;
void SzArEx_Init(CSzArEx *p); void SzArEx_Init(CSzArEx *p);
@ -162,15 +172,18 @@ if dest != NULL, the return value specifies the number of 16-bit characters that
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
SRes SzArEx_Extract(const CSzArEx *db, ILookInStream *inStream, UInt32 fileIndex, /* index of file SRes SzArEx_Extract(
*/ const CSzArEx *db,
UInt32 *blockIndex, /* index of solid block */ ILookInStream *inStream,
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with UInt32 fileIndex, /* index of file */
allocMain) */ UInt32 *blockIndex, /* index of solid block */
size_t *outBufferSize, /* buffer size for output buffer */ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *offset, /* offset of stream for required file in *outBuffer */ size_t *outBufferSize, /* buffer size for output buffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */ size_t *offset, /* offset of stream for required file in *outBuffer */
ISzAlloc *allocMain, ISzAlloc *allocTemp); size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
/* /*
SzArEx_Open Errors: SzArEx_Open Errors:

View File

@ -20,55 +20,57 @@ int g_allocCountTemp = 0;
void *SzAlloc(void *p, size_t size) void *SzAlloc(void *p, size_t size)
{ {
p = p; p = p;
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
g_allocCount++; g_allocCount++;
#endif #endif
return malloc(size); return malloc(size);
} }
void SzFree(void *p, void *address) void SzFree(void *p, void *address)
{ {
p = p; p = p;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) { if (address != 0)
g_allocCount--; {
fprintf(stderr, "\nFree; count = %10d", g_allocCount); g_allocCount--;
} fprintf(stderr, "\nFree; count = %10d", g_allocCount);
#endif }
free(address); #endif
free(address);
} }
void *SzAllocTemp(void *p, size_t size) void *SzAllocTemp(void *p, size_t size)
{ {
p = p; p = p;
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
g_allocCountTemp++; g_allocCountTemp++;
#ifdef _WIN32 #ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size); return HeapAlloc(GetProcessHeap(), 0, size);
#endif #endif
#endif #endif
return malloc(size); return malloc(size);
} }
void SzFreeTemp(void *p, void *address) void SzFreeTemp(void *p, void *address)
{ {
p = p; p = p;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
if (address != 0) { if (address != 0)
g_allocCountTemp--; {
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); g_allocCountTemp--;
} fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
#ifdef _WIN32 }
HeapFree(GetProcessHeap(), 0, address); #ifdef _WIN32
return; HeapFree(GetProcessHeap(), 0, address);
#endif return;
#endif #endif
free(address); #endif
free(address);
} }

View File

@ -7,28 +7,30 @@ Public domain */
void Buf_Init(CBuf *p) void Buf_Init(CBuf *p)
{ {
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
} }
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
{ {
p->size = 0; p->size = 0;
if (size == 0) { if (size == 0)
p->data = 0; {
return 1; p->data = 0;
} return 1;
p->data = (Byte *)alloc->Alloc(alloc, size); }
if (p->data != 0) { p->data = (Byte *)alloc->Alloc(alloc, size);
p->size = size; if (p->data != 0)
return 1; {
} p->size = size;
return 0; return 1;
}
return 0;
} }
void Buf_Free(CBuf *p, ISzAlloc *alloc) void Buf_Free(CBuf *p, ISzAlloc *alloc)
{ {
alloc->Free(alloc, p->data); alloc->Free(alloc, p->data);
p->data = 0; p->data = 0;
p->size = 0; p->size = 0;
} }

View File

@ -10,19 +10,21 @@
extern "C" { extern "C" {
#endif #endif
typedef struct { typedef struct
Byte *data; {
size_t size; Byte *data;
size_t size;
} CBuf; } CBuf;
void Buf_Init(CBuf *p); void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
void Buf_Free(CBuf *p, ISzAlloc *alloc); void Buf_Free(CBuf *p, ISzAlloc *alloc);
typedef struct { typedef struct
Byte *data; {
size_t size; Byte *data;
size_t pos; size_t size;
size_t pos;
} CDynBuf; } CDynBuf;
void DynBuf_Construct(CDynBuf *p); void DynBuf_Construct(CDynBuf *p);

View File

@ -1,73 +1,83 @@
/* 7zCrc.c -- CRC32 calculation /* 7zCrc.c -- CRC32 init
2009-11-23 : Igor Pavlov : Public domain */ 2010-12-01 : Igor Pavlov : Public domain */
#include "7zCrc.h" #include "7zCrc.h"
#include "CpuArch.h" #include "CpuArch.h"
#define kCrcPoly 0xEDB88320 #define kCrcPoly 0xEDB88320
#ifdef MY_CPU_LE #ifdef MY_CPU_X86_OR_AMD64
#define CRC_NUM_TABLES 8 #define CRC_NUM_TABLES 8
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#elif defined(MY_CPU_LE)
#define CRC_NUM_TABLES 4
#else #else
#define CRC_NUM_TABLES 1 #define CRC_NUM_TABLES 5
#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);
#endif #endif
typedef UInt32(MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, #ifndef MY_CPU_BE
const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT4(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);
static CRC_FUNC g_CrcUpdate; static CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
#if CRC_NUM_TABLES == 1
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
#else
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
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{ {
return g_CrcUpdate(v, data, size, g_CrcTable); return g_CrcUpdate(v, data, size, g_CrcTable);
} }
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
{ {
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
} }
void MY_FAST_CALL CrcGenerateTable() void MY_FAST_CALL CrcGenerateTable()
{ {
UInt32 i; UInt32 i;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++)
UInt32 r = i; {
unsigned j; UInt32 r = i;
for (j = 0; j < 8; j++) unsigned j;
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); for (j = 0; j < 8; j++)
g_CrcTable[i] = r; r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
} g_CrcTable[i] = r;
#if CRC_NUM_TABLES == 1 }
g_CrcUpdate = CrcUpdateT1; for (; i < 256 * CRC_NUM_TABLES; i++)
#else {
for (; i < 256 * CRC_NUM_TABLES; i++) { UInt32 r = g_CrcTable[i - 256];
UInt32 r = g_CrcTable[i - 256]; g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); }
}
g_CrcUpdate = CrcUpdateT4; #ifdef MY_CPU_LE
#ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder()) g_CrcUpdate = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT8;
#endif #if CRC_NUM_TABLES == 8
#endif if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
#else
{
#ifndef MY_CPU_BE
UInt32 k = 1;
if (*(const Byte *)&k == 1)
g_CrcUpdate = CrcUpdateT4;
else
#endif
{
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{
UInt32 x = g_CrcTable[i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
g_CrcUpdate = CrcUpdateT1_BeT4;
}
}
#endif
} }

View File

@ -1,30 +1,64 @@
/* 7zCrcOpt.c -- CRC32 calculation : optimized version /* 7zCrcOpt.c -- CRC32 calculation
2009-11-23 : Igor Pavlov : Public domain */ 2010-12-01 : Igor Pavlov : Public domain */
#include "CpuArch.h" #include "CpuArch.h"
#ifdef MY_CPU_LE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
const Byte *p = (const Byte *)data; const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p); v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 4; size -= 4, p += 4) { for (; size >= 4; size -= 4, p += 4)
v ^= *(const UInt32 *)p; {
v = table[0x300 + (v & 0xFF)] ^ table[0x200 + ((v >> 8) & 0xFF)] ^ v ^= *(const UInt32 *)p;
table[0x100 + ((v >> 16) & 0xFF)] ^ table[0x000 + ((v >> 24))]; v =
} table[0x300 + (v & 0xFF)] ^
for (; size > 0; size--, p++) table[0x200 + ((v >> 8) & 0xFF)] ^
v = CRC_UPDATE_BYTE_2(v, *p); table[0x100 + ((v >> 16) & 0xFF)] ^
return v; table[0x000 + ((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
} }
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{ {
return CrcUpdateT4(v, data, size, table); return CrcUpdateT4(v, data, size, table);
}
#endif
#ifndef MY_CPU_LE
#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)
{
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
v = CRC_UINT32_SWAP(v);
table += 0x100;
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 -= 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
} }
#endif #endif

View File

@ -1,465 +1,470 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2010-11-02 : Igor Pavlov : Public domain */ 2010-11-02 : Igor Pavlov : Public domain */
#include <string.h> #include <string.h>
#define _7ZIP_PPMD_SUPPPORT /* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h" #include "7z.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "Bra.h" #include "Bra.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "Lzma2Dec.h" #include "LzmaDec.h"
#include "LzmaDec.h" #include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
#include "Ppmd7.h" #include "Ppmd7.h"
#endif #endif
#define k_Copy 0 #define k_Copy 0
#define k_LZMA2 0x21 #define k_LZMA2 0x21
#define k_LZMA 0x30101 #define k_LZMA 0x30101
#define k_BCJ 0x03030103 #define k_BCJ 0x03030103
#define k_PPC 0x03030205 #define k_PPC 0x03030205
#define k_ARM 0x03030501 #define k_ARM 0x03030501
#define k_ARMT 0x03030701 #define k_ARMT 0x03030701
#define k_SPARC 0x03030805 #define k_SPARC 0x03030805
#define k_BCJ2 0x0303011B #define k_BCJ2 0x0303011B
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
#define k_PPMD 0x30401 #define k_PPMD 0x30401
typedef struct { typedef struct
IByteIn p; {
const Byte *cur; IByteIn p;
const Byte *end; const Byte *cur;
const Byte *begin; const Byte *end;
UInt64 processed; const Byte *begin;
Bool extra; UInt64 processed;
SRes res; Bool extra;
ILookInStream *inStream; SRes res;
} CByteInToLook; ILookInStream *inStream;
} CByteInToLook;
static Byte ReadByte(void *pp)
{ static Byte ReadByte(void *pp)
CByteInToLook *p = (CByteInToLook *)pp; {
if (p->cur != p->end) CByteInToLook *p = (CByteInToLook *)pp;
return *p->cur++; if (p->cur != p->end)
if (p->res == SZ_OK) { return *p->cur++;
size_t size = p->cur - p->begin; if (p->res == SZ_OK)
p->processed += size; {
p->res = p->inStream->Skip(p->inStream, size); size_t size = p->cur - p->begin;
size = (1 << 25); p->processed += size;
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size); p->res = p->inStream->Skip(p->inStream, size);
p->cur = p->begin; size = (1 << 25);
p->end = p->begin + size; p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
if (size != 0) p->cur = p->begin;
return *p->cur++; p->end = p->begin + size;
; if (size != 0)
} return *p->cur++;;
p->extra = True; }
return 0; p->extra = True;
} return 0;
}
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
{ Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
CPpmd7 ppmd; {
CByteInToLook s; CPpmd7 ppmd;
SRes res = SZ_OK; CByteInToLook s;
SRes res = SZ_OK;
s.p.Read = ReadByte;
s.inStream = inStream; s.p.Read = ReadByte;
s.begin = s.end = s.cur = NULL; s.inStream = inStream;
s.extra = False; s.begin = s.end = s.cur = NULL;
s.res = SZ_OK; s.extra = False;
s.processed = 0; s.res = SZ_OK;
s.processed = 0;
if (coder->Props.size != 5)
return SZ_ERROR_UNSUPPORTED; if (coder->Props.size != 5)
return SZ_ERROR_UNSUPPORTED;
{
unsigned order = coder->Props.data[0]; {
UInt32 memSize = GetUi32(coder->Props.data + 1); unsigned order = coder->Props.data[0];
if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER || UInt32 memSize = GetUi32(coder->Props.data + 1);
memSize < PPMD7_MIN_MEM_SIZE || memSize > PPMD7_MAX_MEM_SIZE) if (order < PPMD7_MIN_ORDER ||
return SZ_ERROR_UNSUPPORTED; order > PPMD7_MAX_ORDER ||
Ppmd7_Construct(&ppmd); memSize < PPMD7_MIN_MEM_SIZE ||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) memSize > PPMD7_MAX_MEM_SIZE)
return SZ_ERROR_MEM; return SZ_ERROR_UNSUPPORTED;
Ppmd7_Init(&ppmd, order); Ppmd7_Construct(&ppmd);
} if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
{ return SZ_ERROR_MEM;
CPpmd7z_RangeDec rc; Ppmd7_Init(&ppmd, order);
Ppmd7z_RangeDec_CreateVTable(&rc); }
rc.Stream = &s.p; {
if (!Ppmd7z_RangeDec_Init(&rc)) CPpmd7z_RangeDec rc;
res = SZ_ERROR_DATA; Ppmd7z_RangeDec_CreateVTable(&rc);
else if (s.extra) rc.Stream = &s.p;
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); if (!Ppmd7z_RangeDec_Init(&rc))
else { res = SZ_ERROR_DATA;
SizeT i; else if (s.extra)
for (i = 0; i < outSize; i++) { res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); else
if (s.extra || sym < 0) {
break; SizeT i;
outBuffer[i] = (Byte)sym; for (i = 0; i < outSize; i++)
} {
if (i != outSize) int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); if (s.extra || sym < 0)
else if (s.processed + (s.cur - s.begin) != inSize || break;
!Ppmd7z_RangeDec_IsFinishedOK(&rc)) outBuffer[i] = (Byte)sym;
res = SZ_ERROR_DATA; }
} if (i != outSize)
} res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
Ppmd7_Free(&ppmd, allocMain); else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
return res; res = SZ_ERROR_DATA;
} }
}
#endif Ppmd7_Free(&ppmd, allocMain);
return res;
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, }
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{ #endif
CLzmaDec state;
SRes res = SZ_OK;
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
LzmaDec_Construct(&state); Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
RINOK(LzmaDec_AllocateProbs(&state, {
coder->Props.data, CLzmaDec state;
(unsigned)coder->Props.size, SRes res = SZ_OK;
allocMain));
state.dic = outBuffer; LzmaDec_Construct(&state);
state.dicBufSize = outSize; RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
LzmaDec_Init(&state); state.dic = outBuffer;
state.dicBufSize = outSize;
for (;;) { LzmaDec_Init(&state);
Byte *inBuf = NULL;
size_t lookahead = (1 << 18); for (;;)
if (lookahead > inSize) {
lookahead = (size_t)inSize; Byte *inBuf = NULL;
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); size_t lookahead = (1 << 18);
if (res != SZ_OK) if (lookahead > inSize)
break; lookahead = (size_t)inSize;
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
{ if (res != SZ_OK)
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; break;
ELzmaStatus status;
res = LzmaDec_DecodeToDic(&state, {
outSize, SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
inBuf, ELzmaStatus status;
&inProcessed, res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
LZMA_FINISH_END, lookahead -= inProcessed;
&status); inSize -= inProcessed;
lookahead -= inProcessed; if (res != SZ_OK)
inSize -= inProcessed; break;
if (res != SZ_OK) if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
break; {
if (state.dicPos == state.dicBufSize || if (state.dicBufSize != outSize || lookahead != 0 ||
(inProcessed == 0 && dicPos == state.dicPos)) { (status != LZMA_STATUS_FINISHED_WITH_MARK &&
if (state.dicBufSize != outSize || lookahead != 0 || status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
(status != LZMA_STATUS_FINISHED_WITH_MARK && res = SZ_ERROR_DATA;
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) break;
res = SZ_ERROR_DATA; }
break; res = inStream->Skip((void *)inStream, inProcessed);
} if (res != SZ_OK)
res = inStream->Skip((void *)inStream, inProcessed); break;
if (res != SZ_OK) }
break; }
}
} LzmaDec_FreeProbs(&state, allocMain);
return res;
LzmaDec_FreeProbs(&state, allocMain); }
return res;
} static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream, {
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain) CLzma2Dec state;
{ SRes res = SZ_OK;
CLzma2Dec state;
SRes res = SZ_OK; Lzma2Dec_Construct(&state);
if (coder->Props.size != 1)
Lzma2Dec_Construct(&state); return SZ_ERROR_DATA;
if (coder->Props.size != 1) RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
return SZ_ERROR_DATA; state.decoder.dic = outBuffer;
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); state.decoder.dicBufSize = outSize;
state.decoder.dic = outBuffer; Lzma2Dec_Init(&state);
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state); for (;;)
{
for (;;) { Byte *inBuf = NULL;
Byte *inBuf = NULL; size_t lookahead = (1 << 18);
size_t lookahead = (1 << 18); if (lookahead > inSize)
if (lookahead > inSize) lookahead = (size_t)inSize;
lookahead = (size_t)inSize; res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); if (res != SZ_OK)
if (res != SZ_OK) break;
break;
{
{ SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; ELzmaStatus status;
ELzmaStatus status; res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
res = Lzma2Dec_DecodeToDic(&state, lookahead -= inProcessed;
outSize, inSize -= inProcessed;
inBuf, if (res != SZ_OK)
&inProcessed, break;
LZMA_FINISH_END, if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
&status); {
lookahead -= inProcessed; if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
inSize -= inProcessed; (status != LZMA_STATUS_FINISHED_WITH_MARK))
if (res != SZ_OK) res = SZ_ERROR_DATA;
break; break;
if (state.decoder.dicPos == state.decoder.dicBufSize || }
(inProcessed == 0 && dicPos == state.decoder.dicPos)) { res = inStream->Skip((void *)inStream, inProcessed);
if (state.decoder.dicBufSize != outSize || lookahead != 0 || if (res != SZ_OK)
(status != LZMA_STATUS_FINISHED_WITH_MARK)) break;
res = SZ_ERROR_DATA; }
break; }
}
res = inStream->Skip((void *)inStream, inProcessed); Lzma2Dec_FreeProbs(&state, allocMain);
if (res != SZ_OK) return res;
break; }
}
} static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{
Lzma2Dec_FreeProbs(&state, allocMain); while (inSize > 0)
return res; {
} void *inBuf;
size_t curSize = (1 << 18);
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) if (curSize > inSize)
{ curSize = (size_t)inSize;
while (inSize > 0) { RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
void *inBuf; if (curSize == 0)
size_t curSize = (1 << 18); return SZ_ERROR_INPUT_EOF;
if (curSize > inSize) memcpy(outBuffer, inBuf, curSize);
curSize = (size_t)inSize; outBuffer += curSize;
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); inSize -= curSize;
if (curSize == 0) RINOK(inStream->Skip((void *)inStream, curSize));
return SZ_ERROR_INPUT_EOF; }
memcpy(outBuffer, inBuf, curSize); return SZ_OK;
outBuffer += curSize; }
inSize -= curSize;
RINOK(inStream->Skip((void *)inStream, curSize)); static Bool IS_MAIN_METHOD(UInt32 m)
} {
return SZ_OK; switch(m)
} {
case k_Copy:
static Bool IS_MAIN_METHOD(UInt32 m) case k_LZMA:
{ case k_LZMA2:
switch (m) { #ifdef _7ZIP_PPMD_SUPPPORT
case k_Copy: case k_PPMD:
case k_LZMA: #endif
case k_LZMA2: return True;
#ifdef _7ZIP_PPMD_SUPPPORT }
case k_PPMD: return False;
#endif }
return True;
} static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
return False; {
} return
c->NumInStreams == 1 &&
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) c->NumOutStreams == 1 &&
{ c->MethodID <= (UInt32)0xFFFFFFFF &&
return c->NumInStreams == 1 && c->NumOutStreams == 1 && c->MethodID <= (UInt32)0xFFFFFFFF && IS_MAIN_METHOD((UInt32)c->MethodID);
IS_MAIN_METHOD((UInt32)c->MethodID); }
}
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
static SRes CheckSupportedFolder(const CSzFolder *f)
static SRes CheckSupportedFolder(const CSzFolder *f) {
{ if (f->NumCoders < 1 || f->NumCoders > 4)
if (f->NumCoders < 1 || f->NumCoders > 4) return SZ_ERROR_UNSUPPORTED;
return SZ_ERROR_UNSUPPORTED; if (!IS_SUPPORTED_CODER(&f->Coders[0]))
if (!IS_SUPPORTED_CODER(&f->Coders[0])) return SZ_ERROR_UNSUPPORTED;
return SZ_ERROR_UNSUPPORTED; if (f->NumCoders == 1)
if (f->NumCoders == 1) { {
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
return SZ_OK; return SZ_OK;
} }
if (f->NumCoders == 2) { if (f->NumCoders == 2)
CSzCoderInfo *c = &f->Coders[1]; {
if (c->MethodID > (UInt32)0xFFFFFFFF || c->NumInStreams != 1 || CSzCoderInfo *c = &f->Coders[1];
c->NumOutStreams != 1 || f->NumPackStreams != 1 || f->PackStreams[0] != 0 || if (c->MethodID > (UInt32)0xFFFFFFFF ||
f->NumBindPairs != 1 || f->BindPairs[0].InIndex != 1 || c->NumInStreams != 1 ||
f->BindPairs[0].OutIndex != 0) c->NumOutStreams != 1 ||
return SZ_ERROR_UNSUPPORTED; f->NumPackStreams != 1 ||
switch ((UInt32)c->MethodID) { f->PackStreams[0] != 0 ||
case k_BCJ: f->NumBindPairs != 1 ||
case k_ARM: f->BindPairs[0].InIndex != 1 ||
break; f->BindPairs[0].OutIndex != 0)
default: return SZ_ERROR_UNSUPPORTED;
return SZ_ERROR_UNSUPPORTED; switch ((UInt32)c->MethodID)
} {
return SZ_OK; case k_BCJ:
} case k_ARM:
if (f->NumCoders == 4) { break;
if (!IS_SUPPORTED_CODER(&f->Coders[1]) || !IS_SUPPORTED_CODER(&f->Coders[2]) || default:
!IS_BCJ2(&f->Coders[3])) return SZ_ERROR_UNSUPPORTED;
return SZ_ERROR_UNSUPPORTED; }
if (f->NumPackStreams != 4 || f->PackStreams[0] != 2 || f->PackStreams[1] != 6 || return SZ_OK;
f->PackStreams[2] != 1 || f->PackStreams[3] != 0 || f->NumBindPairs != 3 || }
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || if (f->NumCoders == 4)
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || {
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
return SZ_ERROR_UNSUPPORTED; !IS_SUPPORTED_CODER(&f->Coders[2]) ||
return SZ_OK; !IS_BCJ2(&f->Coders[3]))
} return SZ_ERROR_UNSUPPORTED;
return SZ_ERROR_UNSUPPORTED; if (f->NumPackStreams != 4 ||
} f->PackStreams[0] != 2 ||
f->PackStreams[1] != 6 ||
static UInt64 GetSum(const UInt64 *values, UInt32 index) f->PackStreams[2] != 1 ||
{ f->PackStreams[3] != 0 ||
UInt64 sum = 0; f->NumBindPairs != 3 ||
UInt32 i; f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
for (i = 0; i < index; i++) f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
sum += values[i]; f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
return sum; return SZ_ERROR_UNSUPPORTED;
} return SZ_OK;
}
#define CASE_BRA_CONV(isa) \ return SZ_ERROR_UNSUPPORTED;
case k_##isa: \ }
isa##_Convert(outBuffer, outSize, 0, 0); \
break; static UInt64 GetSum(const UInt64 *values, UInt32 index)
{
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, UInt64 sum = 0;
ILookInStream *inStream, UInt64 startPos, Byte *outBuffer, UInt32 i;
SizeT outSize, ISzAlloc *allocMain, Byte *tempBuf[]) for (i = 0; i < index; i++)
{ sum += values[i];
UInt32 ci; return sum;
SizeT tempSizes[3] = { 0, 0, 0 }; }
SizeT tempSize3 = 0;
Byte *tempBuf3 = 0; #define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
RINOK(CheckSupportedFolder(folder)); static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
ILookInStream *inStream, UInt64 startPos,
for (ci = 0; ci < folder->NumCoders; ci++) { Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
CSzCoderInfo *coder = &folder->Coders[ci]; Byte *tempBuf[])
{
if (IS_MAIN_METHOD((UInt32)coder->MethodID)) { UInt32 ci;
UInt32 si = 0; SizeT tempSizes[3] = { 0, 0, 0};
UInt64 offset; SizeT tempSize3 = 0;
UInt64 inSize; Byte *tempBuf3 = 0;
Byte *outBufCur = outBuffer;
SizeT outSizeCur = outSize; RINOK(CheckSupportedFolder(folder));
if (folder->NumCoders == 4) {
UInt32 indices[] = { 3, 2, 0 }; for (ci = 0; ci < folder->NumCoders; ci++)
UInt64 unpackSize = folder->UnpackSizes[ci]; {
si = indices[ci]; CSzCoderInfo *coder = &folder->Coders[ci];
if (ci < 2) {
Byte *temp; if (IS_MAIN_METHOD((UInt32)coder->MethodID))
outSizeCur = (SizeT)unpackSize; {
if (outSizeCur != unpackSize) UInt32 si = 0;
return SZ_ERROR_MEM; UInt64 offset;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur); UInt64 inSize;
if (temp == 0 && outSizeCur != 0) Byte *outBufCur = outBuffer;
return SZ_ERROR_MEM; SizeT outSizeCur = outSize;
outBufCur = tempBuf[1 - ci] = temp; if (folder->NumCoders == 4)
tempSizes[1 - ci] = outSizeCur; {
} else if (ci == 2) { UInt32 indices[] = { 3, 2, 0 };
if (unpackSize > outSize) /* check it */ UInt64 unpackSize = folder->UnpackSizes[ci];
return SZ_ERROR_PARAM; si = indices[ci];
tempBuf3 = outBufCur = if (ci < 2)
outBuffer + (outSize - (size_t)unpackSize); {
tempSize3 = outSizeCur = (SizeT)unpackSize; Byte *temp;
} else outSizeCur = (SizeT)unpackSize;
return SZ_ERROR_UNSUPPORTED; if (outSizeCur != unpackSize)
} return SZ_ERROR_MEM;
offset = GetSum(packSizes, si); temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
inSize = packSizes[si]; if (temp == 0 && outSizeCur != 0)
RINOK(LookInStream_SeekTo(inStream, startPos + offset)); return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
if (coder->MethodID == k_Copy) { tempSizes[1 - ci] = outSizeCur;
if (inSize != outSizeCur) /* check it */ }
return SZ_ERROR_DATA; else if (ci == 2)
RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); {
} else if (coder->MethodID == k_LZMA) { if (unpackSize > outSize) /* check it */
RINOK(SzDecodeLzma(coder, return SZ_ERROR_PARAM;
inSize, tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
inStream, tempSize3 = outSizeCur = (SizeT)unpackSize;
outBufCur, }
outSizeCur, else
allocMain)); return SZ_ERROR_UNSUPPORTED;
} else if (coder->MethodID == k_LZMA2) { }
RINOK(SzDecodeLzma2(coder, offset = GetSum(packSizes, si);
inSize, inSize = packSizes[si];
inStream, RINOK(LookInStream_SeekTo(inStream, startPos + offset));
outBufCur,
outSizeCur, if (coder->MethodID == k_Copy)
allocMain)); {
} else { if (inSize != outSizeCur) /* check it */
#ifdef _7ZIP_PPMD_SUPPPORT return SZ_ERROR_DATA;
RINOK(SzDecodePpmd(coder, RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
inSize, }
inStream, else if (coder->MethodID == k_LZMA)
outBufCur, {
outSizeCur, RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
allocMain)); }
#else else if (coder->MethodID == k_LZMA2)
return SZ_ERROR_UNSUPPORTED; {
#endif RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
} }
} else if (coder->MethodID == k_BCJ2) { else
UInt64 offset = GetSum(packSizes, 1); {
UInt64 s3Size = packSizes[1]; #ifdef _7ZIP_PPMD_SUPPPORT
SRes res; RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
if (ci != 3) #else
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
RINOK(LookInStream_SeekTo(inStream, startPos + offset)); #endif
tempSizes[2] = (SizeT)s3Size; }
if (tempSizes[2] != s3Size) }
return SZ_ERROR_MEM; else if (coder->MethodID == k_BCJ2)
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]); {
if (tempBuf[2] == 0 && tempSizes[2] != 0) UInt64 offset = GetSum(packSizes, 1);
return SZ_ERROR_MEM; UInt64 s3Size = packSizes[1];
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); SRes res;
RINOK(res) if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
res = Bcj2_Decode(tempBuf3, RINOK(LookInStream_SeekTo(inStream, startPos + offset));
tempSize3, tempSizes[2] = (SizeT)s3Size;
tempBuf[0], if (tempSizes[2] != s3Size)
tempSizes[0], return SZ_ERROR_MEM;
tempBuf[1], tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
tempSizes[1], if (tempBuf[2] == 0 && tempSizes[2] != 0)
tempBuf[2], return SZ_ERROR_MEM;
tempSizes[2], res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
outBuffer, RINOK(res)
outSize);
RINOK(res) res = Bcj2_Decode(
} else { tempBuf3, tempSize3,
if (ci != 1) tempBuf[0], tempSizes[0],
return SZ_ERROR_UNSUPPORTED; tempBuf[1], tempSizes[1],
switch (coder->MethodID) { tempBuf[2], tempSizes[2],
case k_BCJ: { outBuffer, outSize);
UInt32 state; RINOK(res)
x86_Convert_Init(state); }
x86_Convert(outBuffer, outSize, 0, &state, 0); else
break; {
} if (ci != 1)
CASE_BRA_CONV(ARM) return SZ_ERROR_UNSUPPORTED;
default: switch(coder->MethodID)
return SZ_ERROR_UNSUPPORTED; {
} case k_BCJ:
} {
} UInt32 state;
return SZ_OK; x86_Convert_Init(state);
} x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *inStream, }
UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) CASE_BRA_CONV(ARM)
{ default:
Byte *tempBuf[3] = { 0, 0, 0 }; return SZ_ERROR_UNSUPPORTED;
int i; }
SRes res = SzFolder_Decode2(folder, }
packSizes, }
inStream, return SZ_OK;
startPos, }
outBuffer,
(SizeT)outSize, SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
allocMain, ILookInStream *inStream, UInt64 startPos,
tempBuf); Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
for (i = 0; i < 3; i++) {
IAlloc_Free(allocMain, tempBuf[i]); Byte *tempBuf[3] = { 0, 0, 0};
return res; int i;
} SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]);
return res;
}

File diff suppressed because it is too large Load Diff

View File

@ -7,157 +7,163 @@
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) { while (size != 0)
size_t processed = size; {
RINOK(stream->Read(stream, buf, &processed)); size_t processed = size;
if (processed == 0) RINOK(stream->Read(stream, buf, &processed));
return errorType; if (processed == 0)
buf = (void *)((Byte *)buf + processed); return errorType;
size -= processed; buf = (void *)((Byte *)buf + processed);
} size -= processed;
return SZ_OK; }
return SZ_OK;
} }
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
{ {
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf) SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
{ {
size_t processed = 1; size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed)); RINOK(stream->Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
} }
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
{ {
Int64 t = offset; Int64 t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET); return stream->Seek(stream, &t, SZ_SEEK_SET);
} }
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
{ {
const void *lookBuf; const void *lookBuf;
if (*size == 0) if (*size == 0)
return SZ_OK; return SZ_OK;
RINOK(stream->Look(stream, &lookBuf, size)); RINOK(stream->Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size); memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size); return stream->Skip(stream, *size);
} }
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) { while (size != 0)
size_t processed = size; {
RINOK(stream->Read(stream, buf, &processed)); size_t processed = size;
if (processed == 0) RINOK(stream->Read(stream, buf, &processed));
return errorType; if (processed == 0)
buf = (void *)((Byte *)buf + processed); return errorType;
size -= processed; buf = (void *)((Byte *)buf + processed);
} size -= processed;
return SZ_OK; }
return SZ_OK;
} }
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
{ {
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) { if (size2 == 0 && *size > 0)
p->pos = 0; {
size2 = LookToRead_BUF_SIZE; p->pos = 0;
res = p->realStream->Read(p->realStream, p->buf, &size2); size2 = LookToRead_BUF_SIZE;
p->size = size2; res = p->realStream->Read(p->realStream, p->buf, &size2);
} p->size = size2;
if (size2 < *size) }
*size = size2; if (size2 < *size)
*buf = p->buf + p->pos; *size = size2;
return res; *buf = p->buf + p->pos;
return res;
} }
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
{ {
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) { if (size2 == 0 && *size > 0)
p->pos = 0; {
if (*size > LookToRead_BUF_SIZE) p->pos = 0;
*size = LookToRead_BUF_SIZE; if (*size > LookToRead_BUF_SIZE)
res = p->realStream->Read(p->realStream, p->buf, size); *size = LookToRead_BUF_SIZE;
size2 = p->size = *size; res = p->realStream->Read(p->realStream, p->buf, size);
} size2 = p->size = *size;
if (size2 < *size) }
*size = size2; if (size2 < *size)
*buf = p->buf + p->pos; *size = size2;
return res; *buf = p->buf + p->pos;
return res;
} }
static SRes LookToRead_Skip(void *pp, size_t offset) static SRes LookToRead_Skip(void *pp, size_t offset)
{ {
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
p->pos += offset; p->pos += offset;
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead_Read(void *pp, void *buf, size_t *size) static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
{ {
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
size_t rem = p->size - p->pos; size_t rem = p->size - p->pos;
if (rem == 0) if (rem == 0)
return p->realStream->Read(p->realStream, buf, size); return p->realStream->Read(p->realStream, buf, size);
if (rem > *size) if (rem > *size)
rem = *size; rem = *size;
memcpy(buf, p->buf + p->pos, rem); memcpy(buf, p->buf + p->pos, rem);
p->pos += rem; p->pos += rem;
*size = rem; *size = rem;
return SZ_OK; return SZ_OK;
} }
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
{ {
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
p->pos = p->size = 0; p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin); return p->realStream->Seek(p->realStream, pos, origin);
} }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead) void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
{ {
p->s.Look = lookahead ? LookToRead_Look_Lookahead : LookToRead_Look_Exact; p->s.Look = lookahead ?
p->s.Skip = LookToRead_Skip; LookToRead_Look_Lookahead :
p->s.Read = LookToRead_Read; LookToRead_Look_Exact;
p->s.Seek = LookToRead_Seek; p->s.Skip = LookToRead_Skip;
p->s.Read = LookToRead_Read;
p->s.Seek = LookToRead_Seek;
} }
void LookToRead_Init(CLookToRead *p) void LookToRead_Init(CLookToRead *p)
{ {
p->pos = p->size = 0; p->pos = p->size = 0;
} }
static SRes SecToLook_Read(void *pp, void *buf, size_t *size) static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
{ {
CSecToLook *p = (CSecToLook *)pp; CSecToLook *p = (CSecToLook *)pp;
return LookInStream_LookRead(p->realStream, buf, size); return LookInStream_LookRead(p->realStream, buf, size);
} }
void SecToLook_CreateVTable(CSecToLook *p) void SecToLook_CreateVTable(CSecToLook *p)
{ {
p->s.Read = SecToLook_Read; p->s.Read = SecToLook_Read;
} }
static SRes SecToRead_Read(void *pp, void *buf, size_t *size) static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
{ {
CSecToRead *p = (CSecToRead *)pp; CSecToRead *p = (CSecToRead *)pp;
return p->realStream->Read(p->realStream, buf, size); return p->realStream->Read(p->realStream, buf, size);
} }
void SecToRead_CreateVTable(CSecToRead *p) void SecToRead_CreateVTable(CSecToRead *p)
{ {
p->s.Read = SecToRead_Read; p->s.Read = SecToRead_Read;
} }

View File

@ -9,7 +9,7 @@
#define CProb UInt16 #define CProb UInt16
#endif #endif
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1)&0xF0) == 0x80) #define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) #define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
#define kNumTopBits 24 #define kNumTopBits 24
@ -20,132 +20,113 @@
#define kNumMoveBits 5 #define kNumMoveBits 5
#define RC_READ_BYTE (*buffer++) #define RC_READ_BYTE (*buffer++)
#define RC_TEST \ #define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
{ \ #define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
if (buffer == bufferLim) \ { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
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 \ #define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
if (range < kTopValue) { \
RC_TEST; \
range <<= 8; \
code = (code << 8) | RC_READ_BYTE; \
}
#define IF_BIT_0(p) \ #define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
ttt = *(p); \ #define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
bound = (range >> kNumBitModelTotalBits) * ttt; \ #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
if (code < bound)
#define UPDATE_0(p) \
range = bound; \
*(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); \
NORMALIZE;
#define UPDATE_1(p) \
range -= bound; \
code -= bound; \
*(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); \
NORMALIZE;
int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2, int Bcj2_Decode(
SizeT size2, const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize) const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize)
{ {
CProb p[256 + 2]; CProb p[256 + 2];
SizeT inPos = 0, outPos = 0; SizeT inPos = 0, outPos = 0;
const Byte *buffer, *bufferLim; const Byte *buffer, *bufferLim;
UInt32 range, code; UInt32 range, code;
Byte prevByte = 0; Byte prevByte = 0;
unsigned int i; unsigned int i;
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
p[i] = kBitModelTotal >> 1; p[i] = kBitModelTotal >> 1;
buffer = buf3; buffer = buf3;
bufferLim = buffer + size3; bufferLim = buffer + size3;
RC_INIT2 RC_INIT2
if (outSize == 0) if (outSize == 0)
return SZ_OK; return SZ_OK;
for (;;) { for (;;)
Byte b; {
CProb *prob; Byte b;
UInt32 bound; CProb *prob;
UInt32 ttt; UInt32 bound;
UInt32 ttt;
SizeT limit = size0 - inPos; SizeT limit = size0 - inPos;
if (outSize - outPos < limit) if (outSize - outPos < limit)
limit = outSize - outPos; limit = outSize - outPos;
while (limit != 0) { while (limit != 0)
Byte b = buf0[inPos]; {
outBuf[outPos++] = b; Byte b = buf0[inPos];
if (IsJ(prevByte, b)) outBuf[outPos++] = b;
break; if (IsJ(prevByte, b))
inPos++; break;
prevByte = b; inPos++;
limit--; prevByte = b;
} limit--;
}
if (limit == 0 || outPos == outSize) if (limit == 0 || outPos == outSize)
break; break;
b = buf0[inPos++]; b = buf0[inPos++];
if (b == 0xE8) if (b == 0xE8)
prob = p + prevByte; prob = p + prevByte;
else if (b == 0xE9) else if (b == 0xE9)
prob = p + 256; prob = p + 256;
else else
prob = p + 257; prob = p + 257;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob) UPDATE_0(prob)
prevByte = b; prevByte = b;
} }
else else
{ {
UInt32 dest; UInt32 dest;
const Byte *v; const Byte *v;
UPDATE_1(prob) UPDATE_1(prob)
if (b == 0xE8) { if (b == 0xE8)
v = buf1; {
if (size1 < 4) v = buf1;
return SZ_ERROR_DATA; if (size1 < 4)
buf1 += 4; return SZ_ERROR_DATA;
size1 -= 4; buf1 += 4;
} else { size1 -= 4;
v = buf2; }
if (size2 < 4) else
return SZ_ERROR_DATA; {
buf2 += 4; v = buf2;
size2 -= 4; if (size2 < 4)
} return SZ_ERROR_DATA;
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | ((UInt32)v[2] << 8) | buf2 += 4;
((UInt32)v[3])) - size2 -= 4;
((UInt32)outPos + 4); }
outBuf[outPos++] = (Byte)dest; dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
if (outPos == outSize) ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
break; outBuf[outPos++] = (Byte)dest;
outBuf[outPos++] = (Byte)(dest >> 8); if (outPos == outSize)
if (outPos == outSize) break;
break; outBuf[outPos++] = (Byte)(dest >> 8);
outBuf[outPos++] = (Byte)(dest >> 16); if (outPos == outSize)
if (outPos == outSize) break;
break; outBuf[outPos++] = (Byte)(dest >> 16);
outBuf[outPos++] = prevByte = (Byte)(dest >> 24); if (outPos == outSize)
} break;
} outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; }
}
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
} }

View File

@ -24,8 +24,12 @@ Returns:
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2, int Bcj2_Decode(
SizeT size2, const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize); const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,116 +5,129 @@
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; SizeT i;
if (size < 4) if (size < 4)
return 0; return 0;
size -= 4; size -= 4;
ip += 8; ip += 8;
for (i = 0; i <= size; i += 4) { for (i = 0; i <= size; i += 4)
if (data[i + 3] == 0xEB) { {
UInt32 dest; if (data[i + 3] == 0xEB)
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | {
(data[i + 0]); UInt32 dest;
src <<= 2; UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
if (encoding) src <<= 2;
dest = ip + (UInt32)i + src; if (encoding)
else dest = ip + (UInt32)i + src;
dest = src - (ip + (UInt32)i); else
dest >>= 2; dest = src - (ip + (UInt32)i);
data[i + 2] = (Byte)(dest >> 16); dest >>= 2;
data[i + 1] = (Byte)(dest >> 8); data[i + 2] = (Byte)(dest >> 16);
data[i + 0] = (Byte)dest; data[i + 1] = (Byte)(dest >> 8);
} data[i + 0] = (Byte)dest;
} }
return i; }
return i;
} }
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; SizeT i;
if (size < 4) if (size < 4)
return 0; return 0;
size -= 4; size -= 4;
ip += 4; ip += 4;
for (i = 0; i <= size; i += 2) { for (i = 0; i <= size; i += 2)
if ((data[i + 1] & 0xF8) == 0xF0 && (data[i + 3] & 0xF8) == 0xF8) { {
UInt32 dest; if ((data[i + 1] & 0xF8) == 0xF0 &&
UInt32 src = (((UInt32)data[i + 1] & 0x7) << 19) | (data[i + 3] & 0xF8) == 0xF8)
((UInt32)data[i + 0] << 11) | {
(((UInt32)data[i + 3] & 0x7) << 8) | (data[i + 2]); UInt32 dest;
UInt32 src =
src <<= 1; (((UInt32)data[i + 1] & 0x7) << 19) |
if (encoding) ((UInt32)data[i + 0] << 11) |
dest = ip + (UInt32)i + src; (((UInt32)data[i + 3] & 0x7) << 8) |
else (data[i + 2]);
dest = src - (ip + (UInt32)i);
dest >>= 1; src <<= 1;
if (encoding)
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); dest = ip + (UInt32)i + src;
data[i + 0] = (Byte)(dest >> 11); else
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); dest = src - (ip + (UInt32)i);
data[i + 2] = (Byte)dest; dest >>= 1;
i += 2;
} data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
} data[i + 0] = (Byte)(dest >> 11);
return i; data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
data[i + 2] = (Byte)dest;
i += 2;
}
}
return i;
} }
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; SizeT i;
if (size < 4) if (size < 4)
return 0; return 0;
size -= 4; size -= 4;
for (i = 0; i <= size; i += 4) { for (i = 0; i <= size; i += 4)
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) { {
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
((UInt32)data[i + 1] << 16) | ((UInt32)data[i + 2] << 8) | {
((UInt32)data[i + 3] & (~3)); UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
((UInt32)data[i + 1] << 16) |
UInt32 dest; ((UInt32)data[i + 2] << 8) |
if (encoding) ((UInt32)data[i + 3] & (~3));
dest = ip + (UInt32)i + src;
else UInt32 dest;
dest = src - (ip + (UInt32)i); if (encoding)
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); dest = ip + (UInt32)i + src;
data[i + 1] = (Byte)(dest >> 16); else
data[i + 2] = (Byte)(dest >> 8); dest = src - (ip + (UInt32)i);
data[i + 3] &= 0x3; data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
data[i + 3] |= dest; data[i + 1] = (Byte)(dest >> 16);
} data[i + 2] = (Byte)(dest >> 8);
} data[i + 3] &= 0x3;
return i; data[i + 3] |= dest;
}
}
return i;
} }
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{ {
UInt32 i; UInt32 i;
if (size < 4) if (size < 4)
return 0; return 0;
size -= 4; size -= 4;
for (i = 0; i <= size; i += 4) { for (i = 0; i <= size; i += 4)
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || {
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) { if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
UInt32 src = ((UInt32)data[i + 0] << 24) | ((UInt32)data[i + 1] << 16) | (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3]); {
UInt32 dest; UInt32 src =
((UInt32)data[i + 0] << 24) |
((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3]);
UInt32 dest;
src <<= 2;
if (encoding)
dest = ip + i + src;
else
dest = src - (ip + i);
dest >>= 2;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
src <<= 2; data[i + 0] = (Byte)(dest >> 24);
if (encoding) data[i + 1] = (Byte)(dest >> 16);
dest = ip + i + src; data[i + 2] = (Byte)(dest >> 8);
else data[i + 3] = (Byte)dest;
dest = src - (ip + i); }
dest >>= 2; }
return i;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) |
0x40000000;
data[i + 0] = (Byte)(dest >> 24);
data[i + 1] = (Byte)(dest >> 16);
data[i + 2] = (Byte)(dest >> 8);
data[i + 3] = (Byte)dest;
}
}
return i;
} }

View File

@ -13,23 +13,23 @@ extern "C" {
/* /*
These functions convert relative addresses to absolute addresses These functions convert relative addresses to absolute addresses
in CALL instructions to increase the compression ratio. in CALL instructions to increase the compression ratio.
In: In:
data - data buffer data - data buffer
size - size of data size - size of data
ip - current virtual Instruction Pinter (IP) value ip - current virtual Instruction Pinter (IP) value
state - state variable for x86 converter state - state variable for x86 converter
encoding - 0 (for decoding), 1 (for encoding) encoding - 0 (for decoding), 1 (for encoding)
Out: Out:
state - state variable for x86 converter state - state variable for x86 converter
Returns: Returns:
The number of processed bytes. If you call these functions with multiple calls, The number of processed bytes. If you call these functions with multiple calls,
you must start next call with first byte after block of processed bytes. you must start next call with first byte after block of processed bytes.
Type Endian Alignment LookAhead Type Endian Alignment LookAhead
x86 little 1 4 x86 little 1 4
ARMT little 2 2 ARMT little 2 2
ARM little 4 0 ARM little 4 0
@ -53,10 +53,7 @@ in CALL instructions to increase the compression ratio.
} }
*/ */
#define x86_Convert_Init(state) \ #define x86_Convert_Init(state) { state = 0; }
{ \
state = 0; \
}
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);

View File

@ -5,74 +5,81 @@
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
const Byte kMaskToAllowedStatus[8] = { 1, 1, 1, 0, 1, 0, 0, 0 }; const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
const Byte kMaskToBitNumber[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
{ {
SizeT bufferPos = 0, prevPosT; SizeT bufferPos = 0, prevPosT;
UInt32 prevMask = *state & 0x7; UInt32 prevMask = *state & 0x7;
if (size < 5) if (size < 5)
return 0; return 0;
ip += 5; ip += 5;
prevPosT = (SizeT)0 - 1; prevPosT = (SizeT)0 - 1;
for (;;) { for (;;)
Byte *p = data + bufferPos; {
Byte *limit = data + size - 4; Byte *p = data + bufferPos;
for (; p < limit; p++) Byte *limit = data + size - 4;
if ((*p & 0xFE) == 0xE8) for (; p < limit; p++)
break; if ((*p & 0xFE) == 0xE8)
bufferPos = (SizeT)(p - data); break;
if (p >= limit) bufferPos = (SizeT)(p - data);
break; if (p >= limit)
prevPosT = bufferPos - prevPosT; break;
if (prevPosT > 3) prevPosT = bufferPos - prevPosT;
prevMask = 0; if (prevPosT > 3)
else { prevMask = 0;
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; else
if (prevMask != 0) { {
Byte b = p[4 - kMaskToBitNumber[prevMask]]; prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) { if (prevMask != 0)
prevPosT = bufferPos; {
prevMask = ((prevMask << 1) & 0x7) | 1; Byte b = p[4 - kMaskToBitNumber[prevMask]];
bufferPos++; if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
continue; {
} prevPosT = bufferPos;
} prevMask = ((prevMask << 1) & 0x7) | 1;
} bufferPos++;
prevPosT = bufferPos; continue;
if (Test86MSByte(p[4])) {
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) |
((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 dest;
for (;;) {
Byte b;
int index;
if (encoding)
dest = (ip + (UInt32)bufferPos) + src;
else
dest = src - (ip + (UInt32)bufferPos);
if (prevMask == 0)
break;
index = kMaskToBitNumber[prevMask] * 8;
b = (Byte)(dest >> (24 - index));
if (!Test86MSByte(b))
break;
src = dest ^ ((1 << (32 - index)) - 1);
}
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
p[3] = (Byte)(dest >> 16);
p[2] = (Byte)(dest >> 8);
p[1] = (Byte)dest;
bufferPos += 5;
} else {
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
}
} }
prevPosT = bufferPos - prevPosT; }
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); }
return bufferPos; prevPosT = bufferPos;
if (Test86MSByte(p[4]))
{
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 dest;
for (;;)
{
Byte b;
int index;
if (encoding)
dest = (ip + (UInt32)bufferPos) + src;
else
dest = src - (ip + (UInt32)bufferPos);
if (prevMask == 0)
break;
index = kMaskToBitNumber[prevMask] * 8;
b = (Byte)(dest >> (24 - index));
if (!Test86MSByte(b))
break;
src = dest ^ ((1 << (32 - index)) - 1);
}
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
p[3] = (Byte)(dest >> 16);
p[2] = (Byte)(dest >> 8);
p[1] = (Byte)dest;
bufferPos += 5;
}
else
{
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
}
}
prevPosT = bufferPos - prevPosT;
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
return bufferPos;
} }

View File

@ -12,157 +12,157 @@
#if defined(USE_ASM) && !defined(MY_CPU_AMD64) #if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag) static UInt32 CheckFlag(UInt32 flag)
{ {
#ifdef _MSC_VER #ifdef _MSC_VER
__asm pushfd; __asm pushfd;
__asm pop EAX; __asm pop EAX;
__asm mov EDX, EAX; __asm mov EDX, EAX;
__asm xor EAX, flag; __asm xor EAX, flag;
__asm push EAX; __asm push EAX;
__asm popfd; __asm popfd;
__asm pushfd; __asm pushfd;
__asm pop EAX; __asm pop EAX;
__asm xor EAX, EDX; __asm xor EAX, EDX;
__asm push EDX; __asm push EDX;
__asm popfd; __asm popfd;
__asm and flag, EAX; __asm and flag, EAX;
#else #else
__asm__ __volatile__( __asm__ __volatile__ (
"pushf\n\t" "pushf\n\t"
"pop %%EAX\n\t" "pop %%EAX\n\t"
"movl %%EAX,%%EDX\n\t" "movl %%EAX,%%EDX\n\t"
"xorl %0,%%EAX\n\t" "xorl %0,%%EAX\n\t"
"push %%EAX\n\t" "push %%EAX\n\t"
"popf\n\t" "popf\n\t"
"pushf\n\t" "pushf\n\t"
"pop %%EAX\n\t" "pop %%EAX\n\t"
"xorl %%EDX,%%EAX\n\t" "xorl %%EDX,%%EAX\n\t"
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t" "andl %%EAX, %0\n\t":
: "=c"(flag) "=c" (flag) : "c" (flag));
: "c"(flag)); #endif
#endif return flag;
return flag;
} }
#define CHECK_CPUID_IS_SUPPORTED \ #define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) \
return False;
#else #else
#define CHECK_CPUID_IS_SUPPORTED #define CHECK_CPUID_IS_SUPPORTED
#endif #endif
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{ {
#ifdef USE_ASM #ifdef USE_ASM
#ifdef _MSC_VER #ifdef _MSC_VER
UInt32 a2, b2, c2, d2; UInt32 a2, b2, c2, d2;
__asm xor EBX, EBX; __asm xor EBX, EBX;
__asm xor ECX, ECX; __asm xor ECX, ECX;
__asm xor EDX, EDX; __asm xor EDX, EDX;
__asm mov EAX, function; __asm mov EAX, function;
__asm cpuid; __asm cpuid;
__asm mov a2, EAX; __asm mov a2, EAX;
__asm mov b2, EBX; __asm mov b2, EBX;
__asm mov c2, ECX; __asm mov c2, ECX;
__asm mov d2, EDX; __asm mov d2, EDX;
*a = a2; *a = a2;
*b = b2; *b = b2;
*c = c2; *c = c2;
*d = d2; *d = d2;
#else #else
// Mac cross-compile compiler: __asm__ __volatile__ (
// can't find register in class 'BREG' while reloading 'asm' "cpuid"
// so use class 'r' register var binding : "=a" (*a) ,
register _b asm("%bx"); "=b" (*b) ,
__asm__ __volatile__("cpuid" : "=a"(*a), "=r"(_b), "=c"(*c), "=d"(*d) : "0"(function)); "=c" (*c) ,
*b = _b; "=d" (*d)
: "0" (function)) ;
#endif #endif
#else
#else int CPUInfo[4];
__cpuid(CPUInfo, function);
*a = CPUInfo[0];
*b = CPUInfo[1];
*c = CPUInfo[2];
*d = CPUInfo[3];
int CPUInfo[4]; #endif
__cpuid(CPUInfo, function);
*a = CPUInfo[0];
*b = CPUInfo[1];
*c = CPUInfo[2];
*d = CPUInfo[3];
#endif
} }
Bool x86cpuid_CheckAndRead(Cx86cpuid *p) Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
{ {
CHECK_CPUID_IS_SUPPORTED CHECK_CPUID_IS_SUPPORTED
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
return True; return True;
} }
static UInt32 kVendors[][3] = { { 0x756E6547, 0x49656E69, 0x6C65746E }, static UInt32 kVendors[][3] =
{ 0x68747541, 0x69746E65, 0x444D4163 }, {
{ 0x746E6543, 0x48727561, 0x736C7561 } }; { 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
{ 0x746E6543, 0x48727561, 0x736C7561}
};
int x86cpuid_GetFirm(const Cx86cpuid *p) int x86cpuid_GetFirm(const Cx86cpuid *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) { for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
const UInt32 *v = kVendors[i]; {
if (v[0] == p->vendor[0] && v[1] == p->vendor[1] && v[2] == p->vendor[2]) const UInt32 *v = kVendors[i];
return (int)i; if (v[0] == p->vendor[0] &&
} v[1] == p->vendor[1] &&
return -1; v[2] == p->vendor[2])
return (int)i;
}
return -1;
} }
Bool CPU_Is_InOrder() Bool CPU_Is_InOrder()
{ {
Cx86cpuid p; Cx86cpuid p;
int firm; int firm;
UInt32 family, model; UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p)) if (!x86cpuid_CheckAndRead(&p))
return True; return True;
family = x86cpuid_GetFamily(&p); family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p); model = x86cpuid_GetModel(&p);
firm = x86cpuid_GetFirm(&p); firm = x86cpuid_GetFirm(&p);
switch (firm) { switch (firm)
case CPU_FIRM_INTEL: {
return (family < 6 || (family == 6 && model == 0x100C)); case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
case CPU_FIRM_AMD: case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
case CPU_FIRM_VIA: }
return (family < 6 || (family == 6 && model < 0xF)); return True;
}
return True;
} }
#if !defined(MY_CPU_AMD64) && defined(_WIN32) #if !defined(MY_CPU_AMD64) && defined(_WIN32)
static Bool CPU_Sys_Is_SSE_Supported() static Bool CPU_Sys_Is_SSE_Supported()
{ {
OSVERSIONINFO vi; OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi); vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionEx(&vi)) if (!GetVersionEx(&vi))
return False; return False;
return (vi.dwMajorVersion >= 5); return (vi.dwMajorVersion >= 5);
} }
#define CHECK_SYS_SSE_SUPPORT \ #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
if (!CPU_Sys_Is_SSE_Supported()) \
return False;
#else #else
#define CHECK_SYS_SSE_SUPPORT #define CHECK_SYS_SSE_SUPPORT
#endif #endif
Bool CPU_Is_Aes_Supported() Bool CPU_Is_Aes_Supported()
{ {
Cx86cpuid p; Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT CHECK_SYS_SSE_SUPPORT
if (!x86cpuid_CheckAndRead(&p)) if (!x86cpuid_CheckAndRead(&p))
return False; return False;
return (p.c >> 25) & 1; return (p.c >> 25) & 1;
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2010-10-26: Igor Pavlov : Public domain */ 2010-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@ -10,8 +10,7 @@ EXTERN_C_BEGIN
/* /*
MY_CPU_LE means that CPU is LITTLE ENDIAN. MY_CPU_LE means that CPU is LITTLE ENDIAN.
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
ENDIAN).
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
@ -49,12 +48,11 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN
#endif #endif
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || \ #if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
#define MY_CPU_LE #define MY_CPU_LE
#endif #endif
#if defined(__BIG_ENDIAN__) #if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif
@ -75,34 +73,27 @@ Stop_Compiling_Bad_Endian
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
#define GetUi32(p) \ #define GetUi32(p) ( \
(((const Byte *)(p))[0] | ((UInt32)((const Byte *)(p))[1] << 8) | \ ((const Byte *)(p))[0] | \
((UInt32)((const Byte *)(p))[2] << 16) | ((UInt32)((const Byte *)(p))[3] << 24)) ((UInt32)((const Byte *)(p))[1] << 8) | \
((UInt32)((const Byte *)(p))[2] << 16) | \
((UInt32)((const Byte *)(p))[3] << 24))
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi16(p, d) \ #define SetUi16(p, d) { UInt32 _x_ = (d); \
{ \ ((Byte *)(p))[0] = (Byte)_x_; \
UInt32 _x_ = (d); \ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
((Byte *)(p))[0] = (Byte)_x_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
}
#define SetUi32(p, d) \ #define SetUi32(p, d) { UInt32 _x_ = (d); \
{ \ ((Byte *)(p))[0] = (Byte)_x_; \
UInt32 _x_ = (d); \ ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
((Byte *)(p))[0] = (Byte)_x_; \ ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
((Byte *)(p))[3] = (Byte)(_x_ >> 24); \
}
#define SetUi64(p, d) \ #define SetUi64(p, d) { UInt64 _x64_ = (d); \
{ \ SetUi32(p, (UInt32)_x64_); \
UInt64 _x64_ = (d); \ SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
SetUi32(p, (UInt32)_x64_); \
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); \
}
#endif #endif
@ -115,9 +106,11 @@ Stop_Compiling_Bad_Endian
#else #else
#define GetBe32(p) \ #define GetBe32(p) ( \
(((UInt32)((const Byte *)(p))[0] << 24) | ((UInt32)((const Byte *)(p))[1] << 16) | \ ((UInt32)((const Byte *)(p))[0] << 24) | \
((UInt32)((const Byte *)(p))[2] << 8) | ((const Byte *)(p))[3]) ((UInt32)((const Byte *)(p))[1] << 16) | \
((UInt32)((const Byte *)(p))[2] << 8) | \
((const Byte *)(p))[3] )
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
@ -125,18 +118,25 @@ Stop_Compiling_Bad_Endian
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64
typedef struct { typedef struct
UInt32 maxFunc; {
UInt32 vendor[3]; UInt32 maxFunc;
UInt32 ver; UInt32 vendor[3];
UInt32 b; UInt32 ver;
UInt32 c; UInt32 b;
UInt32 d; UInt32 c;
UInt32 d;
} Cx86cpuid; } Cx86cpuid;
enum { CPU_FIRM_INTEL, CPU_FIRM_AMD, CPU_FIRM_VIA }; enum
{
CPU_FIRM_INTEL,
CPU_FIRM_AMD,
CPU_FIRM_VIA
};
Bool x86cpuid_CheckAndRead(Cx86cpuid *p); Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p); int x86cpuid_GetFirm(const Cx86cpuid *p);

View File

@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */ 2010-12-15 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@ -36,7 +36,7 @@
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) #define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4 #define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p)&1)) << ((p) / 2 + 11)) #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO #ifdef SHOW_DEBUG_INFO
#define PRF(x) x #define PRF(x) x
@ -44,301 +44,307 @@
#define PRF(x) #define PRF(x)
#endif #endif
typedef enum { typedef enum
LZMA2_STATE_CONTROL, {
LZMA2_STATE_UNPACK0, LZMA2_STATE_CONTROL,
LZMA2_STATE_UNPACK1, LZMA2_STATE_UNPACK0,
LZMA2_STATE_PACK0, LZMA2_STATE_UNPACK1,
LZMA2_STATE_PACK1, LZMA2_STATE_PACK0,
LZMA2_STATE_PROP, LZMA2_STATE_PACK1,
LZMA2_STATE_DATA, LZMA2_STATE_PROP,
LZMA2_STATE_DATA_CONT, LZMA2_STATE_DATA,
LZMA2_STATE_FINISHED, LZMA2_STATE_DATA_CONT,
LZMA2_STATE_ERROR LZMA2_STATE_FINISHED,
LZMA2_STATE_ERROR
} ELzma2State; } ELzma2State;
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
{ {
UInt32 dicSize; UInt32 dicSize;
if (prop > 40) if (prop > 40)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
props[0] = (Byte)LZMA2_LCLP_MAX; props[0] = (Byte)LZMA2_LCLP_MAX;
props[1] = (Byte)(dicSize); props[1] = (Byte)(dicSize);
props[2] = (Byte)(dicSize >> 8); props[2] = (Byte)(dicSize >> 8);
props[3] = (Byte)(dicSize >> 16); props[3] = (Byte)(dicSize >> 16);
props[4] = (Byte)(dicSize >> 24); props[4] = (Byte)(dicSize >> 24);
return SZ_OK; return SZ_OK;
} }
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc) SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
{ {
Byte props[LZMA_PROPS_SIZE]; Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
void Lzma2Dec_Init(CLzma2Dec *p) void Lzma2Dec_Init(CLzma2Dec *p)
{ {
p->state = LZMA2_STATE_CONTROL; p->state = LZMA2_STATE_CONTROL;
p->needInitDic = True; p->needInitDic = True;
p->needInitState = True; p->needInitState = True;
p->needInitProp = True; p->needInitProp = True;
LzmaDec_Init(&p->decoder); LzmaDec_Init(&p->decoder);
} }
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b) static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{ {
switch (p->state) { switch(p->state)
case LZMA2_STATE_CONTROL: {
p->control = b; case LZMA2_STATE_CONTROL:
PRF(printf("\n %4X ", p->decoder.dicPos)); p->control = b;
PRF(printf(" %2X", b)); PRF(printf("\n %4X ", p->decoder.dicPos));
if (p->control == 0) PRF(printf(" %2X", b));
return LZMA2_STATE_FINISHED; if (p->control == 0)
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { return LZMA2_STATE_FINISHED;
if ((p->control & 0x7F) > 2) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
return LZMA2_STATE_ERROR; {
p->unpackSize = 0; if ((p->control & 0x7F) > 2)
} else return LZMA2_STATE_ERROR;
p->unpackSize = (UInt32)(p->control & 0x1F) << 16; p->unpackSize = 0;
return LZMA2_STATE_UNPACK0; }
else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
PRF(printf(" %8d", p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1;
case LZMA2_STATE_UNPACK0: case LZMA2_STATE_PACK1:
p->unpackSize |= (UInt32)b << 8; p->packSize |= (UInt32)b;
return LZMA2_STATE_UNPACK1; p->packSize++;
PRF(printf(" %8d", 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_UNPACK1: case LZMA2_STATE_PROP:
p->unpackSize |= (UInt32)b; {
p->unpackSize++; int lc, lp;
PRF(printf(" %8d", p->unpackSize)); if (b >= (9 * 5 * 5))
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
PRF(printf(" %8d", 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;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = b / 5;
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc;
p->decoder.prop.lp = lp;
p->needInitProp = False;
return LZMA2_STATE_DATA;
}
}
return LZMA2_STATE_ERROR; return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = b / 5;
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc;
p->decoder.prop.lp = lp;
p->needInitProp = False;
return LZMA2_STATE_DATA;
}
}
return LZMA2_STATE_ERROR;
} }
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size) static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
{ {
memcpy(p->dic + p->dicPos, src, size); memcpy(p->dic + p->dicPos, src, size);
p->dicPos += size; p->dicPos += size;
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
p->processedPos += (UInt32)size; p->processedPos += (UInt32)size;
} }
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
ELzmaFinishMode finishMode, ELzmaStatus *status) const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
*srcLen = 0; *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED) { while (p->state != LZMA2_STATE_FINISHED)
SizeT dicPos = p->decoder.dicPos; {
if (p->state == LZMA2_STATE_ERROR) SizeT dicPos = p->decoder.dicPos;
return SZ_ERROR_DATA; if (p->state == LZMA2_STATE_ERROR)
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) { return SZ_ERROR_DATA;
*status = LZMA_STATUS_NOT_FINISHED; if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
return SZ_OK; {
} *status = LZMA_STATUS_NOT_FINISHED;
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) { return SZ_OK;
if (*srcLen == inSize) { }
*status = LZMA_STATUS_NEEDS_MORE_INPUT; if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
return SZ_OK; {
} if (*srcLen == inSize)
(*srcLen)++; {
p->state = Lzma2Dec_UpdateState(p, *src++); *status = LZMA_STATUS_NEEDS_MORE_INPUT;
continue;
}
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur) {
destSizeCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) {
if (*srcLen == inSize) {
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->state == LZMA2_STATE_DATA) {
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
return SZ_ERROR_DATA;
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
if (srcSizeCur > destSizeCur)
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
return SZ_ERROR_DATA;
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL
: LZMA2_STATE_DATA_CONT;
} else {
SizeT outSizeProcessed;
SRes res;
if (p->state == LZMA2_STATE_DATA) {
int mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
Bool initState = (mode > 0);
if ((!initDic && p->needInitDic) ||
(!initState && p->needInitState))
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;
res = LzmaDec_DecodeToDic(&p->decoder,
dicPos + destSizeCur,
src,
&srcSizeCur,
curFinishMode,
status);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur;
outSizeProcessed = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outSizeProcessed;
RINOK(res);
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res;
if (srcSizeCur == 0 && outSizeProcessed == 0) {
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
p->unpackSize != 0 || p->packSize != 0)
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; return SZ_OK;
} }
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
continue;
}
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur)
{
destSizeCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, if (LZMA2_IS_UNCOMPRESSED_STATE(p))
ELzmaFinishMode finishMode, ELzmaStatus *status) {
{ if (*srcLen == inSize)
SizeT outSize = *destLen, inSize = *srcLen; {
*srcLen = *destLen = 0; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
for (;;) { return SZ_OK;
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos) {
outSizeCur = p->decoder.dicBufSize;
curFinishMode = LZMA_FINISH_ANY;
} else {
outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
}
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur;
*srcLen += srcSizeCur;
outSizeCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
} }
}
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, if (p->state == LZMA2_STATE_DATA)
ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) {
{ Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
CLzma2Dec decoder; if (initDic)
p->needInitProp = p->needInitState = True;
else if (p->needInitDic)
return SZ_ERROR_DATA;
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
if (srcSizeCur > destSizeCur)
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
return SZ_ERROR_DATA;
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
SizeT outSizeProcessed;
SRes res; SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
Byte props[LZMA_PROPS_SIZE];
Lzma2Dec_Construct(&decoder); if (p->state == LZMA2_STATE_DATA)
{
int mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
Bool initState = (mode > 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
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;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur;
*destLen = *srcLen = 0; outSizeProcessed = p->decoder.dicPos - dicPos;
*status = LZMA_STATUS_NOT_SPECIFIED; p->unpackSize -= (UInt32)outSizeProcessed;
decoder.decoder.dic = dest;
decoder.decoder.dicBufSize = outSize;
RINOK(Lzma2Dec_GetOldProps(prop, props)); RINOK(res);
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res;
*srcLen = inSize; if (srcSizeCur == 0 && outSizeProcessed == 0)
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); {
*destLen = decoder.decoder.dicPos; if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) p->unpackSize != 0 || p->packSize != 0)
res = SZ_ERROR_INPUT_EOF; return SZ_ERROR_DATA;
p->state = LZMA2_STATE_CONTROL;
LzmaDec_FreeProbs(&decoder.decoder, alloc); }
return res; if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0;
for (;;)
{
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos)
{
outSizeCur = p->decoder.dicBufSize;
curFinishMode = LZMA_FINISH_ANY;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
}
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur;
*srcLen += srcSizeCur;
outSizeCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
}
}
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{
CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
Lzma2Dec_Construct(&p);
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest;
p.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&p);
*srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc);
return res;
} }

View File

@ -12,15 +12,16 @@ extern "C" {
/* ---------- State Interface ---------- */ /* ---------- State Interface ---------- */
typedef struct { typedef struct
CLzmaDec decoder; {
UInt32 packSize; CLzmaDec decoder;
UInt32 unpackSize; UInt32 packSize;
int state; UInt32 unpackSize;
Byte control; int state;
Bool needInitDic; Byte control;
Bool needInitState; Bool needInitDic;
Bool needInitProp; Bool needInitState;
Bool needInitProp;
} CLzma2Dec; } CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) #define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
@ -31,6 +32,7 @@ SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
void Lzma2Dec_Init(CLzma2Dec *p); void Lzma2Dec_Init(CLzma2Dec *p);
/* /*
finishMode: finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit). It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
@ -46,11 +48,12 @@ Returns:
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
@ -71,8 +74,8 @@ Returns:
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/ */
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
#ifdef __cplusplus #ifdef __cplusplus
} }

File diff suppressed because it is too large Load Diff

View File

@ -20,13 +20,15 @@ extern "C" {
#define CLzmaProb UInt16 #define CLzmaProb UInt16
#endif #endif
/* ---------- LZMA Properties ---------- */ /* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5 #define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps { typedef struct _CLzmaProps
unsigned lc, lp, pb; {
UInt32 dicSize; unsigned lc, lp, pb;
UInt32 dicSize;
} CLzmaProps; } CLzmaProps;
/* LzmaProps_Decode - decodes properties /* LzmaProps_Decode - decodes properties
@ -37,6 +39,7 @@ Returns:
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */ /* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
@ -44,31 +47,28 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
#define LZMA_REQUIRED_INPUT_MAX 20 #define LZMA_REQUIRED_INPUT_MAX 20
typedef struct { typedef struct
CLzmaProps prop; {
CLzmaProb *probs; CLzmaProps prop;
Byte *dic; CLzmaProb *probs;
const Byte *buf; Byte *dic;
UInt32 range, code; const Byte *buf;
SizeT dicPos; UInt32 range, code;
SizeT dicBufSize; SizeT dicPos;
UInt32 processedPos; SizeT dicBufSize;
UInt32 checkDicSize; UInt32 processedPos;
unsigned state; UInt32 checkDicSize;
UInt32 reps[4]; unsigned state;
unsigned remainLen; UInt32 reps[4];
int needFlush; unsigned remainLen;
int needInitState; int needFlush;
UInt32 numProbs; int needInitState;
unsigned tempBufSize; UInt32 numProbs;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) \ #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
{ \
(p)->dic = 0; \
(p)->probs = 0; \
}
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec *p);
@ -76,9 +76,10 @@ void LzmaDec_Init(CLzmaDec *p);
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum { typedef enum
LZMA_FINISH_ANY, /* finish at any point */ {
LZMA_FINISH_END /* block must be finished at the end */ LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode; } ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
@ -96,17 +97,18 @@ typedef enum {
3) Check that output(srcLen) = compressedSize, if you know real compressedSize. 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */ You must use correct finish mode in that case. */
typedef enum { typedef enum
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ {
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
without end mark */ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus; } ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */ /* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */ /* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces: /* There are 3 levels of interfaces:
@ -116,6 +118,7 @@ typedef enum {
You can select any of these interfaces, but don't mix functions from different You can select any of these interfaces, but don't mix functions from different
groups for same object. */ groups for same object. */
/* There are two variants to allocate state for Dictionary Interface: /* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free 1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
@ -127,7 +130,7 @@ LzmaDec_Allocate* can return:
SZ_ERROR_MEM - Memory allocation error SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
@ -156,7 +159,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
*/ */
/* LzmaDec_DecodeToDic /* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic). The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
@ -175,8 +178,9 @@ Returns:
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */ /* ---------- Buffer Interface ---------- */
@ -191,8 +195,9 @@ finishMode:
LZMA_FINISH_END - Stream must be finished after (*destLen). LZMA_FINISH_END - Stream must be finished after (*destLen).
*/ */
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
@ -215,9 +220,9 @@ Returns:
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/ */
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ISzAlloc *alloc); ELzmaStatus *status, ISzAlloc *alloc);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,87 +1,86 @@
/* Ppmd.h -- PPMD codec common code /* Ppmd.h -- PPMD codec common code
2010-03-12 : Igor Pavlov : Public domain 2011-01-27 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
#define __PPMD_H #define __PPMD_H
#include "CpuArch.h" #include "Types.h"
#include "Types.h" #include "CpuArch.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#ifdef MY_CPU_32BIT #ifdef MY_CPU_32BIT
#define PPMD_32BIT #define PPMD_32BIT
#endif #endif
#define PPMD_INT_BITS 7 #define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7 #define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) #define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) #define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) #define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) #define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
#define PPMD_UPDATE_PROB_1(prob) ((prob)-PPMD_GET_MEAN(prob)) #define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
#define PPMD_N1 4 #define PPMD_N1 4
#define PPMD_N2 4 #define PPMD_N2 4
#define PPMD_N3 4 #define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) #define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) #define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
/* SEE-contexts for PPM-contexts with masked symbols */ #pragma pack(push, 1)
typedef struct { /* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */ /* SEE-contexts for PPM-contexts with masked symbols */
Byte Count; /* Count to next change of Shift */ typedef struct
} CPpmd_See; {
UInt16 Summ; /* Freq */
#define Ppmd_See_Update(p) \ Byte Shift; /* Speed of Freq change; low Shift is for fast change */
if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) { \ Byte Count; /* Count to next change of Shift */
(p)->Summ <<= 1; \ } CPpmd_See;
(p)->Count = (Byte)(3 << (p)->Shift++); \
} #define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
typedef struct {
Byte Symbol; typedef struct
Byte Freq; {
UInt16 SuccessorLow; Byte Symbol;
UInt16 SuccessorHigh; Byte Freq;
} CPpmd_State; UInt16 SuccessorLow;
UInt16 SuccessorHigh;
typedef } CPpmd_State;
#ifdef PPMD_32BIT
CPpmd_State * #pragma pack(pop)
#else
UInt32 typedef
#endif #ifdef PPMD_32BIT
CPpmd_State_Ref; CPpmd_State *
#else
typedef UInt32
#ifdef PPMD_32BIT #endif
void * CPpmd_State_Ref;
#else
UInt32 typedef
#endif #ifdef PPMD_32BIT
CPpmd_Void_Ref; void *
#else
typedef UInt32
#ifdef PPMD_32BIT #endif
Byte * CPpmd_Void_Ref;
#else
UInt32 typedef
#endif #ifdef PPMD_32BIT
CPpmd_Byte_Ref; Byte *
#else
#define PPMD_SetAllBitsIn256Bytes(p) \ UInt32
{ \ #endif
unsigned i; \ CPpmd_Byte_Ref;
for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
p[i + 7] = p[i + 6] = p[i + 5] = p[i + 4] = p[i + 3] = p[i + 2] = \ #define PPMD_SetAllBitsIn256Bytes(p) \
p[i + 1] = p[i + 0] = ~(size_t)0; \ { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
} \ p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
}
EXTERN_C_END
EXTERN_C_END
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +1,140 @@
/* Ppmd7.h -- PPMdH compression codec /* Ppmd7.h -- PPMdH compression codec
2010-03-12 : Igor Pavlov : Public domain 2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation /* This code supports virtual RangeDecoder and includes the implementation
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef __PPMD7_H #ifndef __PPMD7_H
#define __PPMD7_H #define __PPMD7_H
#include "Ppmd.h" #include "Ppmd.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#define PPMD7_MIN_ORDER 2 #define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64 #define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11) #define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3) #define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_; struct CPpmd7_Context_;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
struct CPpmd7_Context_ * struct CPpmd7_Context_ *
#else #else
UInt32 UInt32
#endif #endif
CPpmd7_Context_Ref; CPpmd7_Context_Ref;
typedef struct CPpmd7_Context_ { typedef struct CPpmd7_Context_
UInt16 NumStats; {
UInt16 SummFreq; UInt16 NumStats;
CPpmd_State_Ref Stats; UInt16 SummFreq;
CPpmd7_Context_Ref Suffix; CPpmd_State_Ref Stats;
} CPpmd7_Context; CPpmd7_Context_Ref Suffix;
} CPpmd7_Context;
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
typedef struct {
CPpmd7_Context *MinContext, *MaxContext; typedef struct
CPpmd_State *FoundState; {
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; CPpmd7_Context *MinContext, *MaxContext;
Int32 RunLength, InitRL; /* must be 32-bit at least */ CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
UInt32 Size; Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; UInt32 Size;
UInt32 AlignOffset; UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
Byte Indx2Units[PPMD_NUM_INDEXES]; UInt32 AlignOffset;
Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; Byte Indx2Units[PPMD_NUM_INDEXES];
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; Byte Units2Indx[128];
CPpmd_See DummySee, See[25][16]; CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
UInt16 BinSumm[128][64]; Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
} CPpmd7; CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64];
void Ppmd7_Construct(CPpmd7 *p); } CPpmd7;
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); void Ppmd7_Construct(CPpmd7 *p);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
/* ---------- Internal Functions ---------- */ #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
extern const Byte PPMD7_kExpEscape[16];
/* ---------- Internal Functions ---------- */
#ifdef PPMD_32BIT
#define Ppmd7_GetPtr(p, ptr) (ptr) extern const Byte PPMD7_kExpEscape[16];
#define Ppmd7_GetContext(p, ptr) (ptr)
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) #ifdef PPMD_32BIT
#else #define Ppmd7_GetPtr(p, ptr) (ptr)
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) #define Ppmd7_GetContext(p, ptr) (ptr)
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) #else
#endif #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
void Ppmd7_Update1(CPpmd7 *p); #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
void Ppmd7_Update1_0(CPpmd7 *p); #endif
void Ppmd7_Update2(CPpmd7 *p);
void Ppmd7_UpdateBin(CPpmd7 *p); void Ppmd7_Update1(CPpmd7 *p);
void Ppmd7_Update1_0(CPpmd7 *p);
#define Ppmd7_GetBinSumm(p) \ void Ppmd7_Update2(CPpmd7 *p);
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1] \ void Ppmd7_UpdateBin(CPpmd7 *p);
[p->PrevSuccess + \
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ #define Ppmd7_GetBinSumm(p) \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
((p->RunLength >> 26) & 0x20)] (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale); ((p->RunLength >> 26) & 0x20)]
/* ---------- Decode ---------- */ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
typedef struct {
UInt32 (*GetThreshold)(void *p, UInt32 total); /* ---------- Decode ---------- */
void (*Decode)(void *p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0); typedef struct
} IPpmd7_RangeDec; {
UInt32 (*GetThreshold)(void *p, UInt32 total);
typedef struct { void (*Decode)(void *p, UInt32 start, UInt32 size);
IPpmd7_RangeDec p; UInt32 (*DecodeBit)(void *p, UInt32 size0);
UInt32 Range; } IPpmd7_RangeDec;
UInt32 Code;
IByteIn *Stream; typedef struct
} CPpmd7z_RangeDec; {
IPpmd7_RangeDec p;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); UInt32 Range;
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); UInt32 Code;
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) IByteIn *Stream;
} CPpmd7z_RangeDec;
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
/* ---------- Encode ---------- */ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
typedef struct {
UInt64 Low; int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
UInt32 Range;
Byte Cache;
UInt64 CacheSize; /* ---------- Encode ---------- */
IByteOut *Stream;
} CPpmd7z_RangeEnc; typedef struct
{
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); UInt64 Low;
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); UInt32 Range;
Byte Cache;
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); UInt64 CacheSize;
IByteOut *Stream;
EXTERN_C_END } CPpmd7z_RangeEnc;
#endif void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
EXTERN_C_END
#endif

View File

@ -1,172 +1,187 @@
/* Ppmd7Dec.c -- PPMdH Decoder /* Ppmd7Dec.c -- PPMdH Decoder
2010-03-12 : Igor Pavlov : Public domain 2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Ppmd7.h" #include "Ppmd7.h"
#define kTopValue (1 << 24) #define kTopValue (1 << 24)
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
{ {
unsigned i; unsigned i;
p->Code = 0; p->Code = 0;
p->Range = 0xFFFFFFFF; p->Range = 0xFFFFFFFF;
if (p->Stream->Read((void *)p->Stream) != 0) if (p->Stream->Read((void *)p->Stream) != 0)
return False; return False;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
return (p->Code < 0xFFFFFFFF); return (p->Code < 0xFFFFFFFF);
} }
static UInt32 Range_GetThreshold(void *pp, UInt32 total) static UInt32 Range_GetThreshold(void *pp, UInt32 total)
{ {
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
return (p->Code) / (p->Range /= total); return (p->Code) / (p->Range /= total);
} }
static void Range_Normalize(CPpmd7z_RangeDec *p) static void Range_Normalize(CPpmd7z_RangeDec *p)
{ {
if (p->Range < kTopValue) { if (p->Range < kTopValue)
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); {
p->Range <<= 8; p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
if (p->Range < kTopValue) { p->Range <<= 8;
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); if (p->Range < kTopValue)
p->Range <<= 8; {
} p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
} p->Range <<= 8;
} }
}
static void Range_Decode(void *pp, UInt32 start, UInt32 size) }
{
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; static void Range_Decode(void *pp, UInt32 start, UInt32 size)
p->Code -= start * p->Range; {
p->Range *= size; CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
Range_Normalize(p); p->Code -= start * p->Range;
} p->Range *= size;
Range_Normalize(p);
static UInt32 Range_DecodeBit(void *pp, UInt32 size0) }
{
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
UInt32 newBound = (p->Range >> 14) * size0; {
UInt32 symbol; CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
if (p->Code < newBound) { UInt32 newBound = (p->Range >> 14) * size0;
symbol = 0; UInt32 symbol;
p->Range = newBound; if (p->Code < newBound)
} else { {
symbol = 1; symbol = 0;
p->Code -= newBound; p->Range = newBound;
p->Range -= newBound; }
} else
Range_Normalize(p); {
return symbol; symbol = 1;
} p->Code -= newBound;
p->Range -= newBound;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) }
{ Range_Normalize(p);
p->p.GetThreshold = Range_GetThreshold; return symbol;
p->p.Decode = Range_Decode; }
p->p.DecodeBit = Range_DecodeBit;
} void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{
#define MASK(sym) ((signed char *)charMask)[sym] p->p.GetThreshold = Range_GetThreshold;
p->p.Decode = Range_Decode;
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) p->p.DecodeBit = Range_DecodeBit;
{ }
size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1) {
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); #define MASK(sym) ((signed char *)charMask)[sym]
unsigned i;
UInt32 count, hiCnt; int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) { {
Byte symbol; size_t charMask[256 / sizeof(size_t)];
rc->Decode(rc, 0, s->Freq); if (p->MinContext->NumStats != 1)
p->FoundState = s; {
symbol = s->Symbol; CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
Ppmd7_Update1_0(p); unsigned i;
return symbol; UInt32 count, hiCnt;
} if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
p->PrevSuccess = 0; {
i = p->MinContext->NumStats - 1; Byte symbol;
do { rc->Decode(rc, 0, s->Freq);
if ((hiCnt += (++s)->Freq) > count) { p->FoundState = s;
Byte symbol; symbol = s->Symbol;
rc->Decode(rc, hiCnt - s->Freq, s->Freq); Ppmd7_Update1_0(p);
p->FoundState = s; return symbol;
symbol = s->Symbol; }
Ppmd7_Update1(p); p->PrevSuccess = 0;
return symbol; i = p->MinContext->NumStats - 1;
} do
} while (--i); {
if (count >= p->MinContext->SummFreq) if ((hiCnt += (++s)->Freq) > count)
return -2; {
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; Byte symbol;
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); rc->Decode(rc, hiCnt - s->Freq, s->Freq);
PPMD_SetAllBitsIn256Bytes(charMask); p->FoundState = s;
MASK(s->Symbol) = 0; symbol = s->Symbol;
i = p->MinContext->NumStats - 1; Ppmd7_Update1(p);
do { return symbol;
MASK((--s)->Symbol) = 0; }
} while (--i); }
} else { while (--i);
UInt16 *prob = Ppmd7_GetBinSumm(p); if (count >= p->MinContext->SummFreq)
if (rc->DecodeBit(rc, *prob) == 0) { return -2;
Byte symbol; p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; PPMD_SetAllBitsIn256Bytes(charMask);
Ppmd7_UpdateBin(p); MASK(s->Symbol) = 0;
return symbol; i = p->MinContext->NumStats - 1;
} do { MASK((--s)->Symbol) = 0; } while (--i);
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); }
p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; else
PPMD_SetAllBitsIn256Bytes(charMask); {
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; UInt16 *prob = Ppmd7_GetBinSumm(p);
p->PrevSuccess = 0; if (rc->DecodeBit(rc, *prob) == 0)
} {
for (;;) { Byte symbol;
CPpmd_State *ps[256], *s; *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
UInt32 freqSum, count, hiCnt; symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
CPpmd_See *see; Ppmd7_UpdateBin(p);
unsigned i, num, numMasked = p->MinContext->NumStats; return symbol;
do { }
p->OrderFall++; *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
if (!p->MinContext->Suffix) p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
return -1; PPMD_SetAllBitsIn256Bytes(charMask);
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
} while (p->MinContext->NumStats == numMasked); p->PrevSuccess = 0;
hiCnt = 0; }
s = Ppmd7_GetStats(p, p->MinContext); for (;;)
i = 0; {
num = p->MinContext->NumStats - numMasked; CPpmd_State *ps[256], *s;
do { UInt32 freqSum, count, hiCnt;
int k = (int)(MASK(s->Symbol)); CPpmd_See *see;
hiCnt += (s->Freq & k); unsigned i, num, numMasked = p->MinContext->NumStats;
ps[i] = s++; do
i -= k; {
} while (i != num); p->OrderFall++;
if (!p->MinContext->Suffix)
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); return -1;
freqSum += hiCnt; p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
count = rc->GetThreshold(rc, freqSum); }
while (p->MinContext->NumStats == numMasked);
if (count < hiCnt) { hiCnt = 0;
Byte symbol; s = Ppmd7_GetStats(p, p->MinContext);
CPpmd_State **pps = ps; i = 0;
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++) num = p->MinContext->NumStats - numMasked;
; do
s = *pps; {
rc->Decode(rc, hiCnt - s->Freq, s->Freq); int k = (int)(MASK(s->Symbol));
Ppmd_See_Update(see); hiCnt += (s->Freq & k);
p->FoundState = s; ps[i] = s++;
symbol = s->Symbol; i -= k;
Ppmd7_Update2(p); }
return symbol; while (i != num);
}
if (count >= freqSum) see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
return -2; freqSum += hiCnt;
rc->Decode(rc, hiCnt, freqSum - hiCnt); count = rc->GetThreshold(rc, freqSum);
see->Summ = (UInt16)(see->Summ + freqSum);
do { if (count < hiCnt)
MASK(ps[--i]->Symbol) = 0; {
} while (i != 0); Byte symbol;
} CPpmd_State **pps = ps;
} for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
s = *pps;
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
Ppmd_See_Update(see);
p->FoundState = s;
symbol = s->Symbol;
Ppmd7_Update2(p);
return symbol;
}
if (count >= freqSum)
return -2;
rc->Decode(rc, hiCnt, freqSum - hiCnt);
see->Summ = (UInt16)(see->Summ + freqSum);
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
}
}

View File

@ -49,12 +49,7 @@ typedef int WRes;
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) \ #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
{ \
int __result__ = (x); \
if (__result__ != 0) \
return __result__; \
}
#endif #endif
typedef unsigned char Byte; typedef unsigned char Byte;
@ -86,7 +81,7 @@ typedef unsigned __int64 UInt64;
#else #else
typedef long long int Int64; typedef long long int Int64;
typedef unsigned long long int UInt64; typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n##ULL #define UINT64_CONST(n) n ## ULL
#endif #endif
#endif #endif
@ -101,6 +96,7 @@ typedef int Bool;
#define True 1 #define True 1
#define False 0 #define False 0
#ifdef _WIN32 #ifdef _WIN32
#define MY_STD_CALL __stdcall #define MY_STD_CALL __stdcall
#else #else
@ -125,20 +121,24 @@ typedef int Bool;
#endif #endif
/* The following interfaces use first parameter as pointer to structure */ /* The following interfaces use first parameter as pointer to structure */
typedef struct { typedef struct
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ {
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn; } IByteIn;
typedef struct { typedef struct
void (*Write)(void *p, Byte b); {
void (*Write)(void *p, Byte b);
} IByteOut; } IByteOut;
typedef struct { typedef struct
SRes (*Read)(void *p, void *buf, size_t *size); {
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. SRes (*Read)(void *p, void *buf, size_t *size);
(output(*size) < input(*size)) is allowed */ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream; } ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */ /* it can return SZ_ERROR_INPUT_EOF */
@ -146,30 +146,38 @@ SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
typedef struct { typedef struct
size_t (*Write)(void *p, const void *buf, size_t size); {
/* Returns: result - the number of actually written bytes. size_t (*Write)(void *p, const void *buf, size_t size);
(result < size) means error */ /* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream; } ISeqOutStream;
typedef enum { SZ_SEEK_SET = 0, SZ_SEEK_CUR = 1, SZ_SEEK_END = 2 } ESzSeek; typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct { typedef struct
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ {
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream; } ISeekInStream;
typedef struct { typedef struct
SRes (*Look)(void *p, const void **buf, size_t *size); {
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. SRes (*Look)(void *p, const void **buf, size_t *size);
(output(*size) > input(*size)) is not allowed /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */ (output(*size) > input(*size)) is not allowed
SRes (*Skip)(void *p, size_t offset); (output(*size) < input(*size)) is allowed */
/* offset must be <= output(*size) of Look */ SRes (*Skip)(void *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size); SRes (*Read)(void *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */ /* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ILookInStream; } ILookInStream;
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
@ -181,40 +189,45 @@ SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14) #define LookToRead_BUF_SIZE (1 << 14)
typedef struct { typedef struct
ILookInStream s; {
ISeekInStream *realStream; ILookInStream s;
size_t pos; ISeekInStream *realStream;
size_t size; size_t pos;
Byte buf[LookToRead_BUF_SIZE]; size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead; } CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead); void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p); void LookToRead_Init(CLookToRead *p);
typedef struct { typedef struct
ISeqInStream s; {
ILookInStream *realStream; ISeqInStream s;
ILookInStream *realStream;
} CSecToLook; } CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p); void SecToLook_CreateVTable(CSecToLook *p);
typedef struct { typedef struct
ISeqInStream s; {
ILookInStream *realStream; ISeqInStream s;
ILookInStream *realStream;
} CSecToRead; } CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p); void SecToRead_CreateVTable(CSecToRead *p);
typedef struct { typedef struct
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); {
/* Returns: result. (result != SZ_OK) means break. SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
Value (UInt64)(Int64)-1 for size means unknown value. */ /* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress; } ICompressProgress;
typedef struct { typedef struct
void *(*Alloc)(void *p, size_t size); {
void (*Free)(void *p, void *address); /* address can be 0 */ void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc; } ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) #define IAlloc_Alloc(p, size) (p)->Alloc((p), size)

View File

@ -1,4 +1,4 @@
LZMA SDK 9.20 LZMA SDK 9.22
------------- -------------
LZMA SDK provides the documentation, samples, header files, libraries, LZMA SDK provides the documentation, samples, header files, libraries,
@ -24,6 +24,12 @@ Some code in LZMA SDK is based on public domain code from another developers:
1) PPMd var.H (2001): Dmitry Shkarin 1) PPMd var.H (2001): Dmitry Shkarin
2) SHA-256: Wei Dai (Crypto++ library) 2) SHA-256: Wei Dai (Crypto++ library)
You can copy, modify, distribute and perform LZMA SDK code, even for commercial purposes,
all without asking permission.
LZMA SDK code is compatible with open source licenses, for example, you can
include it to GNU GPL or GNU LGPL code.
LZMA SDK Contents LZMA SDK Contents
----------------- -----------------