Some formating things

This commit is contained in:
Zach Bacon 2016-07-31 19:55:24 -04:00
parent 84650620c2
commit a986b42e23
No known key found for this signature in database
GPG Key ID: 7D110798AFE84B3A
27 changed files with 4164 additions and 4456 deletions

View File

@ -13,115 +13,113 @@ EXTERN_C_BEGIN
extern Byte k7zSignature[k7zSignatureSize]; extern Byte k7zSignature[k7zSignatureSize];
#define k7zMajorVersion 0 #define k7zMajorVersion 0
enum EIdEnum enum EIdEnum {
{ k7zIdEnd,
k7zIdEnd, k7zIdHeader,
k7zIdHeader, k7zIdArchiveProperties,
k7zIdArchiveProperties, k7zIdAdditionalStreamsInfo,
k7zIdAdditionalStreamsInfo, k7zIdMainStreamsInfo,
k7zIdMainStreamsInfo, k7zIdFilesInfo,
k7zIdFilesInfo, k7zIdPackInfo,
k7zIdPackInfo, k7zIdUnpackInfo,
k7zIdUnpackInfo, k7zIdSubStreamsInfo,
k7zIdSubStreamsInfo, k7zIdSize,
k7zIdSize, k7zIdCRC,
k7zIdCRC, k7zIdFolder,
k7zIdFolder, k7zIdCodersUnpackSize,
k7zIdCodersUnpackSize, k7zIdNumUnpackStream,
k7zIdNumUnpackStream, k7zIdEmptyStream,
k7zIdEmptyStream, k7zIdEmptyFile,
k7zIdEmptyFile, k7zIdAnti,
k7zIdAnti, k7zIdName,
k7zIdName, k7zIdCTime,
k7zIdCTime, k7zIdATime,
k7zIdATime, k7zIdMTime,
k7zIdMTime, k7zIdWinAttributes,
k7zIdWinAttributes, k7zIdComment,
k7zIdComment, k7zIdEncodedHeader,
k7zIdEncodedHeader, k7zIdStartPos,
k7zIdStartPos, k7zIdDummy
k7zIdDummy
}; };
typedef struct typedef struct
{ {
UInt32 NumInStreams; UInt32 NumInStreams;
UInt32 NumOutStreams; UInt32 NumOutStreams;
UInt64 MethodID; UInt64 MethodID;
CBuf Props; 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 InIndex;
UInt32 OutIndex; UInt32 OutIndex;
} CSzBindPair; } CSzBindPair;
typedef struct typedef struct
{ {
CSzCoderInfo *Coders; CSzCoderInfo* Coders;
CSzBindPair *BindPairs; CSzBindPair* BindPairs;
UInt32 *PackStreams; UInt32* PackStreams;
UInt64 *UnpackSizes; UInt64* UnpackSizes;
UInt32 NumCoders; UInt32 NumCoders;
UInt32 NumBindPairs; UInt32 NumBindPairs;
UInt32 NumPackStreams; UInt32 NumPackStreams;
int UnpackCRCDefined; int UnpackCRCDefined;
UInt32 UnpackCRC; UInt32 UnpackCRC;
UInt32 NumUnpackStreams; UInt32 NumUnpackStreams;
} CSzFolder; } CSzFolder;
void SzFolder_Init(CSzFolder *p); void SzFolder_Init(CSzFolder* p);
UInt64 SzFolder_GetUnpackSize(CSzFolder *p); UInt64 SzFolder_GetUnpackSize(CSzFolder* p);
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex); 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, SRes SzFolder_Decode(const CSzFolder* folder, const UInt64* packSizes,
ILookInStream *stream, UInt64 startPos, ILookInStream* stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); Byte* outBuffer, size_t outSize, ISzAlloc* allocMain);
typedef struct typedef struct
{ {
UInt32 Low; UInt32 Low;
UInt32 High; UInt32 High;
} CNtfsFileTime; } CNtfsFileTime;
typedef struct typedef struct
{ {
CNtfsFileTime MTime; CNtfsFileTime MTime;
UInt64 Size; UInt64 Size;
UInt32 Crc; UInt32 Crc;
UInt32 Attrib; UInt32 Attrib;
Byte HasStream; Byte HasStream;
Byte IsDir; Byte IsDir;
Byte IsAnti; Byte IsAnti;
Byte CrcDefined; Byte CrcDefined;
Byte MTimeDefined; Byte MTimeDefined;
Byte AttribDefined; Byte AttribDefined;
} CSzFileItem; } CSzFileItem;
void SzFile_Init(CSzFileItem *p); void SzFile_Init(CSzFileItem* p);
typedef struct typedef struct
{ {
UInt64 *PackSizes; UInt64* PackSizes;
Byte *PackCRCsDefined; Byte* PackCRCsDefined;
UInt32 *PackCRCs; UInt32* PackCRCs;
CSzFolder *Folders; CSzFolder* Folders;
CSzFileItem *Files; CSzFileItem* Files;
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 NumFolders; UInt32 NumFolders;
UInt32 NumFiles; 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
@ -145,24 +143,24 @@ void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
typedef struct typedef struct
{ {
CSzAr db; CSzAr db;
UInt64 startPosAfterHeader; UInt64 startPosAfterHeader;
UInt64 dataPos; UInt64 dataPos;
UInt32 *FolderStartPackStreamIndex; UInt32* FolderStartPackStreamIndex;
UInt64 *PackStreamStartPositions; UInt64* PackStreamStartPositions;
UInt32 *FolderStartFileIndex; UInt32* FolderStartFileIndex;
UInt32 *FileIndexToFolderIndexMap; UInt32* FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */ size_t* FileNameOffsets; /* in 2-byte steps */
CBuf FileNames; /* UTF-16-LE */ CBuf FileNames; /* UTF-16-LE */
} CSzArEx; } CSzArEx;
void SzArEx_Init(CSzArEx *p); void SzArEx_Init(CSzArEx* p);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); void SzArEx_Free(CSzArEx* p, ISzAlloc* alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder); UInt64 SzArEx_GetFolderStreamPos(const CSzArEx* p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize); int SzArEx_GetFolderFullPackSize(const CSzArEx* p, UInt32 folderIndex, UInt64* resSize);
/* /*
if dest == NULL, the return value specifies the required size of the buffer, if dest == NULL, the return value specifies the required size of the buffer,
@ -170,20 +168,19 @@ if dest == NULL, the return value specifies the required size of the buffer,
if dest != NULL, the return value specifies the number of 16-bit characters that if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */ are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); size_t SzArEx_GetFileNameUtf16(const CSzArEx* p, size_t fileIndex, UInt16* dest);
SRes SzArEx_Extract( SRes SzArEx_Extract(
const CSzArEx *db, const CSzArEx* db,
ILookInStream *inStream, ILookInStream* inStream,
UInt32 fileIndex, /* index of file */ UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */ UInt32* blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ Byte** outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */ size_t* outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */ size_t* offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */ size_t* outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain, ISzAlloc* allocMain,
ISzAlloc *allocTemp); ISzAlloc* allocTemp);
/* /*
SzArEx_Open Errors: SzArEx_Open Errors:
@ -196,7 +193,7 @@ SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL SZ_ERROR_FAIL
*/ */
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); SRes SzArEx_Open(CSzArEx* p, ILookInStream* inStream, ISzAlloc* allocMain, ISzAlloc* allocTemp);
EXTERN_C_END EXTERN_C_END

View File

@ -18,59 +18,57 @@ int g_allocCountTemp = 0;
#endif #endif
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--;
g_allocCount--; fprintf(stderr, "\nFree; count = %10d", g_allocCount);
fprintf(stderr, "\nFree; count = %10d", g_allocCount); }
} #endif
#endif free(address);
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--;
g_allocCountTemp--; fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp); }
} #ifdef _WIN32
#ifdef _WIN32 HeapFree(GetProcessHeap(), 0, address);
HeapFree(GetProcessHeap(), 0, address); return;
return; #endif
#endif #endif
#endif free(address);
free(address);
} }

View File

@ -6,10 +6,10 @@
#include <stdlib.h> #include <stdlib.h>
void *SzAlloc(void *p, size_t size); void* SzAlloc(void* p, size_t size);
void SzFree(void *p, void *address); void SzFree(void* p, void* address);
void *SzAllocTemp(void *p, size_t size); void* SzAllocTemp(void* p, size_t size);
void SzFreeTemp(void *p, void *address); void SzFreeTemp(void* p, void* address);
#endif #endif

View File

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

View File

@ -12,25 +12,25 @@ extern "C" {
typedef struct typedef struct
{ {
Byte *data; Byte* data;
size_t size; 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; Byte* data;
size_t size; size_t size;
size_t pos; size_t pos;
} CDynBuf; } CDynBuf;
void DynBuf_Construct(CDynBuf *p); void DynBuf_Construct(CDynBuf* p);
void DynBuf_SeekToBeg(CDynBuf *p); void DynBuf_SeekToBeg(CDynBuf* p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc); int DynBuf_Write(CDynBuf* p, const Byte* buf, size_t size, ISzAlloc* alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc); void DynBuf_Free(CDynBuf* p, ISzAlloc* alloc);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,77 +7,74 @@
#define kCrcPoly 0xEDB88320 #define kCrcPoly 0xEDB88320
#ifdef MY_CPU_X86_OR_AMD64 #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); UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void* data, size_t size, const UInt32* table);
#elif defined(MY_CPU_LE) #elif defined(MY_CPU_LE)
#define CRC_NUM_TABLES 4 #define CRC_NUM_TABLES 4
#else #else
#define CRC_NUM_TABLES 5 #define CRC_NUM_TABLES 5
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void* data, size_t size, const UInt32* table);
#endif #endif
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void* data, size_t size, const UInt32* table);
#endif #endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); typedef UInt32(MY_FAST_CALL* CRC_FUNC)(UInt32 v, const void* data, size_t size, const UInt32* table);
static CRC_FUNC g_CrcUpdate; static CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void* data, size_t size)
{ {
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;
UInt32 r = i; unsigned j;
unsigned j; for (j = 0; j < 8; j++)
for (j = 0; j < 8; j++) r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); g_CrcTable[i] = r;
g_CrcTable[i] = r;
}
for (; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
#ifdef MY_CPU_LE
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES == 8
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;
} }
} for (; i < 256 * CRC_NUM_TABLES; i++) {
#endif UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
#ifdef MY_CPU_LE
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES == 8
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

@ -17,8 +17,8 @@ void MY_FAST_CALL CrcGenerateTable(void);
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) #define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void* data, size_t size);
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); UInt32 MY_FAST_CALL CrcCalc(const void* data, size_t size);
EXTERN_C_END EXTERN_C_END

View File

@ -7,58 +7,47 @@
#ifndef MY_CPU_BE #ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void* data, size_t size, const UInt32* table)
{ {
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 ^= *(const UInt32 *)p; v = table[0x300 + (v & 0xFF)] ^ table[0x200 + ((v >> 8) & 0xFF)] ^ 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 #endif
#ifndef MY_CPU_LE #ifndef MY_CPU_LE
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void* data, size_t size, const UInt32* table)
{ {
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);
v = CRC_UINT32_SWAP(v); v = CRC_UINT32_SWAP(v);
table += 0x100; table += 0x100;
for (; size >= 4; size -= 4, p += 4) for (; size >= 4; size -= 4, p += 4) {
{ v ^= *(const UInt32*)p;
v ^= *(const UInt32 *)p; v = table[0x000 + (v & 0xFF)] ^ table[0x100 + ((v >> 8) & 0xFF)] ^ table[0x200 + ((v >> 16) & 0xFF)] ^ table[0x300 + ((v >> 24))];
v = }
table[0x000 + (v & 0xFF)] ^ table -= 0x100;
table[0x100 + ((v >> 8) & 0xFF)] ^ v = CRC_UINT32_SWAP(v);
table[0x200 + ((v >> 16) & 0xFF)] ^ for (; size > 0; size--, p++)
table[0x300 + ((v >> 24))]; v = CRC_UPDATE_BYTE_2(v, *p);
} return v;
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

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

@ -5,165 +5,159 @@
#include "Types.h" #include "Types.h"
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(ISeqInStream* stream, void* buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0) {
{ size_t processed = size;
size_t processed = size; RINOK(stream->Read(stream, buf, &processed));
RINOK(stream->Read(stream, buf, &processed)); if (processed == 0)
if (processed == 0) return errorType;
return errorType; buf = (void*)((Byte*)buf + processed);
buf = (void *)((Byte *)buf + processed); size -= processed;
size -= processed; }
}
return SZ_OK;
}
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
{
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
{
size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
}
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
{
Int64 t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET);
}
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
{
const void *lookBuf;
if (*size == 0)
return SZ_OK; return SZ_OK;
RINOK(stream->Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size);
} }
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read(ISeqInStream* stream, void* buf, size_t size)
{ {
while (size != 0) return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
{ }
size_t processed = size;
SRes SeqInStream_ReadByte(ISeqInStream* stream, Byte* buf)
{
size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed)); RINOK(stream->Read(stream, buf, &processed));
if (processed == 0) return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
return errorType;
buf = (void *)((Byte *)buf + processed);
size -= processed;
}
return SZ_OK;
} }
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) SRes LookInStream_SeekTo(ILookInStream* stream, UInt64 offset)
{ {
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); Int64 t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET);
} }
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) SRes LookInStream_LookRead(ILookInStream* stream, void* buf, size_t* size)
{ {
SRes res = SZ_OK; const void* lookBuf;
CLookToRead *p = (CLookToRead *)pp; if (*size == 0)
size_t size2 = p->size - p->pos; return SZ_OK;
if (size2 == 0 && *size > 0) RINOK(stream->Look(stream, &lookBuf, size));
{ memcpy(buf, lookBuf, *size);
p->pos = 0; return stream->Skip(stream, *size);
size2 = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, &size2);
p->size = size2;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
} }
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) SRes LookInStream_Read2(ILookInStream* stream, void* buf, size_t size, SRes errorType)
{ {
SRes res = SZ_OK; while (size != 0) {
CLookToRead *p = (CLookToRead *)pp; size_t processed = size;
size_t size2 = p->size - p->pos; RINOK(stream->Read(stream, buf, &processed));
if (size2 == 0 && *size > 0) if (processed == 0)
{ return errorType;
p->pos = 0; buf = (void*)((Byte*)buf + processed);
if (*size > LookToRead_BUF_SIZE) size -= processed;
*size = LookToRead_BUF_SIZE; }
res = p->realStream->Read(p->realStream, p->buf, size); return SZ_OK;
size2 = p->size = *size;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
} }
static SRes LookToRead_Skip(void *pp, size_t offset) SRes LookInStream_Read(ILookInStream* stream, void* buf, size_t size)
{ {
CLookToRead *p = (CLookToRead *)pp; return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
p->pos += offset;
return SZ_OK;
} }
static SRes LookToRead_Read(void *pp, void *buf, size_t *size) static SRes LookToRead_Look_Lookahead(void* pp, const void** buf, size_t* size)
{ {
CLookToRead *p = (CLookToRead *)pp; SRes res = SZ_OK;
size_t rem = p->size - p->pos; CLookToRead* p = (CLookToRead*)pp;
if (rem == 0) size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) {
p->pos = 0;
size2 = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, &size2);
p->size = size2;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
static SRes LookToRead_Look_Exact(void* pp, const void** buf, size_t* size)
{
SRes res = SZ_OK;
CLookToRead* p = (CLookToRead*)pp;
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) {
p->pos = 0;
if (*size > LookToRead_BUF_SIZE)
*size = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, size);
size2 = p->size = *size;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
static SRes LookToRead_Skip(void* pp, size_t offset)
{
CLookToRead* p = (CLookToRead*)pp;
p->pos += offset;
return SZ_OK;
}
static SRes LookToRead_Read(void* pp, void* buf, size_t* size)
{
CLookToRead* p = (CLookToRead*)pp;
size_t rem = p->size - p->pos;
if (rem == 0)
return p->realStream->Read(p->realStream, buf, size);
if (rem > *size)
rem = *size;
memcpy(buf, p->buf + p->pos, rem);
p->pos += rem;
*size = rem;
return SZ_OK;
}
static SRes LookToRead_Seek(void* pp, Int64* pos, ESzSeek origin)
{
CLookToRead* p = (CLookToRead*)pp;
p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin);
}
void LookToRead_CreateVTable(CLookToRead* p, int lookahead)
{
p->s.Look = lookahead ? LookToRead_Look_Lookahead : LookToRead_Look_Exact;
p->s.Skip = LookToRead_Skip;
p->s.Read = LookToRead_Read;
p->s.Seek = LookToRead_Seek;
}
void LookToRead_Init(CLookToRead* p)
{
p->pos = p->size = 0;
}
static SRes SecToLook_Read(void* pp, void* buf, size_t* size)
{
CSecToLook* p = (CSecToLook*)pp;
return LookInStream_LookRead(p->realStream, buf, size);
}
void SecToLook_CreateVTable(CSecToLook* p)
{
p->s.Read = SecToLook_Read;
}
static SRes SecToRead_Read(void* pp, void* buf, size_t* size)
{
CSecToRead* p = (CSecToRead*)pp;
return p->realStream->Read(p->realStream, buf, size); return p->realStream->Read(p->realStream, buf, size);
if (rem > *size)
rem = *size;
memcpy(buf, p->buf + p->pos, rem);
p->pos += rem;
*size = rem;
return SZ_OK;
} }
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin) void SecToRead_CreateVTable(CSecToRead* p)
{ {
CLookToRead *p = (CLookToRead *)pp; p->s.Read = SecToRead_Read;
p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin);
}
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
{
p->s.Look = lookahead ?
LookToRead_Look_Lookahead :
LookToRead_Look_Exact;
p->s.Skip = LookToRead_Skip;
p->s.Read = LookToRead_Read;
p->s.Seek = LookToRead_Seek;
}
void LookToRead_Init(CLookToRead *p)
{
p->pos = p->size = 0;
}
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
{
CSecToLook *p = (CSecToLook *)pp;
return LookInStream_LookRead(p->realStream, buf, size);
}
void SecToLook_CreateVTable(CSecToLook *p)
{
p->s.Read = SecToLook_Read;
}
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
{
CSecToRead *p = (CSecToRead *)pp;
return p->realStream->Read(p->realStream, buf, size);
}
void SecToRead_CreateVTable(CSecToRead *p)
{
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,113 +20,134 @@
#define kNumMoveBits 5 #define kNumMoveBits 5
#define RC_READ_BYTE (*buffer++) #define RC_READ_BYTE (*buffer++)
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } #define RC_TEST \
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ { \
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} if (buffer == bufferLim) \
return SZ_ERROR_DATA; \
}
#define RC_INIT2 \
code = 0; \
range = 0xFFFFFFFF; \
{ \
int i; \
for (i = 0; i < 5; i++) { \
RC_TEST; \
code = (code << 8) | RC_READ_BYTE; \
} \
}
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } #define NORMALIZE \
if (range < kTopValue) { \
RC_TEST; \
range <<= 8; \
code = (code << 8) | RC_READ_BYTE; \
}
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) #define IF_BIT_0(p) \
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; ttt = *(p); \
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; \
if (code < bound)
#define UPDATE_0(p) \
range = bound; \
*(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); \
NORMALIZE;
#define UPDATE_1(p) \
range -= bound; \
code -= bound; \
*(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); \
NORMALIZE;
int Bcj2_Decode( int Bcj2_Decode(
const Byte *buf0, SizeT size0, const Byte* buf0, SizeT size0,
const Byte *buf1, SizeT size1, const Byte* buf1, SizeT size1,
const Byte *buf2, SizeT size2, const Byte* buf2, SizeT size2,
const Byte *buf3, SizeT size3, const Byte* buf3, SizeT size3,
Byte *outBuf, SizeT outSize) 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;
Byte b; CProb* prob;
CProb *prob; UInt32 bound;
UInt32 bound; UInt32 ttt;
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];
Byte b = buf0[inPos]; outBuf[outPos++] = b;
outBuf[outPos++] = b; if (IsJ(prevByte, b))
if (IsJ(prevByte, b)) break;
break; inPos++;
inPos++; prevByte = b;
prevByte = b; limit--;
limit--; }
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevByte;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
IF_BIT_0(prob)
{
UPDATE_0(prob)
prevByte = b;
}
else
{
UInt32 dest;
const Byte* v;
UPDATE_1(prob)
if (b == 0xE8) {
v = buf1;
if (size1 < 4)
return SZ_ERROR_DATA;
buf1 += 4;
size1 -= 4;
} else {
v = buf2;
if (size2 < 4)
return SZ_ERROR_DATA;
buf2 += 4;
size2 -= 4;
}
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest;
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 8);
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 16);
if (outPos == outSize)
break;
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
}
} }
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevByte;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
IF_BIT_0(prob)
{
UPDATE_0(prob)
prevByte = b;
}
else
{
UInt32 dest;
const Byte *v;
UPDATE_1(prob)
if (b == 0xE8)
{
v = buf1;
if (size1 < 4)
return SZ_ERROR_DATA;
buf1 += 4;
size1 -= 4;
}
else
{
v = buf2;
if (size2 < 4)
return SZ_ERROR_DATA;
buf2 += 4;
size2 -= 4;
}
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest;
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 8);
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 16);
if (outPos == outSize)
break;
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
}
}
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
} }

View File

@ -25,11 +25,11 @@ Returns:
*/ */
int Bcj2_Decode( int Bcj2_Decode(
const Byte *buf0, SizeT size0, const Byte* buf0, SizeT size0,
const Byte *buf1, SizeT size1, const Byte* buf1, SizeT size1,
const Byte *buf2, SizeT size2, const Byte* buf2, SizeT size2,
const Byte *buf3, SizeT size3, const Byte* buf3, SizeT size3,
Byte *outBuf, SizeT outSize); Byte* outBuf, SizeT outSize);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -3,131 +3,110 @@
#include "Bra.h" #include "Bra.h"
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) SizeT ARM_Convert(Byte* data, SizeT size, UInt32 ip, int encoding)
{ {
SizeT i; 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) {
if (data[i + 3] == 0xEB) UInt32 dest;
{ 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) {
if ((data[i + 1] & 0xF8) == 0xF0 && UInt32 dest;
(data[i + 3] & 0xF8) == 0xF8) UInt32 src = (((UInt32)data[i + 1] & 0x7) << 19) | ((UInt32)data[i + 0] << 11) | (((UInt32)data[i + 3] & 0x7) << 8) | (data[i + 2]);
{
UInt32 dest;
UInt32 src =
(((UInt32)data[i + 1] & 0x7) << 19) |
((UInt32)data[i + 0] << 11) |
(((UInt32)data[i + 3] & 0x7) << 8) |
(data[i + 2]);
src <<= 1; src <<= 1;
if (encoding) if (encoding)
dest = ip + (UInt32)i + src; dest = ip + (UInt32)i + src;
else else
dest = src - (ip + (UInt32)i); dest = src - (ip + (UInt32)i);
dest >>= 1; dest >>= 1;
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7)); data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
data[i + 0] = (Byte)(dest >> 11); data[i + 0] = (Byte)(dest >> 11);
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7)); data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
data[i + 2] = (Byte)dest; data[i + 2] = (Byte)dest;
i += 2; i += 2;
}
} }
} return i;
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) {
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) | ((UInt32)data[i + 1] << 16) | ((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3] & (~3));
{
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3] & (~3));
UInt32 dest; UInt32 dest;
if (encoding) if (encoding)
dest = ip + (UInt32)i + src; dest = ip + (UInt32)i + src;
else else
dest = src - (ip + (UInt32)i); dest = src - (ip + (UInt32)i);
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3)); data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
data[i + 1] = (Byte)(dest >> 16); data[i + 1] = (Byte)(dest >> 16);
data[i + 2] = (Byte)(dest >> 8); data[i + 2] = (Byte)(dest >> 8);
data[i + 3] &= 0x3; data[i + 3] &= 0x3;
data[i + 3] |= dest; data[i + 3] |= dest;
}
} }
} return i;
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) | ((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3]);
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) 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; src <<= 2;
if (encoding) if (encoding)
dest = ip + i + src; dest = ip + i + src;
else else
dest = src - (ip + i); dest = src - (ip + i);
dest >>= 2; dest >>= 2;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
data[i + 0] = (Byte)(dest >> 24); data[i + 0] = (Byte)(dest >> 24);
data[i + 1] = (Byte)(dest >> 16); data[i + 1] = (Byte)(dest >> 16);
data[i + 2] = (Byte)(dest >> 8); data[i + 2] = (Byte)(dest >> 8);
data[i + 3] = (Byte)dest; data[i + 3] = (Byte)dest;
}
} }
} return i;
return i;
} }

View File

@ -53,13 +53,16 @@ in CALL instructions to increase the compression ratio.
} }
*/ */
#define x86_Convert_Init(state) { state = 0; } #define x86_Convert_Init(state) \
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); { \
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); state = 0; \
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); }
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT x86_Convert(Byte* data, SizeT size, UInt32 ip, UInt32* state, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARM_Convert(Byte* data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); SizeT ARMT_Convert(Byte* data, SizeT size, UInt32 ip, int encoding);
SizeT PPC_Convert(Byte* data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte* data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte* data, SizeT size, UInt32 ip, int encoding);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

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

View File

@ -12,157 +12,160 @@
#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)
#endif : "c"(flag));
return flag; #endif
return flag;
} }
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; #define CHECK_CPUID_IS_SUPPORTED \
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
__asm__ __volatile__ ( __asm__ __volatile__(
"cpuid" "cpuid"
: "=a" (*a) , : "=a"(*a),
"=b" (*b) , "=b"(*b),
"=c" (*c) , "=c"(*c),
"=d" (*d) "=d"(*d)
: "0" (function)) ; : "0"(function));
#endif #endif
#else #else
int CPUInfo[4]; int CPUInfo[4];
__cpuid(CPUInfo, function); __cpuid(CPUInfo, function);
*a = CPUInfo[0]; *a = CPUInfo[0];
*b = CPUInfo[1]; *b = CPUInfo[1];
*c = CPUInfo[2]; *c = CPUInfo[2];
*d = CPUInfo[3]; *d = CPUInfo[3];
#endif #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] = static UInt32 kVendors[][3] = {
{ { 0x756E6547, 0x49656E69, 0x6C65746E },
{ 0x756E6547, 0x49656E69, 0x6C65746E}, { 0x68747541, 0x69746E65, 0x444D4163 },
{ 0x68747541, 0x69746E65, 0x444D4163}, { 0x746E6543, 0x48727561, 0x736C7561 }
{ 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];
const UInt32 *v = kVendors[i]; if (v[0] == p->vendor[0] && v[1] == p->vendor[1] && v[2] == p->vendor[2])
if (v[0] == p->vendor[0] && return (int)i;
v[1] == p->vendor[1] && }
v[2] == p->vendor[2]) return -1;
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;
family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p);
firm = x86cpuid_GetFirm(&p);
switch (firm) {
case CPU_FIRM_INTEL:
return (family < 6 || (family == 6 && model == 0x100C));
case CPU_FIRM_AMD:
return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA:
return (family < 6 || (family == 6 && model < 0xF));
}
return True; return True;
family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p);
firm = x86cpuid_GetFirm(&p);
switch (firm)
{
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
}
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 if (!CPU_Sys_Is_SSE_Supported()) return False; #define CHECK_SYS_SSE_SUPPORT \
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

@ -48,11 +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) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__) #if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
#define MY_CPU_LE #define MY_CPU_LE
#endif #endif
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__) #if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif
@ -62,38 +62,44 @@ Stop_Compiling_Bad_Endian
#ifdef MY_CPU_LE_UNALIGN #ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(p)) #define GetUi16(p) (*(const UInt16*)(p))
#define GetUi32(p) (*(const UInt32 *)(p)) #define GetUi32(p) (*(const UInt32*)(p))
#define GetUi64(p) (*(const UInt64 *)(p)) #define GetUi64(p) (*(const UInt64*)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d); #define SetUi16(p, d) *(UInt16*)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d); #define SetUi32(p, d) *(UInt32*)(p) = (d);
#define SetUi64(p, d) *(UInt64 *)(p) = (d); #define SetUi64(p, d) *(UInt64*)(p) = (d);
#else #else
#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] | \ ((const Byte*)(p))[0] | ((UInt32)((const Byte*)(p))[1] << 8) | ((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) { UInt32 _x_ = (d); \ #define SetUi16(p, d) \
((Byte *)(p))[0] = (Byte)_x_; \ { \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); } UInt32 _x_ = (d); \
((Byte*)(p))[0] = (Byte)_x_; \
((Byte*)(p))[1] = (Byte)(_x_ >> 8); \
}
#define SetUi32(p, d) { UInt32 _x_ = (d); \ #define SetUi32(p, d) \
((Byte *)(p))[0] = (Byte)_x_; \ { \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ UInt32 _x_ = (d); \
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ ((Byte*)(p))[0] = (Byte)_x_; \
((Byte *)(p))[3] = (Byte)(_x_ >> 24); } ((Byte*)(p))[1] = (Byte)(_x_ >> 8); \
((Byte*)(p))[2] = (Byte)(_x_ >> 16); \
((Byte*)(p))[3] = (Byte)(_x_ >> 24); \
}
#define SetUi64(p, d) { UInt64 _x64_ = (d); \ #define SetUi64(p, d) \
SetUi32(p, (UInt32)_x64_); \ { \
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); } UInt64 _x64_ = (d); \
SetUi32(p, (UInt32)_x64_); \
SetUi32(((Byte*)(p)) + 4, (UInt32)(_x64_ >> 32)); \
}
#endif #endif
@ -101,45 +107,40 @@ Stop_Compiling_Bad_Endian
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64) #pragma intrinsic(_byteswap_uint64)
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) _byteswap_ulong(*(const UInt32*)(const Byte*)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) _byteswap_uint64(*(const UInt64*)(const Byte*)(p))
#else #else
#define GetBe32(p) ( \ #define GetBe32(p) ( \
((UInt32)((const Byte *)(p))[0] << 24) | \ ((UInt32)((const Byte*)(p))[0] << 24) | ((UInt32)((const Byte*)(p))[1] << 16) | ((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))
#endif #endif
#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 maxFunc;
UInt32 vendor[3]; UInt32 vendor[3];
UInt32 ver; UInt32 ver;
UInt32 b; UInt32 b;
UInt32 c; UInt32 c;
UInt32 d; UInt32 d;
} Cx86cpuid; } Cx86cpuid;
enum enum {
{ CPU_FIRM_INTEL,
CPU_FIRM_INTEL, CPU_FIRM_AMD,
CPU_FIRM_AMD, CPU_FIRM_VIA
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);
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F) #define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F) #define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)

View File

@ -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,307 +44,284 @@
#define PRF(x) #define PRF(x)
#endif #endif
typedef enum typedef enum {
{ LZMA2_STATE_CONTROL,
LZMA2_STATE_CONTROL, LZMA2_STATE_UNPACK0,
LZMA2_STATE_UNPACK0, LZMA2_STATE_UNPACK1,
LZMA2_STATE_UNPACK1, LZMA2_STATE_PACK0,
LZMA2_STATE_PACK0, LZMA2_STATE_PACK1,
LZMA2_STATE_PACK1, LZMA2_STATE_PROP,
LZMA2_STATE_PROP, LZMA2_STATE_DATA,
LZMA2_STATE_DATA, LZMA2_STATE_DATA_CONT,
LZMA2_STATE_DATA_CONT, LZMA2_STATE_FINISHED,
LZMA2_STATE_FINISHED, LZMA2_STATE_ERROR
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: case LZMA2_STATE_CONTROL:
p->control = b; p->control = b;
PRF(printf("\n %4X ", p->decoder.dicPos)); PRF(printf("\n %4X ", p->decoder.dicPos));
PRF(printf(" %2X", b)); PRF(printf(" %2X", b));
if (p->control == 0) if (p->control == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p)) {
{ if ((p->control & 0x7F) > 2)
if ((p->control & 0x7F) > 2) return LZMA2_STATE_ERROR;
return LZMA2_STATE_ERROR; p->unpackSize = 0;
p->unpackSize = 0; } else
} p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
else return LZMA2_STATE_UNPACK0;
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0: case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8; p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1; return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1: case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b; p->unpackSize |= (UInt32)b;
p->unpackSize++; p->unpackSize++;
PRF(printf(" %8d", p->unpackSize)); PRF(printf(" %8d", p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8; p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1; return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1: case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b; p->packSize |= (UInt32)b;
p->packSize++; p->packSize++;
PRF(printf(" %8d", p->packSize)); PRF(printf(" %8d", p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP : (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP: case LZMA2_STATE_PROP: {
{ int lc, lp;
int lc, lp; if (b >= (9 * 5 * 5))
if (b >= (9 * 5 * 5)) return LZMA2_STATE_ERROR;
return LZMA2_STATE_ERROR; lc = b % 9;
lc = b % 9; b /= 9;
b /= 9; p->decoder.prop.pb = b / 5;
p->decoder.prop.pb = b / 5; lp = b % 5;
lp = b % 5; if (lc + lp > LZMA2_LCLP_MAX)
if (lc + lp > LZMA2_LCLP_MAX) return LZMA2_STATE_ERROR;
return LZMA2_STATE_ERROR; p->decoder.prop.lc = lc;
p->decoder.prop.lc = lc; p->decoder.prop.lp = lp;
p->decoder.prop.lp = lp; p->needInitProp = False;
p->needInitProp = False; return LZMA2_STATE_DATA;
return LZMA2_STATE_DATA;
} }
} }
return LZMA2_STATE_ERROR; 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, SRes Lzma2Dec_DecodeToDic(CLzma2Dec* p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) const Byte* src, SizeT* srcLen, ELzmaFinishMode finishMode, ELzmaStatus* status)
{ {
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;
SizeT dicPos = p->decoder.dicPos; if (p->state == LZMA2_STATE_ERROR)
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
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;
}
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; return SZ_ERROR_DATA;
p->needInitDic = False; if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) {
LzmaDec_InitDicAndState(&p->decoder, initDic, False); *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
} }
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) {
if (*srcLen == inSize) {
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
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 (srcSizeCur > destSizeCur) if (p->unpackSize <= destSizeCur) {
srcSizeCur = destSizeCur; destSizeCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
if (srcSizeCur == 0) if (LZMA2_IS_UNCOMPRESSED_STATE(p)) {
return SZ_ERROR_DATA; if (*srcLen == inSize) {
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); 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);
}
src += srcSizeCur; if (srcSizeCur > destSizeCur)
*srcLen += srcSizeCur; srcSizeCur = destSizeCur;
p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; if (srcSizeCur == 0)
} return SZ_ERROR_DATA;
else
{ LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
SizeT outSizeProcessed;
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;
}
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; SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
if (p->state == LZMA2_STATE_DATA) p->decoder.dicPos = 0;
{ dicPos = p->decoder.dicPos;
int mode = LZMA2_GET_LZMA_MODE(p); if (outSize > p->decoder.dicBufSize - dicPos) {
Bool initDic = (mode == 3); outSizeCur = p->decoder.dicBufSize;
Bool initState = (mode > 0); curFinishMode = LZMA_FINISH_ANY;
if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) } else {
return SZ_ERROR_DATA; outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
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);
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur; src += srcSizeCur;
inSize -= srcSizeCur;
*srcLen += srcSizeCur; *srcLen += srcSizeCur;
p->packSize -= (UInt32)srcSizeCur; outSizeCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
outSizeProcessed = p->decoder.dicPos - dicPos; dest += outSizeCur;
p->unpackSize -= (UInt32)outSizeProcessed; outSize -= outSizeCur;
*destLen += outSizeCur;
RINOK(res); if (res != 0)
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) return res;
return res; if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
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;
} }
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) SRes Lzma2Decode(Byte* dest, SizeT* destLen, const Byte* src, SizeT* srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus* status, ISzAlloc* alloc)
{ {
SizeT outSize = *destLen, inSize = *srcLen; CLzma2Dec p;
*srcLen = *destLen = 0;
for (;;)
{
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res; SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize) SizeT outSize = *destLen, inSize = *srcLen;
p->decoder.dicPos = 0; *destLen = *srcLen = 0;
dicPos = p->decoder.dicPos; *status = LZMA_STATUS_NOT_SPECIFIED;
if (outSize > p->decoder.dicBufSize - dicPos) Lzma2Dec_Construct(&p);
{ RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
outSizeCur = p->decoder.dicBufSize; p.decoder.dic = dest;
curFinishMode = LZMA_FINISH_ANY; p.decoder.dicBufSize = outSize;
} Lzma2Dec_Init(&p);
else *srcLen = inSize;
{ res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
outSizeCur = dicPos + outSize; *destLen = p.decoder.dicPos;
curFinishMode = finishMode; if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
} res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc);
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); return res;
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

@ -14,24 +14,23 @@ extern "C" {
typedef struct typedef struct
{ {
CLzmaDec decoder; CLzmaDec decoder;
UInt32 packSize; UInt32 packSize;
UInt32 unpackSize; UInt32 unpackSize;
int state; int state;
Byte control; Byte control;
Bool needInitDic; Bool needInitDic;
Bool needInitState; Bool needInitState;
Bool needInitProp; Bool needInitProp;
} CLzma2Dec; } CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) #define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc); SRes Lzma2Dec_AllocateProbs(CLzma2Dec* p, Byte prop, 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:
@ -48,12 +47,11 @@ Returns:
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, SRes Lzma2Dec_DecodeToDic(CLzma2Dec* p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte* src, SizeT* srcLen, ELzmaFinishMode finishMode, ELzmaStatus* status);
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 ---------- */
@ -74,8 +72,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, SRes Lzma2Decode(Byte* dest, SizeT* destLen, const Byte* src, SizeT* srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); Byte prop, ELzmaFinishMode finishMode, ELzmaStatus* status, ISzAlloc* alloc);
#ifdef __cplusplus #ifdef __cplusplus
} }

File diff suppressed because it is too large Load Diff

View File

@ -20,15 +20,13 @@ 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;
unsigned lc, lp, pb; UInt32 dicSize;
UInt32 dicSize;
} CLzmaProps; } CLzmaProps;
/* LzmaProps_Decode - decodes properties /* LzmaProps_Decode - decodes properties
@ -37,8 +35,7 @@ Returns:
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
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 ---------- */
@ -49,37 +46,40 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
typedef struct typedef struct
{ {
CLzmaProps prop; CLzmaProps prop;
CLzmaProb *probs; CLzmaProb* probs;
Byte *dic; Byte* dic;
const Byte *buf; const Byte* buf;
UInt32 range, code; UInt32 range, code;
SizeT dicPos; SizeT dicPos;
SizeT dicBufSize; SizeT dicBufSize;
UInt32 processedPos; UInt32 processedPos;
UInt32 checkDicSize; UInt32 checkDicSize;
unsigned state; unsigned state;
UInt32 reps[4]; UInt32 reps[4];
unsigned remainLen; unsigned remainLen;
int needFlush; int needFlush;
int needInitState; int needInitState;
UInt32 numProbs; UInt32 numProbs;
unsigned tempBufSize; unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } #define LzmaDec_Construct(p) \
{ \
(p)->dic = 0; \
(p)->probs = 0; \
}
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec* p);
/* There are two types of LZMA streams: /* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 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_ANY, /* finish at any point */ LZMA_FINISH_END /* block must be finished at the end */
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 !!!
@ -97,18 +97,16 @@ 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_NOT_SPECIFIED, /* use main error code instead */ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished 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:
@ -118,7 +116,6 @@ 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
@ -131,11 +128,11 @@ LzmaDec_Allocate* can return:
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_AllocateProbs(CLzmaDec* p, const Byte* props, unsigned propsSize, ISzAlloc* alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec* p, ISzAlloc* alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_Allocate(CLzmaDec* state, const Byte* prop, unsigned propsSize, ISzAlloc* alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); void LzmaDec_Free(CLzmaDec* state, ISzAlloc* alloc);
/* ---------- Dictionary Interface ---------- */ /* ---------- Dictionary Interface ---------- */
@ -178,9 +175,8 @@ Returns:
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, SRes LzmaDec_DecodeToDic(CLzmaDec* p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte* src, SizeT* srcLen, ELzmaFinishMode finishMode, ELzmaStatus* status);
/* ---------- Buffer Interface ---------- */ /* ---------- Buffer Interface ---------- */
@ -195,9 +191,8 @@ 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, SRes LzmaDec_DecodeToBuf(CLzmaDec* p, Byte* dest, SizeT* destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte* src, SizeT* srcLen, ELzmaFinishMode finishMode, ELzmaStatus* status);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
@ -220,9 +215,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, SRes LzmaDecode(Byte* dest, SizeT* destLen, const Byte* src, SizeT* srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte* propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc); ELzmaStatus* status, ISzAlloc* alloc);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,13 +5,13 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
#define __PPMD_H #define __PPMD_H
#include "Types.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "Types.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
@ -21,7 +21,7 @@ EXTERN_C_BEGIN
#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
@ -35,51 +35,58 @@ EXTERN_C_BEGIN
/* SEE-contexts for PPM-contexts with masked symbols */ /* SEE-contexts for PPM-contexts with masked symbols */
typedef struct typedef struct
{ {
UInt16 Summ; /* Freq */ UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */ Byte Shift; /* Speed of Freq change; low Shift is for fast change */
Byte Count; /* Count to next change of Shift */ Byte Count; /* Count to next change of Shift */
} CPpmd_See; } CPpmd_See;
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ #define Ppmd_See_Update(p) \
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) { \
(p)->Summ <<= 1; \
(p)->Count = (Byte)(3 << (p)->Shift++); \
}
typedef struct typedef struct
{ {
Byte Symbol; Byte Symbol;
Byte Freq; Byte Freq;
UInt16 SuccessorLow; UInt16 SuccessorLow;
UInt16 SuccessorHigh; UInt16 SuccessorHigh;
} CPpmd_State; } CPpmd_State;
#pragma pack(pop) #pragma pack(pop)
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
CPpmd_State * CPpmd_State*
#else #else
UInt32 UInt32
#endif #endif
CPpmd_State_Ref; CPpmd_State_Ref;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
void * void*
#else #else
UInt32 UInt32
#endif #endif
CPpmd_Void_Ref; CPpmd_Void_Ref;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
Byte * Byte*
#else #else
UInt32 UInt32
#endif #endif
CPpmd_Byte_Ref; CPpmd_Byte_Ref;
#define PPMD_SetAllBitsIn256Bytes(p) \ #define PPMD_SetAllBitsIn256Bytes(p) \
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \ { \
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }} unsigned 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

File diff suppressed because it is too large Load Diff

View File

@ -22,118 +22,110 @@ EXTERN_C_BEGIN
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 NumStats; UInt16 SummFreq;
UInt16 SummFreq; CPpmd_State_Ref Stats;
CPpmd_State_Ref Stats; CPpmd7_Context_Ref Suffix;
CPpmd7_Context_Ref Suffix;
} CPpmd7_Context; } CPpmd7_Context;
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) #define Ppmd7Context_OneState(p) ((CPpmd_State*)&(p)->SummFreq)
typedef struct typedef struct
{ {
CPpmd7_Context *MinContext, *MaxContext; CPpmd7_Context *MinContext, *MaxContext;
CPpmd_State *FoundState; CPpmd_State* FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
Int32 RunLength, InitRL; /* must be 32-bit at least */ Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size; UInt32 Size;
UInt32 GlueCount; UInt32 GlueCount;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 AlignOffset; UInt32 AlignOffset;
Byte Indx2Units[PPMD_NUM_INDEXES]; Byte Indx2Units[PPMD_NUM_INDEXES];
Byte Units2Indx[128]; Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
CPpmd_See DummySee, See[25][16]; CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64]; UInt16 BinSumm[128][64];
} CPpmd7; } CPpmd7;
void Ppmd7_Construct(CPpmd7 *p); void Ppmd7_Construct(CPpmd7* p);
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc); Bool Ppmd7_Alloc(CPpmd7* p, UInt32 size, ISzAlloc* alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc); void Ppmd7_Free(CPpmd7* p, ISzAlloc* alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder); void Ppmd7_Init(CPpmd7* p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL) #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
/* ---------- Internal Functions ---------- */ /* ---------- Internal Functions ---------- */
extern const Byte PPMD7_kExpEscape[16]; extern const Byte PPMD7_kExpEscape[16];
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
#define Ppmd7_GetPtr(p, ptr) (ptr) #define Ppmd7_GetPtr(p, ptr) (ptr)
#define Ppmd7_GetContext(p, ptr) (ptr) #define Ppmd7_GetContext(p, ptr) (ptr)
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
#else #else
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) #define Ppmd7_GetPtr(p, offs) ((void*)((p)->Base + (offs)))
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context*)Ppmd7_GetPtr((p), (offs)))
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) #define Ppmd7_GetStats(p, ctx) ((CPpmd_State*)Ppmd7_GetPtr((p), ((ctx)->Stats)))
#endif #endif
void Ppmd7_Update1(CPpmd7 *p); void Ppmd7_Update1(CPpmd7* p);
void Ppmd7_Update1_0(CPpmd7 *p); void Ppmd7_Update1_0(CPpmd7* p);
void Ppmd7_Update2(CPpmd7 *p); void Ppmd7_Update2(CPpmd7* p);
void Ppmd7_UpdateBin(CPpmd7 *p); void Ppmd7_UpdateBin(CPpmd7* p);
#define Ppmd7_GetBinSumm(p) \ #define Ppmd7_GetBinSumm(p) \
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + ((p->RunLength >> 26) & 0x20)]
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
((p->RunLength >> 26) & 0x20)]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
CPpmd_See* Ppmd7_MakeEscFreq(CPpmd7* p, unsigned numMasked, UInt32* scale);
/* ---------- Decode ---------- */ /* ---------- Decode ---------- */
typedef struct typedef struct
{ {
UInt32 (*GetThreshold)(void *p, UInt32 total); UInt32 (*GetThreshold)(void* p, UInt32 total);
void (*Decode)(void *p, UInt32 start, UInt32 size); void (*Decode)(void* p, UInt32 start, UInt32 size);
UInt32 (*DecodeBit)(void *p, UInt32 size0); UInt32 (*DecodeBit)(void* p, UInt32 size0);
} IPpmd7_RangeDec; } IPpmd7_RangeDec;
typedef struct typedef struct
{ {
IPpmd7_RangeDec p; IPpmd7_RangeDec p;
UInt32 Range; UInt32 Range;
UInt32 Code; UInt32 Code;
IByteIn *Stream; IByteIn* Stream;
} CPpmd7z_RangeDec; } CPpmd7z_RangeDec;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p); void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec* p);
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p); Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec* p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc); int Ppmd7_DecodeSymbol(CPpmd7* p, IPpmd7_RangeDec* rc);
/* ---------- Encode ---------- */ /* ---------- Encode ---------- */
typedef struct typedef struct
{ {
UInt64 Low; UInt64 Low;
UInt32 Range; UInt32 Range;
Byte Cache; Byte Cache;
UInt64 CacheSize; UInt64 CacheSize;
IByteOut *Stream; IByteOut* Stream;
} CPpmd7z_RangeEnc; } CPpmd7z_RangeEnc;
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p); void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc* p);
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p); void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc* p);
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); void Ppmd7_EncodeSymbol(CPpmd7* p, CPpmd7z_RangeEnc* rc, int symbol);
EXTERN_C_END EXTERN_C_END

View File

@ -6,182 +6,167 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#define kTopValue (1 << 24) #define kTopValue (1 << 24)
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec* p)
{ {
unsigned i;
p->Code = 0;
p->Range = 0xFFFFFFFF;
if (p->Stream->Read((void *)p->Stream) != 0)
return False;
for (i = 0; i < 4; i++)
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
return (p->Code < 0xFFFFFFFF);
}
static UInt32 Range_GetThreshold(void *pp, UInt32 total)
{
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
return (p->Code) / (p->Range /= total);
}
static void Range_Normalize(CPpmd7z_RangeDec *p)
{
if (p->Range < kTopValue)
{
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
p->Range <<= 8;
if (p->Range < kTopValue)
{
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;
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;
UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol;
if (p->Code < newBound)
{
symbol = 0;
p->Range = newBound;
}
else
{
symbol = 1;
p->Code -= newBound;
p->Range -= newBound;
}
Range_Normalize(p);
return symbol;
}
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{
p->p.GetThreshold = Range_GetThreshold;
p->p.Decode = Range_Decode;
p->p.DecodeBit = Range_DecodeBit;
}
#define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
{
size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1)
{
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
unsigned i; unsigned i;
UInt32 count, hiCnt; p->Code = 0;
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) p->Range = 0xFFFFFFFF;
{ if (p->Stream->Read((void*)p->Stream) != 0)
Byte symbol; return False;
rc->Decode(rc, 0, s->Freq); for (i = 0; i < 4; i++)
p->FoundState = s; p->Code = (p->Code << 8) | p->Stream->Read((void*)p->Stream);
symbol = s->Symbol; return (p->Code < 0xFFFFFFFF);
Ppmd7_Update1_0(p); }
return symbol;
} static UInt32 Range_GetThreshold(void* pp, UInt32 total)
p->PrevSuccess = 0; {
i = p->MinContext->NumStats - 1; CPpmd7z_RangeDec* p = (CPpmd7z_RangeDec*)pp;
do return (p->Code) / (p->Range /= total);
{ }
if ((hiCnt += (++s)->Freq) > count)
{ static void Range_Normalize(CPpmd7z_RangeDec* p)
Byte symbol; {
rc->Decode(rc, hiCnt - s->Freq, s->Freq); if (p->Range < kTopValue) {
p->FoundState = s; p->Code = (p->Code << 8) | p->Stream->Read((void*)p->Stream);
symbol = s->Symbol; p->Range <<= 8;
Ppmd7_Update1(p); if (p->Range < kTopValue) {
return symbol; p->Code = (p->Code << 8) | p->Stream->Read((void*)p->Stream);
} p->Range <<= 8;
} }
while (--i); }
if (count >= p->MinContext->SummFreq) }
return -2;
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; static void Range_Decode(void* pp, UInt32 start, UInt32 size)
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); {
PPMD_SetAllBitsIn256Bytes(charMask); CPpmd7z_RangeDec* p = (CPpmd7z_RangeDec*)pp;
MASK(s->Symbol) = 0; p->Code -= start * p->Range;
i = p->MinContext->NumStats - 1; p->Range *= size;
do { MASK((--s)->Symbol) = 0; } while (--i); Range_Normalize(p);
} }
else
{ static UInt32 Range_DecodeBit(void* pp, UInt32 size0)
UInt16 *prob = Ppmd7_GetBinSumm(p); {
if (rc->DecodeBit(rc, *prob) == 0) CPpmd7z_RangeDec* p = (CPpmd7z_RangeDec*)pp;
{ UInt32 newBound = (p->Range >> 14) * size0;
Byte symbol; UInt32 symbol;
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); if (p->Code < newBound) {
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; symbol = 0;
Ppmd7_UpdateBin(p); p->Range = newBound;
return symbol; } else {
} symbol = 1;
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); p->Code -= newBound;
p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; p->Range -= newBound;
PPMD_SetAllBitsIn256Bytes(charMask); }
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; Range_Normalize(p);
p->PrevSuccess = 0; return symbol;
} }
for (;;)
{ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec* p)
CPpmd_State *ps[256], *s; {
UInt32 freqSum, count, hiCnt; p->p.GetThreshold = Range_GetThreshold;
CPpmd_See *see; p->p.Decode = Range_Decode;
unsigned i, num, numMasked = p->MinContext->NumStats; p->p.DecodeBit = Range_DecodeBit;
do }
{
p->OrderFall++; #define MASK(sym) ((signed char*)charMask)[sym]
if (!p->MinContext->Suffix)
return -1; int Ppmd7_DecodeSymbol(CPpmd7* p, IPpmd7_RangeDec* rc)
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); {
} size_t charMask[256 / sizeof(size_t)];
while (p->MinContext->NumStats == numMasked); if (p->MinContext->NumStats != 1) {
hiCnt = 0; CPpmd_State* s = Ppmd7_GetStats(p, p->MinContext);
s = Ppmd7_GetStats(p, p->MinContext); unsigned i;
i = 0; UInt32 count, hiCnt;
num = p->MinContext->NumStats - numMasked; if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) {
do Byte symbol;
{ rc->Decode(rc, 0, s->Freq);
int k = (int)(MASK(s->Symbol)); p->FoundState = s;
hiCnt += (s->Freq & k); symbol = s->Symbol;
ps[i] = s++; Ppmd7_Update1_0(p);
i -= k; return symbol;
} }
while (i != num); p->PrevSuccess = 0;
i = p->MinContext->NumStats - 1;
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); do {
freqSum += hiCnt; if ((hiCnt += (++s)->Freq) > count) {
count = rc->GetThreshold(rc, freqSum); Byte symbol;
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
if (count < hiCnt) p->FoundState = s;
{ symbol = s->Symbol;
Byte symbol; Ppmd7_Update1(p);
CPpmd_State **pps = ps; return symbol;
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); }
s = *pps; } while (--i);
rc->Decode(rc, hiCnt - s->Freq, s->Freq); if (count >= p->MinContext->SummFreq)
Ppmd_See_Update(see); return -2;
p->FoundState = s; p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
symbol = s->Symbol; rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
Ppmd7_Update2(p); PPMD_SetAllBitsIn256Bytes(charMask);
return symbol; MASK(s->Symbol) = 0;
} i = p->MinContext->NumStats - 1;
if (count >= freqSum) do {
return -2; MASK((--s)->Symbol) = 0;
rc->Decode(rc, hiCnt, freqSum - hiCnt); } while (--i);
see->Summ = (UInt16)(see->Summ + freqSum); } else {
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); UInt16* prob = Ppmd7_GetBinSumm(p);
} if (rc->DecodeBit(rc, *prob) == 0) {
Byte symbol;
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
Ppmd7_UpdateBin(p);
return symbol;
}
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
PPMD_SetAllBitsIn256Bytes(charMask);
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
p->PrevSuccess = 0;
}
for (;;) {
CPpmd_State *ps[256], *s;
UInt32 freqSum, count, hiCnt;
CPpmd_See* see;
unsigned i, num, numMasked = p->MinContext->NumStats;
do {
p->OrderFall++;
if (!p->MinContext->Suffix)
return -1;
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
} while (p->MinContext->NumStats == numMasked);
hiCnt = 0;
s = Ppmd7_GetStats(p, p->MinContext);
i = 0;
num = p->MinContext->NumStats - numMasked;
do {
int k = (int)(MASK(s->Symbol));
hiCnt += (s->Freq & k);
ps[i] = s++;
i -= k;
} while (i != num);
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
freqSum += hiCnt;
count = rc->GetThreshold(rc, freqSum);
if (count < hiCnt) {
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,7 +49,12 @@ typedef int WRes;
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #define RINOK(x) \
{ \
int __result__ = (x); \
if (__result__ != 0) \
return __result__; \
}
#endif #endif
typedef unsigned char Byte; typedef unsigned char Byte;
@ -81,7 +86,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
@ -96,7 +101,6 @@ 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
@ -121,113 +125,111 @@ 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); SRes (*Read)(void* p, void* buf, size_t* size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
} ISeqInStream; } ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */ /* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); SRes SeqInStream_Read(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); size_t (*Write)(void* p, const void* buf, size_t size);
/* Returns: result - the number of actually written bytes. /* Returns: result - the number of actually written bytes.
(result < size) means error */ (result < size) means error */
} ISeqOutStream; } ISeqOutStream;
typedef enum typedef enum {
{ SZ_SEEK_SET = 0,
SZ_SEEK_SET = 0, SZ_SEEK_CUR = 1,
SZ_SEEK_CUR = 1, SZ_SEEK_END = 2
SZ_SEEK_END = 2
} ESzSeek; } ESzSeek;
typedef struct typedef struct
{ {
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ SRes (*Read)(void* p, void* buf, size_t* size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(void* p, Int64* pos, ESzSeek origin);
} ISeekInStream; } ISeekInStream;
typedef struct typedef struct
{ {
SRes (*Look)(void *p, const void **buf, size_t *size); SRes (*Look)(void* p, const void** buf, size_t* size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed (output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset); SRes (*Skip)(void* p, size_t offset);
/* offset must be <= output(*size) of Look */ /* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size); SRes (*Read)(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);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); SRes LookInStream_SeekTo(ILookInStream* stream, UInt64 offset);
/* reads via ILookInStream::Read */ /* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); SRes LookInStream_Read2(ILookInStream* stream, void* buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); 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; ILookInStream s;
ISeekInStream *realStream; ISeekInStream* realStream;
size_t pos; size_t pos;
size_t size; size_t size;
Byte buf[LookToRead_BUF_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; ISeqInStream s;
ILookInStream *realStream; ILookInStream* realStream;
} CSecToLook; } CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p); void SecToLook_CreateVTable(CSecToLook* p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream s;
ILookInStream *realStream; 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); SRes (*Progress)(void* p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break. /* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */ Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress; } ICompressProgress;
typedef struct typedef struct
{ {
void *(*Alloc)(void *p, size_t size); void* (*Alloc)(void* p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */ 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)