Merge pull request #16 from EoD/fix-linux-build

Fix various Linux build issues
This commit is contained in:
Zach Bacon 2016-07-31 08:20:46 -04:00 committed by GitHub
commit 7153bc7d92
36 changed files with 4780 additions and 4531 deletions

View File

@ -13,7 +13,8 @@ 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,
@ -42,7 +43,8 @@ enum EIdEnum {
k7zIdDummy k7zIdDummy
}; };
typedef struct { typedef struct
{
UInt32 NumInStreams; UInt32 NumInStreams;
UInt32 NumOutStreams; UInt32 NumOutStreams;
UInt64 MethodID; UInt64 MethodID;
@ -52,12 +54,14 @@ typedef struct {
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;
@ -77,15 +81,18 @@ int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p); UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
UInt64 SzFolder_GetUnpackSize(CSzFolder *p); UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *stream, SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain); ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
typedef struct { typedef struct
{
UInt32 Low; UInt32 Low;
UInt32 High; UInt32 High;
} CNtfsFileTime; } CNtfsFileTime;
typedef struct { typedef struct
{
CNtfsFileTime MTime; CNtfsFileTime MTime;
UInt64 Size; UInt64 Size;
UInt32 Crc; UInt32 Crc;
@ -100,7 +107,8 @@ typedef struct {
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;
@ -114,6 +122,7 @@ typedef struct {
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
@ -134,7 +143,8 @@ void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
Free *outBuffer and set *outBuffer to 0, if you want to flush cache. Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/ */
typedef struct { typedef struct
{
CSzAr db; CSzAr db;
UInt64 startPosAfterHeader; UInt64 startPosAfterHeader;
@ -162,15 +172,18 @@ if dest != NULL, the return value specifies the number of 16-bit characters that
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest); size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
SRes SzArEx_Extract(const CSzArEx *db, ILookInStream *inStream, UInt32 fileIndex, /* index of file SRes SzArEx_Extract(
*/ const CSzArEx *db,
ILookInStream *inStream,
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 Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
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 *allocTemp); ISzAlloc *allocMain,
ISzAlloc *allocTemp);
/* /*
SzArEx_Open Errors: SzArEx_Open Errors:

View File

@ -23,22 +23,23 @@ 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);
} }
@ -47,28 +48,29 @@ 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

@ -14,12 +14,14 @@ 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)
{ {
p->size = 0; p->size = 0;
if (size == 0) { if (size == 0)
{
p->data = 0; p->data = 0;
return 1; return 1;
} }
p->data = (Byte *)alloc->Alloc(alloc, size); p->data = (Byte *)alloc->Alloc(alloc, size);
if (p->data != 0) { if (p->data != 0)
{
p->size = size; p->size = size;
return 1; return 1;
} }

View File

@ -10,7 +10,8 @@
extern "C" { extern "C" {
#endif #endif
typedef struct { typedef struct
{
Byte *data; Byte *data;
size_t size; size_t size;
} CBuf; } CBuf;
@ -19,7 +20,8 @@ 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;

View File

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

View File

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

View File

@ -3,15 +3,15 @@
#include <string.h> #include <string.h>
#define _7ZIP_PPMD_SUPPPORT /* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h" #include "7z.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "Bra.h" #include "Bra.h"
#include "CpuArch.h" #include "CpuArch.h"
#include "Lzma2Dec.h"
#include "LzmaDec.h" #include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT #ifdef _7ZIP_PPMD_SUPPPORT
#include "Ppmd7.h" #include "Ppmd7.h"
#endif #endif
@ -30,7 +30,8 @@
#define k_PPMD 0x30401 #define k_PPMD 0x30401
typedef struct { typedef struct
{
IByteIn p; IByteIn p;
const Byte *cur; const Byte *cur;
const Byte *end; const Byte *end;
@ -46,7 +47,8 @@ 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);
@ -55,8 +57,7 @@ static Byte ReadByte(void *pp)
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;
@ -82,8 +83,10 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
{ {
unsigned order = coder->Props.data[0]; unsigned order = coder->Props.data[0];
UInt32 memSize = GetUi32(coder->Props.data + 1); UInt32 memSize = GetUi32(coder->Props.data + 1);
if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER || if (order < PPMD7_MIN_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE || memSize > PPMD7_MAX_MEM_SIZE) order > PPMD7_MAX_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE ||
memSize > PPMD7_MAX_MEM_SIZE)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
Ppmd7_Construct(&ppmd); Ppmd7_Construct(&ppmd);
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
@ -98,9 +101,11 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
else if (s.extra) else if (s.extra)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else { else
{
SizeT i; SizeT i;
for (i = 0; i < outSize; i++) { for (i = 0; i < outSize; i++)
{
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p); int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
if (s.extra || sym < 0) if (s.extra || sym < 0)
break; break;
@ -108,8 +113,7 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
} }
if (i != outSize) if (i != outSize)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else if (s.processed + (s.cur - s.begin) != inSize || else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
!Ppmd7z_RangeDec_IsFinishedOK(&rc))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
} }
} }
@ -119,6 +123,7 @@ static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
#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)
{ {
@ -126,15 +131,13 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
SRes res = SZ_OK; SRes res = SZ_OK;
LzmaDec_Construct(&state); LzmaDec_Construct(&state);
RINOK(LzmaDec_AllocateProbs(&state, RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
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)
@ -146,18 +149,13 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
{ {
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
ELzmaStatus status; ELzmaStatus status;
res = LzmaDec_DecodeToDic(&state, res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
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 || if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
(inProcessed == 0 && dicPos == state.dicPos)) { {
if (state.dicBufSize != outSize || lookahead != 0 || if (state.dicBufSize != outSize || lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK && (status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
@ -188,7 +186,8 @@ static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inS
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)
@ -200,18 +199,13 @@ static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inS
{ {
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
ELzmaStatus status; ELzmaStatus status;
res = Lzma2Dec_DecodeToDic(&state, res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
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 || if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
(inProcessed == 0 && dicPos == state.decoder.dicPos)) { {
if (state.decoder.dicBufSize != outSize || lookahead != 0 || if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK)) (status != LZMA_STATUS_FINISHED_WITH_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
@ -229,7 +223,8 @@ static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inS
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)
@ -247,13 +242,14 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
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;
@ -261,7 +257,10 @@ static Bool IS_MAIN_METHOD(UInt32 m)
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{ {
return c->NumInStreams == 1 && c->NumOutStreams == 1 && c->MethodID <= (UInt32)0xFFFFFFFF && return
c->NumInStreams == 1 &&
c->NumOutStreams == 1 &&
c->MethodID <= (UInt32)0xFFFFFFFF &&
IS_MAIN_METHOD((UInt32)c->MethodID); IS_MAIN_METHOD((UInt32)c->MethodID);
} }
@ -273,19 +272,26 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (!IS_SUPPORTED_CODER(&f->Coders[0])) if (!IS_SUPPORTED_CODER(&f->Coders[0]))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1) { if (f->NumCoders == 1)
{
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
return SZ_OK; return SZ_OK;
} }
if (f->NumCoders == 2) { if (f->NumCoders == 2)
{
CSzCoderInfo *c = &f->Coders[1]; CSzCoderInfo *c = &f->Coders[1];
if (c->MethodID > (UInt32)0xFFFFFFFF || c->NumInStreams != 1 || if (c->MethodID > (UInt32)0xFFFFFFFF ||
c->NumOutStreams != 1 || f->NumPackStreams != 1 || f->PackStreams[0] != 0 || c->NumInStreams != 1 ||
f->NumBindPairs != 1 || f->BindPairs[0].InIndex != 1 || c->NumOutStreams != 1 ||
f->NumPackStreams != 1 ||
f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
f->BindPairs[0].InIndex != 1 ||
f->BindPairs[0].OutIndex != 0) f->BindPairs[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID) { switch ((UInt32)c->MethodID)
{
case k_BCJ: case k_BCJ:
case k_ARM: case k_ARM:
break; break;
@ -294,12 +300,18 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
} }
return SZ_OK; return SZ_OK;
} }
if (f->NumCoders == 4) { if (f->NumCoders == 4)
if (!IS_SUPPORTED_CODER(&f->Coders[1]) || !IS_SUPPORTED_CODER(&f->Coders[2]) || {
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
!IS_BCJ2(&f->Coders[3])) !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4 || f->PackStreams[0] != 2 || f->PackStreams[1] != 6 || if (f->NumPackStreams != 4 ||
f->PackStreams[2] != 1 || f->PackStreams[3] != 0 || f->NumBindPairs != 3 || 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[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
@ -318,36 +330,38 @@ static UInt64 GetSum(const UInt64 *values, UInt32 index)
return sum; return sum;
} }
#define CASE_BRA_CONV(isa) \ #define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
case k_##isa: \
isa##_Convert(outBuffer, outSize, 0, 0); \
break;
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes, static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
ILookInStream *inStream, UInt64 startPos, Byte *outBuffer, ILookInStream *inStream, UInt64 startPos,
SizeT outSize, ISzAlloc *allocMain, Byte *tempBuf[]) Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
Byte *tempBuf[])
{ {
UInt32 ci; UInt32 ci;
SizeT tempSizes[3] = { 0, 0, 0 }; SizeT tempSizes[3] = { 0, 0, 0};
SizeT tempSize3 = 0; SizeT tempSize3 = 0;
Byte *tempBuf3 = 0; Byte *tempBuf3 = 0;
RINOK(CheckSupportedFolder(folder)); RINOK(CheckSupportedFolder(folder));
for (ci = 0; ci < folder->NumCoders; ci++) { for (ci = 0; ci < folder->NumCoders; ci++)
{
CSzCoderInfo *coder = &folder->Coders[ci]; CSzCoderInfo *coder = &folder->Coders[ci];
if (IS_MAIN_METHOD((UInt32)coder->MethodID)) { if (IS_MAIN_METHOD((UInt32)coder->MethodID))
{
UInt32 si = 0; UInt32 si = 0;
UInt64 offset; UInt64 offset;
UInt64 inSize; UInt64 inSize;
Byte *outBufCur = outBuffer; Byte *outBufCur = outBuffer;
SizeT outSizeCur = outSize; SizeT outSizeCur = outSize;
if (folder->NumCoders == 4) { if (folder->NumCoders == 4)
{
UInt32 indices[] = { 3, 2, 0 }; UInt32 indices[] = { 3, 2, 0 };
UInt64 unpackSize = folder->UnpackSizes[ci]; UInt64 unpackSize = folder->UnpackSizes[ci];
si = indices[ci]; si = indices[ci];
if (ci < 2) { if (ci < 2)
{
Byte *temp; Byte *temp;
outSizeCur = (SizeT)unpackSize; outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize) if (outSizeCur != unpackSize)
@ -357,50 +371,46 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp; outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur; tempSizes[1 - ci] = outSizeCur;
} else if (ci == 2) { }
else if (ci == 2)
{
if (unpackSize > outSize) /* check it */ if (unpackSize > outSize) /* check it */
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
tempBuf3 = outBufCur = tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
outBuffer + (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (SizeT)unpackSize; tempSize3 = outSizeCur = (SizeT)unpackSize;
} else }
else
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
offset = GetSum(packSizes, si); offset = GetSum(packSizes, si);
inSize = packSizes[si]; inSize = packSizes[si];
RINOK(LookInStream_SeekTo(inStream, startPos + offset)); RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy) { if (coder->MethodID == k_Copy)
{
if (inSize != outSizeCur) /* check it */ if (inSize != outSizeCur) /* check it */
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); 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) { 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 offset = GetSum(packSizes, 1);
UInt64 s3Size = packSizes[1]; UInt64 s3Size = packSizes[1];
SRes res; SRes res;
@ -416,22 +426,22 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
RINOK(res) RINOK(res)
res = Bcj2_Decode(tempBuf3, res = Bcj2_Decode(
tempSize3, tempBuf3, tempSize3,
tempBuf[0], tempBuf[0], tempSizes[0],
tempSizes[0], tempBuf[1], tempSizes[1],
tempBuf[1], tempBuf[2], tempSizes[2],
tempSizes[1], outBuffer, outSize);
tempBuf[2],
tempSizes[2],
outBuffer,
outSize);
RINOK(res) RINOK(res)
} else { }
else
{
if (ci != 1) if (ci != 1)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
switch (coder->MethodID) { switch(coder->MethodID)
case k_BCJ: { {
case k_BCJ:
{
UInt32 state; UInt32 state;
x86_Convert_Init(state); x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0); x86_Convert(outBuffer, outSize, 0, &state, 0);
@ -446,19 +456,14 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
return SZ_OK; return SZ_OK;
} }
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *inStream, SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain) ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
{ {
Byte *tempBuf[3] = { 0, 0, 0 }; Byte *tempBuf[3] = { 0, 0, 0};
int i; int i;
SRes res = SzFolder_Decode2(folder, SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
packSizes, outBuffer, (SizeT)outSize, allocMain, tempBuf);
inStream,
startPos,
outBuffer,
(SizeT)outSize,
allocMain,
tempBuf);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); IAlloc_Free(allocMain, tempBuf[i]);
return res; return res;

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,8 @@
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)
@ -48,7 +49,8 @@ SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) { while (size != 0)
{
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); RINOK(stream->Read(stream, buf, &processed));
if (processed == 0) if (processed == 0)
@ -69,7 +71,8 @@ static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) { if (size2 == 0 && *size > 0)
{
p->pos = 0; p->pos = 0;
size2 = LookToRead_BUF_SIZE; size2 = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, &size2); res = p->realStream->Read(p->realStream, p->buf, &size2);
@ -86,7 +89,8 @@ static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
SRes res = SZ_OK; SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp; CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos; size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0) { if (size2 == 0 && *size > 0)
{
p->pos = 0; p->pos = 0;
if (*size > LookToRead_BUF_SIZE) if (*size > LookToRead_BUF_SIZE)
*size = LookToRead_BUF_SIZE; *size = LookToRead_BUF_SIZE;
@ -129,7 +133,9 @@ static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
void LookToRead_CreateVTable(CLookToRead *p, int lookahead) void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
{ {
p->s.Look = lookahead ? LookToRead_Look_Lookahead : LookToRead_Look_Exact; p->s.Look = lookahead ?
LookToRead_Look_Lookahead :
LookToRead_Look_Exact;
p->s.Skip = LookToRead_Skip; p->s.Skip = LookToRead_Skip;
p->s.Read = LookToRead_Read; p->s.Read = LookToRead_Read;
p->s.Seek = LookToRead_Seek; p->s.Seek = LookToRead_Seek;

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,45 +20,22 @@
#define kNumMoveBits 5 #define kNumMoveBits 5
#define RC_READ_BYTE (*buffer++) #define RC_READ_BYTE (*buffer++)
#define RC_TEST \ #define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
{ \ #define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
if (buffer == bufferLim) \ { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
return SZ_ERROR_DATA; \
}
#define RC_INIT2 \
code = 0; \
range = 0xFFFFFFFF; \
{ \
int i; \
for (i = 0; i < 5; i++) { \
RC_TEST; \
code = (code << 8) | RC_READ_BYTE; \
} \
}
#define NORMALIZE \ #define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
if (range < kTopValue) { \
RC_TEST; \
range <<= 8; \
code = (code << 8) | RC_READ_BYTE; \
}
#define IF_BIT_0(p) \ #define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
ttt = *(p); \ #define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
bound = (range >> kNumBitModelTotalBits) * ttt; \ #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
if (code < bound)
#define UPDATE_0(p) \
range = bound; \
*(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); \
NORMALIZE;
#define UPDATE_1(p) \
range -= bound; \
code -= bound; \
*(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); \
NORMALIZE;
int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2, int Bcj2_Decode(
SizeT size2, const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize) const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize)
{ {
CProb p[256 + 2]; CProb p[256 + 2];
SizeT inPos = 0, outPos = 0; SizeT inPos = 0, outPos = 0;
@ -78,7 +55,8 @@ int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, co
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;
@ -87,7 +65,8 @@ int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, co
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))
@ -119,22 +98,24 @@ int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, co
UInt32 dest; UInt32 dest;
const Byte *v; const Byte *v;
UPDATE_1(prob) UPDATE_1(prob)
if (b == 0xE8) { if (b == 0xE8)
{
v = buf1; v = buf1;
if (size1 < 4) if (size1 < 4)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
buf1 += 4; buf1 += 4;
size1 -= 4; size1 -= 4;
} else { }
else
{
v = buf2; v = buf2;
if (size2 < 4) if (size2 < 4)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
buf2 += 4; buf2 += 4;
size2 -= 4; size2 -= 4;
} }
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | ((UInt32)v[2] << 8) | dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
((UInt32)v[3])) - ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest; outBuf[outPos++] = (Byte)dest;
if (outPos == outSize) if (outPos == outSize)
break; break;

View File

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

View File

@ -10,11 +10,12 @@ SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
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 dest;
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
(data[i + 0]);
src <<= 2; src <<= 2;
if (encoding) if (encoding)
dest = ip + (UInt32)i + src; dest = ip + (UInt32)i + src;
@ -36,12 +37,17 @@ SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
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 &&
(data[i + 3] & 0xF8) == 0xF8)
{
UInt32 dest; UInt32 dest;
UInt32 src = (((UInt32)data[i + 1] & 0x7) << 19) | UInt32 src =
(((UInt32)data[i + 1] & 0x7) << 19) |
((UInt32)data[i + 0] << 11) | ((UInt32)data[i + 0] << 11) |
(((UInt32)data[i + 3] & 0x7) << 8) | (data[i + 2]); (((UInt32)data[i + 3] & 0x7) << 8) |
(data[i + 2]);
src <<= 1; src <<= 1;
if (encoding) if (encoding)
@ -66,10 +72,13 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
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 src = ((UInt32)(data[i + 0] & 3) << 24) |
((UInt32)data[i + 1] << 16) | ((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3] & (~3)); ((UInt32)data[i + 3] & (~3));
UInt32 dest; UInt32 dest;
@ -93,11 +102,16 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
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) || if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) { (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
UInt32 src = ((UInt32)data[i + 0] << 24) | ((UInt32)data[i + 1] << 16) | {
((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3]); UInt32 src =
((UInt32)data[i + 0] << 24) |
((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3]);
UInt32 dest; UInt32 dest;
src <<= 2; src <<= 2;
@ -107,8 +121,7 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
dest = src - (ip + i); dest = src - (ip + i);
dest >>= 2; dest >>= 2;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
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);

View File

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

View File

@ -5,8 +5,8 @@
#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)
{ {
@ -17,7 +17,8 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
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++)
@ -29,11 +30,14 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
prevPosT = bufferPos - prevPosT; prevPosT = bufferPos - prevPosT;
if (prevPosT > 3) if (prevPosT > 3)
prevMask = 0; prevMask = 0;
else { else
{
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
if (prevMask != 0) { if (prevMask != 0)
{
Byte b = p[4 - kMaskToBitNumber[prevMask]]; Byte b = p[4 - kMaskToBitNumber[prevMask]];
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) { if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
{
prevPosT = bufferPos; prevPosT = bufferPos;
prevMask = ((prevMask << 1) & 0x7) | 1; prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++; bufferPos++;
@ -43,11 +47,12 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
} }
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; Byte b;
int index; int index;
if (encoding) if (encoding)
@ -67,7 +72,9 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
p[2] = (Byte)(dest >> 8); p[2] = (Byte)(dest >> 8);
p[1] = (Byte)dest; p[1] = (Byte)dest;
bufferPos += 5; bufferPos += 5;
} else { }
else
{
prevMask = ((prevMask << 1) & 0x7) | 1; prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++; bufferPos++;
} }

View File

@ -12,7 +12,7 @@
#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;
@ -25,8 +25,8 @@ static UInt32 CheckFlag(UInt32 flag)
__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"
@ -38,24 +38,21 @@ static UInt32 CheckFlag(UInt32 flag)
"xorl %%EDX,%%EAX\n\t" "xorl %%EDX,%%EAX\n\t"
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t" "andl %%EAX, %0\n\t":
: "=c"(flag) "=c" (flag) : "c" (flag));
: "c"(flag)); #endif
#endif
return flag; return flag;
} }
#define CHECK_CPUID_IS_SUPPORTED \ #define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) \
return False;
#else #else
#define CHECK_CPUID_IS_SUPPORTED #define CHECK_CPUID_IS_SUPPORTED
#endif #endif
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{ {
#ifdef USE_ASM #ifdef USE_ASM
#ifdef _MSC_VER #ifdef _MSC_VER
UInt32 a2, b2, c2, d2; UInt32 a2, b2, c2, d2;
__asm xor EBX, EBX; __asm xor EBX, EBX;
@ -73,18 +70,19 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
*c = c2; *c = c2;
*d = d2; *d = d2;
#else #else
// Mac cross-compile compiler: __asm__ __volatile__ (
// can't find register in class 'BREG' while reloading 'asm' "cpuid"
// so use class 'r' register var binding : "=a" (*a) ,
register _b asm("%bx"); "=b" (*b) ,
__asm__ __volatile__("cpuid" : "=a"(*a), "=r"(_b), "=c"(*c), "=d"(*d) : "0"(function)); "=c" (*c) ,
*b = _b; "=d" (*d)
: "0" (function)) ;
#endif #endif
#else #else
int CPUInfo[4]; int CPUInfo[4];
__cpuid(CPUInfo, function); __cpuid(CPUInfo, function);
@ -93,7 +91,7 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
*c = CPUInfo[2]; *c = CPUInfo[2];
*d = CPUInfo[3]; *d = CPUInfo[3];
#endif #endif
} }
Bool x86cpuid_CheckAndRead(Cx86cpuid *p) Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
@ -104,16 +102,22 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
return True; return True;
} }
static UInt32 kVendors[][3] = { { 0x756E6547, 0x49656E69, 0x6C65746E }, static UInt32 kVendors[][3] =
{ 0x68747541, 0x69746E65, 0x444D4163 }, {
{ 0x746E6543, 0x48727561, 0x736C7561 } }; { 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
{ 0x746E6543, 0x48727561, 0x736C7561}
};
int x86cpuid_GetFirm(const Cx86cpuid *p) int x86cpuid_GetFirm(const Cx86cpuid *p)
{ {
unsigned i; unsigned i;
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) { for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
{
const UInt32 *v = kVendors[i]; 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] &&
v[1] == p->vendor[1] &&
v[2] == p->vendor[2])
return (int)i; return (int)i;
} }
return -1; return -1;
@ -129,13 +133,11 @@ Bool CPU_Is_InOrder()
family = x86cpuid_GetFamily(&p); family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p); model = x86cpuid_GetModel(&p);
firm = x86cpuid_GetFirm(&p); firm = x86cpuid_GetFirm(&p);
switch (firm) { switch (firm)
case CPU_FIRM_INTEL: {
return (family < 6 || (family == 6 && model == 0x100C)); case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
case CPU_FIRM_AMD: case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
case CPU_FIRM_VIA:
return (family < 6 || (family == 6 && model < 0xF));
} }
return True; return True;
} }
@ -149,9 +151,7 @@ static Bool CPU_Sys_Is_SSE_Supported()
return False; return False;
return (vi.dwMajorVersion >= 5); return (vi.dwMajorVersion >= 5);
} }
#define CHECK_SYS_SSE_SUPPORT \ #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
if (!CPU_Sys_Is_SSE_Supported()) \
return False;
#else #else
#define CHECK_SYS_SSE_SUPPORT #define CHECK_SYS_SSE_SUPPORT
#endif #endif

View File

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

View File

@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */ 2010-12-15 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@ -36,7 +36,7 @@
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) #define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4 #define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p)&1)) << ((p) / 2 + 11)) #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO #ifdef SHOW_DEBUG_INFO
#define PRF(x) x #define PRF(x) x
@ -44,7 +44,8 @@
#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,
@ -96,18 +97,21 @@ void Lzma2Dec_Init(CLzma2Dec *p)
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 }
else
p->unpackSize = (UInt32)(p->control & 0x1F) << 16; p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0; return LZMA2_STATE_UNPACK0;
@ -129,11 +133,11 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
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)) return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
? 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;
@ -163,23 +167,27 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState); void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
ELzmaFinishMode finishMode, ELzmaStatus *status) const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
*srcLen = 0; *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED) { while (p->state != LZMA2_STATE_FINISHED)
{
SizeT dicPos = p->decoder.dicPos; SizeT dicPos = p->decoder.dicPos;
if (p->state == LZMA2_STATE_ERROR) if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) { if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK; return SZ_OK;
} }
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) { if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
if (*srcLen == inSize) { {
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
@ -192,18 +200,22 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *
SizeT srcSizeCur = inSize - *srcLen; SizeT srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur) { if (p->unpackSize <= destSizeCur)
{
destSizeCur = (SizeT)p->unpackSize; destSizeCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END; curFinishMode = LZMA_FINISH_END;
} }
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) { if (LZMA2_IS_UNCOMPRESSED_STATE(p))
if (*srcLen == inSize) { {
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
if (p->state == LZMA2_STATE_DATA) { if (p->state == LZMA2_STATE_DATA)
{
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic) if (initDic)
p->needInitProp = p->needInitState = True; p->needInitProp = p->needInitState = True;
@ -224,18 +236,19 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *
src += srcSizeCur; src += srcSizeCur;
*srcLen += srcSizeCur; *srcLen += srcSizeCur;
p->unpackSize -= (UInt32)srcSizeCur; p->unpackSize -= (UInt32)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
: LZMA2_STATE_DATA_CONT; }
} else { else
{
SizeT outSizeProcessed; SizeT outSizeProcessed;
SRes res; SRes res;
if (p->state == LZMA2_STATE_DATA) { if (p->state == LZMA2_STATE_DATA)
{
int mode = LZMA2_GET_LZMA_MODE(p); int mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3); Bool initDic = (mode == 3);
Bool initState = (mode > 0); Bool initState = (mode > 0);
if ((!initDic && p->needInitDic) || if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
(!initState && p->needInitState))
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
LzmaDec_InitDicAndState(&p->decoder, initDic, initState); LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
@ -246,12 +259,7 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *
if (srcSizeCur > p->packSize) if (srcSizeCur > p->packSize)
srcSizeCur = (SizeT)p->packSize; srcSizeCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
dicPos + destSizeCur,
src,
&srcSizeCur,
curFinishMode,
status);
src += srcSizeCur; src += srcSizeCur;
*srcLen += srcSizeCur; *srcLen += srcSizeCur;
@ -264,7 +272,8 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res; return res;
if (srcSizeCur == 0 && outSizeProcessed == 0) { if (srcSizeCur == 0 && outSizeProcessed == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
p->unpackSize != 0 || p->packSize != 0) p->unpackSize != 0 || p->packSize != 0)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
@ -279,22 +288,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *
return SZ_OK; return SZ_OK;
} }
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) { for (;;)
{
SizeT srcSizeCur = inSize, outSizeCur, dicPos; SizeT srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode; ELzmaFinishMode curFinishMode;
SRes res; SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize) if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0; p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos; dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos) { if (outSize > p->decoder.dicBufSize - dicPos)
{
outSizeCur = p->decoder.dicBufSize; outSizeCur = p->decoder.dicBufSize;
curFinishMode = LZMA_FINISH_ANY; curFinishMode = LZMA_FINISH_ANY;
} else { }
else
{
outSizeCur = dicPos + outSize; outSizeCur = dicPos + outSize;
curFinishMode = finishMode; curFinishMode = finishMode;
} }
@ -315,30 +327,24 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *
} }
} }
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop, SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{ {
CLzma2Dec decoder; CLzma2Dec p;
SRes res; SRes res;
SizeT outSize = *destLen, inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
Byte props[LZMA_PROPS_SIZE];
Lzma2Dec_Construct(&decoder);
*destLen = *srcLen = 0; *destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
decoder.decoder.dic = dest; Lzma2Dec_Construct(&p);
decoder.decoder.dicBufSize = outSize; RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest;
RINOK(Lzma2Dec_GetOldProps(prop, props)); p.decoder.dicBufSize = outSize;
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); Lzma2Dec_Init(&p);
*srcLen = inSize; *srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = decoder.decoder.dicPos; *destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF; res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc);
LzmaDec_FreeProbs(&decoder.decoder, alloc);
return res; return res;
} }

View File

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

View File

@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder /* LzmaDec.c -- LZMA Decoder
2009-09-20 : Igor Pavlov : Public domain */ 2010-12-15 : Igor Pavlov : Public domain */
#include "LzmaDec.h" #include "LzmaDec.h"
@ -14,51 +14,19 @@
#define RC_INIT_SIZE 5 #define RC_INIT_SIZE 5
#define NORMALIZE \ #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
if (range < kTopValue) { \
range <<= 8; \
code = (code << 8) | (*buf++); \
}
#define IF_BIT_0(p) \ #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
ttt = *(p); \ #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
NORMALIZE; \ #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
bound = (range >> kNumBitModelTotalBits) * ttt; \ #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
if (code < bound) { UPDATE_0(p); i = (i + i); A0; } else \
#define UPDATE_0(p) \ { UPDATE_1(p); i = (i + i) + 1; A1; }
range = bound; \ #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
*(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define UPDATE_1(p) \
range -= bound; \
code -= bound; \
*(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
#define GET_BIT2(p, i, A0, A1) \
IF_BIT_0(p) \
{ \
UPDATE_0(p); \
i = (i + i); \
A0; \
} \
else \
{ \
UPDATE_1(p); \
i = (i + i) + 1; \
A1; \
}
#define GET_BIT(p, i) GET_BIT2(p, i, ;, ;)
#define TREE_GET_BIT(probs, i) \ #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
{ \
GET_BIT((probs + i), i); \
}
#define TREE_DECODE(probs, limit, i) \ #define TREE_DECODE(probs, limit, i) \
{ \ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
i = 1; \
do { \
TREE_GET_BIT(probs, i); \
} while (i < limit); \
i -= limit; \
}
/* #define _LZMA_SIZE_OPT */ /* #define _LZMA_SIZE_OPT */
@ -66,57 +34,28 @@
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
#else #else
#define TREE_6_DECODE(probs, i) \ #define TREE_6_DECODE(probs, i) \
{ \ { i = 1; \
i = 1; \
TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \ TREE_GET_BIT(probs, i); \
i -= 0x40; \ i -= 0x40; }
}
#endif #endif
#define NORMALIZE_CHECK \ #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
if (range < kTopValue) { \
if (buf >= bufLimit) \
return DUMMY_ERROR; \
range <<= 8; \
code = (code << 8) | (*buf++); \
}
#define IF_BIT_0_CHECK(p) \ #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
ttt = *(p); \
NORMALIZE_CHECK; \
bound = (range >> kNumBitModelTotalBits) * ttt; \
if (code < bound)
#define UPDATE_0_CHECK range = bound; #define UPDATE_0_CHECK range = bound;
#define UPDATE_1_CHECK \ #define UPDATE_1_CHECK range -= bound; code -= bound;
range -= bound; \ #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
code -= bound; { UPDATE_0_CHECK; i = (i + i); A0; } else \
#define GET_BIT2_CHECK(p, i, A0, A1) \ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
IF_BIT_0_CHECK(p) \ #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
{ \
UPDATE_0_CHECK; \
i = (i + i); \
A0; \
} \
else \
{ \
UPDATE_1_CHECK; \
i = (i + i) + 1; \
A1; \
}
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ;, ;)
#define TREE_DECODE_CHECK(probs, limit, i) \ #define TREE_DECODE_CHECK(probs, limit, i) \
{ \ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
i = 1; \
do { \
GET_BIT_CHECK(probs + i, i) \
} while (i < limit); \
i -= limit; \
}
#define kNumPosBitsMax 4 #define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax) #define kNumPosStatesMax (1 << kNumPosBitsMax)
@ -135,6 +74,7 @@
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols) #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12 #define kNumStates 12
#define kNumLitStates 7 #define kNumLitStates 7
@ -149,8 +89,7 @@
#define kAlignTableSize (1 << kNumAlignBits) #define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2 #define kMatchMinLen 2
#define kMatchSpecLenStart \ #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
(kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
#define IsMatch 0 #define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
@ -176,9 +115,9 @@ StopCompilingDueBUG
#define LZMA_DIC_MIN (1 << 12) #define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded. /* First LZMA-symbol is always decoded.
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
Out: Out:
Result: Result:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_DATA - Error SZ_ERROR_DATA - Error
@ -187,10 +126,9 @@ StopCompilingDueBUG
= kMatchSpecLenStart : finished = kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker = kMatchSpecLenStart + 1 : Flush marker
= kMatchSpecLenStart + 2 : State Init Marker = kMatchSpecLenStart + 2 : State Init Marker
*/ */
static int MY_FAST_CALL static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{ {
CLzmaProb *probs = p->probs; CLzmaProb *probs = p->probs;
@ -212,7 +150,8 @@ StopCompilingDueBUG
UInt32 range = p->range; UInt32 range = p->range;
UInt32 code = p->code; UInt32 code = p->code;
do { do
{
CLzmaProb *prob; CLzmaProb *prob;
UInt32 bound; UInt32 bound;
unsigned ttt; unsigned ttt;
@ -225,31 +164,31 @@ StopCompilingDueBUG
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + Literal; prob = probs + Literal;
if (checkDicSize != 0 || processedPos != 0) if (checkDicSize != 0 || processedPos != 0)
prob += prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(LZMA_LIT_SIZE *
(((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
if (state < kNumLitStates) { if (state < kNumLitStates)
{
state -= (state < 4) ? state : 3; state -= (state < 4) ? state : 3;
symbol = 1; symbol = 1;
do { do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
GET_BIT(prob + symbol, symbol) }
} while (symbol < 0x100); else
} else { {
unsigned matchByte = unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
unsigned offs = 0x100; unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6; state -= (state < 10) ? 3 : 6;
symbol = 1; symbol = 1;
do { do
{
unsigned bit; unsigned bit;
CLzmaProb *probLit; CLzmaProb *probLit;
matchByte <<= 1; matchByte <<= 1;
bit = (matchByte & offs); bit = (matchByte & offs);
probLit = prob + offs + bit + symbol; probLit = prob + offs + bit + symbol;
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
} while (symbol < 0x100); }
while (symbol < 0x100);
} }
dic[dicPos++] = (Byte)symbol; dic[dicPos++] = (Byte)symbol;
processedPos++; processedPos++;
@ -274,14 +213,11 @@ StopCompilingDueBUG
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
posState;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob); UPDATE_0(prob);
dic[dicPos] = dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dic[(dicPos - rep0) +
((dicPos < rep0) ? dicBufSize : 0)];
dicPos++; dicPos++;
processedPos++; processedPos++;
state = state < kNumLitStates ? 9 : 11; state = state < kNumLitStates ? 9 : 11;
@ -339,8 +275,7 @@ StopCompilingDueBUG
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = probLen = prob + LenMid + (posState << kLenNumMidBits);
prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
limit = (1 << kLenNumMidBits); limit = (1 << kLenNumMidBits);
} }
@ -356,44 +291,45 @@ StopCompilingDueBUG
len += offset; len += offset;
} }
if (state >= kNumStates) { if (state >= kNumStates)
{
UInt32 distance; UInt32 distance;
prob = probs + PosSlot + prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
<< kNumPosSlotBits);
TREE_6_DECODE(prob, distance); TREE_6_DECODE(prob, distance);
if (distance >= kStartPosModelIndex) { if (distance >= kStartPosModelIndex)
{
unsigned posSlot = (unsigned)distance; unsigned posSlot = (unsigned)distance;
int numDirectBits = (int)(((distance >> 1) - 1)); int numDirectBits = (int)(((distance >> 1) - 1));
distance = (2 | (distance & 1)); distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex) { if (posSlot < kEndPosModelIndex)
{
distance <<= numDirectBits; distance <<= numDirectBits;
prob = probs + SpecPos + distance - posSlot - 1; prob = probs + SpecPos + distance - posSlot - 1;
{ {
UInt32 mask = 1; UInt32 mask = 1;
unsigned i = 1; unsigned i = 1;
do { do
GET_BIT2(prob + i, i, {
; GET_BIT2(prob + i, i, ; , distance |= mask);
, distance |= mask);
mask <<= 1; mask <<= 1;
} while (--numDirectBits != 0);
} }
} else { while (--numDirectBits != 0);
}
}
else
{
numDirectBits -= kNumAlignBits; numDirectBits -= kNumAlignBits;
do { do
{
NORMALIZE NORMALIZE
range >>= 1; range >>= 1;
{ {
UInt32 t; UInt32 t;
code -= range; code -= range;
t = (0 - t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
((UInt32)code >> distance = (distance << 1) + (t + 1);
31)); /* (UInt32)((Int32)code
>> 31) */
distance =
(distance << 1) + (t + 1);
code += range & t; code += range & t;
} }
/* /*
@ -404,17 +340,19 @@ StopCompilingDueBUG
distance |= 1; distance |= 1;
} }
*/ */
} while (--numDirectBits != 0); }
while (--numDirectBits != 0);
prob = probs + Align; prob = probs + Align;
distance <<= kNumAlignBits; distance <<= kNumAlignBits;
{ {
unsigned i = 1; unsigned i = 1;
GET_BIT2(prob + i, i, ;, distance |= 1); GET_BIT2(prob + i, i, ; , distance |= 1);
GET_BIT2(prob + i, i, ;, distance |= 2); GET_BIT2(prob + i, i, ; , distance |= 2);
GET_BIT2(prob + i, i, ;, distance |= 4); GET_BIT2(prob + i, i, ; , distance |= 4);
GET_BIT2(prob + i, i, ;, distance |= 8); GET_BIT2(prob + i, i, ; , distance |= 8);
} }
if (distance == (UInt32)0xFFFFFFFF) { if (distance == (UInt32)0xFFFFFFFF)
{
len += kMatchSpecLenStart; len += kMatchSpecLenStart;
state -= kNumStates; state -= kNumStates;
break; break;
@ -425,13 +363,14 @@ StopCompilingDueBUG
rep2 = rep1; rep2 = rep1;
rep1 = rep0; rep1 = rep0;
rep0 = distance + 1; rep0 = distance + 1;
if (checkDicSize == 0) { if (checkDicSize == 0)
{
if (distance >= processedPos) if (distance >= processedPos)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} else if (distance >= checkDicSize) }
else if (distance >= checkDicSize)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
state = (state < kNumStates + kNumLitStates) ? kNumLitStates state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
: kNumLitStates + 3;
} }
len += kMatchMinLen; len += kMatchMinLen;
@ -446,24 +385,30 @@ StopCompilingDueBUG
processedPos += curLen; processedPos += curLen;
len -= curLen; len -= curLen;
if (pos + curLen <= dicBufSize) { if (pos + curLen <= dicBufSize)
{
Byte *dest = dic + dicPos; Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
const Byte *lim = dest + curLen; const Byte *lim = dest + curLen;
dicPos += curLen; dicPos += curLen;
do do
*(dest) = (Byte) * (dest + src); *(dest) = (Byte)*(dest + src);
while (++dest != lim); while (++dest != lim);
} else { }
do { else
{
do
{
dic[dicPos++] = dic[pos]; dic[dicPos++] = dic[pos];
if (++pos == dicBufSize) if (++pos == dicBufSize)
pos = 0; pos = 0;
} while (--curLen != 0); }
while (--curLen != 0);
} }
} }
} }
} while (dicPos < limit && buf < bufLimit); }
while (dicPos < limit && buf < bufLimit);
NORMALIZE; NORMALIZE;
p->buf = buf; p->buf = buf;
p->range = range; p->range = range;
@ -482,7 +427,8 @@ StopCompilingDueBUG
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
{ {
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) { if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
{
Byte *dic = p->dic; Byte *dic = p->dic;
SizeT dicPos = p->dicPos; SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize; SizeT dicBufSize = p->dicBufSize;
@ -496,7 +442,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
p->processedPos += len; p->processedPos += len;
p->remainLen -= len; p->remainLen -= len;
while (len-- != 0) { while (len != 0)
{
len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dicPos++; dicPos++;
} }
@ -506,9 +454,11 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{ {
do { do
{
SizeT limit2 = limit; SizeT limit2 = limit;
if (p->checkDicSize == 0) { if (p->checkDicSize == 0)
{
UInt32 rem = p->prop.dicSize - p->processedPos; UInt32 rem = p->prop.dicSize - p->processedPos;
if (limit - p->dicPos > rem) if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem; limit2 = p->dicPos + rem;
@ -517,15 +467,18 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
if (p->processedPos >= p->prop.dicSize) if (p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
LzmaDec_WriteRem(p, limit); LzmaDec_WriteRem(p, limit);
} while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); }
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart) { if (p->remainLen > kMatchSpecLenStart)
{
p->remainLen = kMatchSpecLenStart; p->remainLen = kMatchSpecLenStart;
} }
return 0; return 0;
} }
typedef enum { typedef enum
{
DUMMY_ERROR, /* unexpected end of input stream */ DUMMY_ERROR, /* unexpected end of input stream */
DUMMY_LIT, DUMMY_LIT,
DUMMY_MATCH, DUMMY_MATCH,
@ -556,32 +509,31 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal; prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0) if (p->checkDicSize != 0 || p->processedPos != 0)
prob += prob += (LZMA_LIT_SIZE *
(LZMA_LIT_SIZE * ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
<< p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >>
(8 - p->prop.lc))));
if (state < kNumLitStates) { if (state < kNumLitStates)
{
unsigned symbol = 1; unsigned symbol = 1;
do { do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
GET_BIT_CHECK(prob + symbol, symbol) }
} while (symbol < 0x100); else
} else { {
unsigned matchByte = unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
p->dic[p->dicPos - p->reps[0] +
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
unsigned offs = 0x100; unsigned offs = 0x100;
unsigned symbol = 1; unsigned symbol = 1;
do { do
{
unsigned bit; unsigned bit;
CLzmaProb *probLit; CLzmaProb *probLit;
matchByte <<= 1; matchByte <<= 1;
bit = (matchByte & offs); bit = (matchByte & offs);
probLit = prob + offs + bit + symbol; probLit = prob + offs + bit + symbol;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
} while (symbol < 0x100); }
while (symbol < 0x100);
} }
res = DUMMY_LIT; res = DUMMY_LIT;
} }
@ -606,8 +558,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
posState;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
@ -661,8 +612,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
probLen = probLen = prob + LenMid + (posState << kLenNumMidBits);
prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
limit = 1 << kLenNumMidBits; limit = 1 << kLenNumMidBits;
} }
@ -678,38 +628,44 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
len += offset; len += offset;
} }
if (state < 4) { if (state < 4)
{
unsigned posSlot; unsigned posSlot;
prob = probs + PosSlot + prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
<< kNumPosSlotBits); kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex) { if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1); int numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
if (posSlot < kEndPosModelIndex) { if (posSlot < kEndPosModelIndex)
prob = probs + SpecPos + {
((2 | (posSlot & 1)) << numDirectBits) - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
posSlot - 1; }
} else { else
{
numDirectBits -= kNumAlignBits; numDirectBits -= kNumAlignBits;
do { do
{
NORMALIZE_CHECK NORMALIZE_CHECK
range >>= 1; range >>= 1;
code -= code -= range & (((code - range) >> 31) - 1);
range & (((code - range) >> 31) - 1);
/* if (code >= range) code -= range; */ /* if (code >= range) code -= range; */
} while (--numDirectBits != 0); }
while (--numDirectBits != 0);
prob = probs + Align; prob = probs + Align;
numDirectBits = kNumAlignBits; numDirectBits = kNumAlignBits;
} }
{ {
unsigned i = 1; unsigned i = 1;
do { do
{
GET_BIT_CHECK(prob + i, i); GET_BIT_CHECK(prob + i, i);
} while (--numDirectBits != 0); }
while (--numDirectBits != 0);
} }
} }
} }
@ -719,10 +675,10 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
return res; return res;
} }
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
{ {
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
((UInt32)data[4]);
p->range = 0xFFFFFFFF; p->range = 0xFFFFFFFF;
p->needFlush = 0; p->needFlush = 0;
} }
@ -733,7 +689,8 @@ void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
p->remainLen = 0; p->remainLen = 0;
p->tempBufSize = 0; p->tempBufSize = 0;
if (initDic) { if (initDic)
{
p->processedPos = 0; p->processedPos = 0;
p->checkDicSize = 0; p->checkDicSize = 0;
p->needInitState = 1; p->needInitState = 1;
@ -769,13 +726,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
while (p->remainLen != kMatchSpecLenStart) { while (p->remainLen != kMatchSpecLenStart)
{
int checkEndMarkNow; int checkEndMarkNow;
if (p->needFlush != 0) { if (p->needFlush != 0)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++; p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE) { if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
@ -787,16 +747,20 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
} }
checkEndMarkNow = 0; checkEndMarkNow = 0;
if (p->dicPos >= dicLimit) { if (p->dicPos >= dicLimit)
if (p->remainLen == 0 && p->code == 0) { {
if (p->remainLen == 0 && p->code == 0)
{
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
return SZ_OK; return SZ_OK;
} }
if (finishMode == LZMA_FINISH_ANY) { if (finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK; return SZ_OK;
} }
if (p->remainLen != 0) { if (p->remainLen != 0)
{
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} }
@ -806,24 +770,29 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
if (p->needInitState) if (p->needInitState)
LzmaDec_InitStateReal(p); LzmaDec_InitStateReal(p);
if (p->tempBufSize == 0) { if (p->tempBufSize == 0)
{
SizeT processed; SizeT processed;
const Byte *bufLimit; const Byte *bufLimit;
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) { if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{
int dummyRes = LzmaDec_TryDummy(p, src, inSize); int dummyRes = LzmaDec_TryDummy(p, src, inSize);
if (dummyRes == DUMMY_ERROR) { if (dummyRes == DUMMY_ERROR)
{
memcpy(p->tempBuf, src, inSize); memcpy(p->tempBuf, src, inSize);
p->tempBufSize = (unsigned)inSize; p->tempBufSize = (unsigned)inSize;
(*srcLen) += inSize; (*srcLen) += inSize;
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
if (checkEndMarkNow && dummyRes != DUMMY_MATCH) { if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} }
bufLimit = src; bufLimit = src;
} else }
else
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
p->buf = src; p->buf = src;
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
@ -832,19 +801,24 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
(*srcLen) += processed; (*srcLen) += processed;
src += processed; src += processed;
inSize -= processed; inSize -= processed;
} else { }
else
{
unsigned rem = p->tempBufSize, lookAhead = 0; unsigned rem = p->tempBufSize, lookAhead = 0;
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
p->tempBuf[rem++] = src[lookAhead++]; p->tempBuf[rem++] = src[lookAhead++];
p->tempBufSize = rem; p->tempBufSize = rem;
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) { if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
if (dummyRes == DUMMY_ERROR) { if (dummyRes == DUMMY_ERROR)
{
(*srcLen) += lookAhead; (*srcLen) += lookAhead;
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return SZ_OK;
} }
if (checkEndMarkNow && dummyRes != DUMMY_MATCH) { if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} }
@ -864,23 +838,26 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
} }
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen; SizeT outSize = *destLen;
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) { for (;;)
{
SizeT inSizeCur = inSize, outSizeCur, dicPos; SizeT inSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode; ELzmaFinishMode curFinishMode;
SRes res; SRes res;
if (p->dicPos == p->dicBufSize) if (p->dicPos == p->dicBufSize)
p->dicPos = 0; p->dicPos = 0;
dicPos = p->dicPos; dicPos = p->dicPos;
if (outSize > p->dicBufSize - dicPos) { if (outSize > p->dicBufSize - dicPos)
{
outSizeCur = p->dicBufSize; outSizeCur = p->dicBufSize;
curFinishMode = LZMA_FINISH_ANY; curFinishMode = LZMA_FINISH_ANY;
} else { }
else
{
outSizeCur = dicPos + outSize; outSizeCur = dicPos + outSize;
curFinishMode = finishMode; curFinishMode = finishMode;
} }
@ -927,8 +904,7 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
if (size < LZMA_PROPS_SIZE) if (size < LZMA_PROPS_SIZE)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
else else
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
((UInt32)data[4] << 24);
if (dicSize < LZMA_DIC_MIN) if (dicSize < LZMA_DIC_MIN)
dicSize = LZMA_DIC_MIN; dicSize = LZMA_DIC_MIN;
@ -949,7 +925,8 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{ {
UInt32 numProbs = LzmaProps_GetNumProbs(propNew); UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (p->probs == 0 || numProbs != p->numProbs) { if (p->probs == 0 || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs; p->numProbs = numProbs;
@ -975,10 +952,12 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
RINOK(LzmaProps_Decode(&propNew, props, propsSize)); RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
dicBufSize = propNew.dicSize; dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize) { if (p->dic == 0 || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
if (p->dic == 0) { if (p->dic == 0)
{
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
} }
@ -988,33 +967,27 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
return SZ_OK; return SZ_OK;
} }
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc)
{ {
CLzmaDec p; CLzmaDec p;
SRes res; SRes res;
SizeT inSize = *srcLen; SizeT outSize = *destLen, inSize = *srcLen;
SizeT outSize = *destLen; *destLen = *srcLen = 0;
*srcLen = *destLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED;
if (inSize < RC_INIT_SIZE) if (inSize < RC_INIT_SIZE)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
LzmaDec_Construct(&p); LzmaDec_Construct(&p);
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
if (res != 0)
return res;
p.dic = dest; p.dic = dest;
p.dicBufSize = outSize; p.dicBufSize = outSize;
LzmaDec_Init(&p); LzmaDec_Init(&p);
*srcLen = inSize; *srcLen = inSize;
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF; res = SZ_ERROR_INPUT_EOF;
(*destLen) = p.dicPos;
LzmaDec_FreeProbs(&p, alloc); LzmaDec_FreeProbs(&p, alloc);
return res; return res;
} }

View File

@ -20,11 +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;
@ -37,6 +39,7 @@ Returns:
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */ /* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
@ -44,7 +47,8 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
#define LZMA_REQUIRED_INPUT_MAX 20 #define LZMA_REQUIRED_INPUT_MAX 20
typedef struct { typedef struct
{
CLzmaProps prop; CLzmaProps prop;
CLzmaProb *probs; CLzmaProb *probs;
Byte *dic; Byte *dic;
@ -64,11 +68,7 @@ typedef struct {
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) \ #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
{ \
(p)->dic = 0; \
(p)->probs = 0; \
}
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec *p);
@ -76,7 +76,8 @@ void LzmaDec_Init(CLzmaDec *p);
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum { typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */ LZMA_FINISH_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;
@ -96,17 +97,18 @@ typedef enum {
3) Check that output(srcLen) = compressedSize, if you know real compressedSize. 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */ You must use correct finish mode in that case. */
typedef enum { typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ LZMA_STATUS_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 LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
without end mark */
} ELzmaStatus; } ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */ /* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */ /* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces: /* There are 3 levels of interfaces:
@ -116,6 +118,7 @@ typedef enum {
You can select any of these interfaces, but don't mix functions from different You can select any of these interfaces, but don't mix functions from different
groups for same object. */ groups for same object. */
/* There are two variants to allocate state for Dictionary Interface: /* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free 1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
@ -175,8 +178,9 @@ Returns:
SZ_ERROR_DATA - Data error SZ_ERROR_DATA - Data error
*/ */
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */ /* ---------- Buffer Interface ---------- */
@ -191,8 +195,9 @@ finishMode:
LZMA_FINISH_END - Stream must be finished after (*destLen). LZMA_FINISH_END - Stream must be finished after (*destLen).
*/ */
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
ELzmaFinishMode finishMode, ELzmaStatus *status); const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */ /* ---------- One Call Interface ---------- */
@ -215,9 +220,9 @@ Returns:
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/ */
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ISzAlloc *alloc); ELzmaStatus *status, ISzAlloc *alloc);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,17 +1,17 @@
/* Ppmd.h -- PPMD codec common code /* Ppmd.h -- PPMD codec common code
2010-03-12 : Igor Pavlov : Public domain 2011-01-27 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H #ifndef __PPMD_H
#define __PPMD_H #define __PPMD_H
#include "CpuArch.h"
#include "Types.h" #include "Types.h"
#include "CpuArch.h"
EXTERN_C_BEGIN EXTERN_C_BEGIN
#ifdef MY_CPU_32BIT #ifdef MY_CPU_32BIT
#define PPMD_32BIT #define PPMD_32BIT
#endif #endif
#define PPMD_INT_BITS 7 #define PPMD_INT_BITS 7
@ -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
@ -29,58 +29,57 @@ EXTERN_C_BEGIN
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) #define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) #define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
#pragma pack(push, 1)
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
/* 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) \ #define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) { \ { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
(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)
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) { \
unsigned i; \ 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; }}
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

View File

@ -7,20 +7,19 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Ppmd7.h" #include "Ppmd7.h"
const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
static const UInt16 kInitBinEsc[] = static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
{ 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051 };
#define MAX_FREQ 124 #define MAX_FREQ 124
#define UNIT_SIZE 12 #define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu)*UNIT_SIZE) #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
#define U2I(nu) (p->Units2Indx[(nu)-1]) #define U2I(nu) (p->Units2Indx[(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx]) #define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
#define REF(ptr) (ptr) #define REF(ptr) (ptr)
#else #else
#define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
#endif #endif
#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) #define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
@ -30,19 +29,20 @@ static const UInt16 kInitBinEsc[] =
#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) #define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
#define SUFFIX(ctx) CTX((ctx)->Suffix) #define SUFFIX(ctx) CTX((ctx)->Suffix)
typedef CPpmd7_Context *CTX_PTR; typedef CPpmd7_Context * CTX_PTR;
struct CPpmd7_Node_; struct CPpmd7_Node_;
typedef typedef
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
struct CPpmd7_Node_ * struct CPpmd7_Node_ *
#else #else
UInt32 UInt32
#endif #endif
CPpmd7_Node_Ref; CPpmd7_Node_Ref;
typedef struct CPpmd7_Node_ { typedef struct CPpmd7_Node_
{
UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
UInt16 NU; UInt16 NU;
CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
@ -50,9 +50,9 @@ typedef struct CPpmd7_Node_ {
} CPpmd7_Node; } CPpmd7_Node;
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
#define NODE(ptr) (ptr) #define NODE(ptr) (ptr)
#else #else
#define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
#endif #endif
void Ppmd7_Construct(CPpmd7 *p) void Ppmd7_Construct(CPpmd7 *p)
@ -61,11 +61,10 @@ void Ppmd7_Construct(CPpmd7 *p)
p->Base = 0; p->Base = 0;
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) { for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { do { p->Units2Indx[k++] = (Byte)i; } while(--step);
p->Units2Indx[k++] = (Byte)i;
} while (--step);
p->Indx2Units[i] = (Byte)k; p->Indx2Units[i] = (Byte)k;
} }
@ -76,7 +75,8 @@ void Ppmd7_Construct(CPpmd7 *p)
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
p->NS2Indx[i] = (Byte)i; p->NS2Indx[i] = (Byte)i;
for (m = i, k = 1; i < 256; i++) { for (m = i, k = 1; i < 256; i++)
{
p->NS2Indx[i] = (Byte)m; p->NS2Indx[i] = (Byte)m;
if (--k == 0) if (--k == 0)
k = (++m) - 2; k = (++m) - 2;
@ -95,20 +95,19 @@ void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc) Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
{ {
if (p->Base == 0 || p->Size != size) { if (p->Base == 0 || p->Size != size)
{
Ppmd7_Free(p, alloc); Ppmd7_Free(p, alloc);
p->AlignOffset = p->AlignOffset =
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
(4 - size) & 3; (4 - size) & 3;
#else #else
4 - (size & 3); 4 - (size & 3);
#endif #endif
if ((p->Base = (Byte *)alloc->Alloc(alloc, if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
p->AlignOffset + size #ifndef PPMD_32BIT
#ifndef PPMD_32BIT + UNIT_SIZE
+ #endif
UNIT_SIZE
#endif
)) == 0) )) == 0)
return False; return False;
p->Size = size; p->Size = size;
@ -133,7 +132,8 @@ static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
{ {
unsigned i, nu = I2U(oldIndx) - I2U(newIndx); unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
ptr = (Byte *)ptr + U2B(I2U(newIndx)); ptr = (Byte *)ptr + U2B(I2U(newIndx));
if (I2U(i = U2I(nu)) != nu) { if (I2U(i = U2I(nu)) != nu)
{
unsigned k = I2U(--i); unsigned k = I2U(--i);
InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
} }
@ -142,12 +142,12 @@ static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
static void GlueFreeBlocks(CPpmd7 *p) static void GlueFreeBlocks(CPpmd7 *p)
{ {
#ifdef PPMD_32BIT #ifdef PPMD_32BIT
CPpmd7_Node headItem; CPpmd7_Node headItem;
CPpmd7_Node_Ref head = &headItem; CPpmd7_Node_Ref head = &headItem;
#else #else
CPpmd7_Node_Ref head = p->AlignOffset + p->Size; CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
#endif #endif
CPpmd7_Node_Ref n = head; CPpmd7_Node_Ref n = head;
unsigned i; unsigned i;
@ -155,11 +155,13 @@ static void GlueFreeBlocks(CPpmd7 *p)
p->GlueCount = 255; p->GlueCount = 255;
/* create doubly-linked list of free blocks */ /* create doubly-linked list of free blocks */
for (i = 0; i < PPMD_NUM_INDEXES; i++) { for (i = 0; i < PPMD_NUM_INDEXES; i++)
{
UInt16 nu = I2U(i); UInt16 nu = I2U(i);
CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
p->FreeList[i] = 0; p->FreeList[i] = 0;
while (next != 0) { while (next != 0)
{
CPpmd7_Node *node = NODE(next); CPpmd7_Node *node = NODE(next);
node->Next = n; node->Next = n;
n = NODE(n)->Prev = next; n = NODE(n)->Prev = next;
@ -175,10 +177,12 @@ static void GlueFreeBlocks(CPpmd7 *p)
((CPpmd7_Node *)p->LoUnit)->Stamp = 1; ((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
/* Glue free blocks */ /* Glue free blocks */
while (n != head) { while (n != head)
{
CPpmd7_Node *node = NODE(n); CPpmd7_Node *node = NODE(n);
UInt32 nu = (UInt32)node->NU; UInt32 nu = (UInt32)node->NU;
for (;;) { for (;;)
{
CPpmd7_Node *node2 = NODE(n) + nu; CPpmd7_Node *node2 = NODE(n) + nu;
nu += node2->NU; nu += node2->NU;
if (node2->Stamp != 0 || nu >= 0x10000) if (node2->Stamp != 0 || nu >= 0x10000)
@ -191,13 +195,15 @@ static void GlueFreeBlocks(CPpmd7 *p)
} }
/* Fill lists of free blocks */ /* Fill lists of free blocks */
for (n = NODE(head)->Next; n != head;) { for (n = NODE(head)->Next; n != head;)
{
CPpmd7_Node *node = NODE(n); CPpmd7_Node *node = NODE(n);
unsigned nu; unsigned nu;
CPpmd7_Node_Ref next = node->Next; CPpmd7_Node_Ref next = node->Next;
for (nu = node->NU; nu > 128; nu -= 128, node += 128) for (nu = node->NU; nu > 128; nu -= 128, node += 128)
InsertNode(p, node, PPMD_NUM_INDEXES - 1); InsertNode(p, node, PPMD_NUM_INDEXES - 1);
if (I2U(i = U2I(nu)) != nu) { if (I2U(i = U2I(nu)) != nu)
{
unsigned k = I2U(--i); unsigned k = I2U(--i);
InsertNode(p, node + k, nu - k - 1); InsertNode(p, node + k, nu - k - 1);
} }
@ -210,21 +216,23 @@ static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
{ {
unsigned i; unsigned i;
void *retVal; void *retVal;
if (p->GlueCount == 0) { if (p->GlueCount == 0)
{
GlueFreeBlocks(p); GlueFreeBlocks(p);
if (p->FreeList[indx] != 0) if (p->FreeList[indx] != 0)
return RemoveNode(p, indx); return RemoveNode(p, indx);
} }
i = indx; i = indx;
do { do
if (++i == PPMD_NUM_INDEXES) { {
if (++i == PPMD_NUM_INDEXES)
{
UInt32 numBytes = U2B(I2U(indx)); UInt32 numBytes = U2B(I2U(indx));
p->GlueCount--; p->GlueCount--;
return ((UInt32)(p->UnitsStart - p->Text) > numBytes) return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
? (p->UnitsStart -= numBytes)
: (NULL);
} }
} while (p->FreeList[i] == 0); }
while (p->FreeList[i] == 0);
retVal = RemoveNode(p, i); retVal = RemoveNode(p, i);
SplitBlock(p, retVal, i, indx); SplitBlock(p, retVal, i, indx);
return retVal; return retVal;
@ -236,7 +244,8 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
if (p->FreeList[indx] != 0) if (p->FreeList[indx] != 0)
return RemoveNode(p, indx); return RemoveNode(p, indx);
numBytes = U2B(I2U(indx)); numBytes = U2B(I2U(indx));
if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) { if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
{
void *retVal = p->LoUnit; void *retVal = p->LoUnit;
p->LoUnit += numBytes; p->LoUnit += numBytes;
return retVal; return retVal;
@ -245,18 +254,8 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
} }
#define MyMem12Cpy(dest, src, num) \ #define MyMem12Cpy(dest, src, num) \
{ \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
UInt32 *d = (UInt32 *)dest; \ do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
const UInt32 *s = (const UInt32 *)src; \
UInt32 n = num; \
do { \
d[0] = s[0]; \
d[1] = s[1]; \
d[2] = s[2]; \
s += 3; \
d += 3; \
} while (--n); \
}
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{ {
@ -264,7 +263,8 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU
unsigned i1 = U2I(newNU); unsigned i1 = U2I(newNU);
if (i0 == i1) if (i0 == i1)
return oldPtr; return oldPtr;
if (p->FreeList[i1] != 0) { if (p->FreeList[i1] != 0)
{
void *ptr = RemoveNode(p, i1); void *ptr = RemoveNode(p, i1);
MyMem12Cpy(ptr, oldPtr, newNU); MyMem12Cpy(ptr, oldPtr, newNU);
InsertNode(p, oldPtr, i0); InsertNode(p, oldPtr, i0);
@ -278,7 +278,7 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU
static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
{ {
(p)->SuccessorLow = (UInt16)((UInt32)(v)&0xFFFF); (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
(p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
} }
@ -303,7 +303,8 @@ static void RestartModel(CPpmd7 *p)
p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
p->LoUnit += U2B(256 / 2); p->LoUnit += U2B(256 / 2);
p->MinContext->Stats = REF(p->FoundState); p->MinContext->Stats = REF(p->FoundState);
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++)
{
CPpmd_State *s = &p->FoundState[i]; CPpmd_State *s = &p->FoundState[i];
s->Symbol = (Byte)i; s->Symbol = (Byte)i;
s->Freq = 1; s->Freq = 1;
@ -311,7 +312,8 @@ static void RestartModel(CPpmd7 *p)
} }
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
for (k = 0; k < 8; k++) { for (k = 0; k < 8; k++)
{
UInt16 *dest = p->BinSumm[i] + k; UInt16 *dest = p->BinSumm[i] + k;
UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
for (m = 0; m < 64; m += 8) for (m = 0; m < 64; m += 8)
@ -319,7 +321,8 @@ static void RestartModel(CPpmd7 *p)
} }
for (i = 0; i < 25; i++) for (i = 0; i < 25; i++)
for (k = 0; k < 16; k++) { for (k = 0; k < 16; k++)
{
CPpmd_See *s = &p->See[i][k]; CPpmd_See *s = &p->See[i][k];
s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
s->Count = 4; s->Count = 4;
@ -346,17 +349,20 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
if (!skip) if (!skip)
ps[numPs++] = p->FoundState; ps[numPs++] = p->FoundState;
while (c->Suffix) { while (c->Suffix)
{
CPpmd_Void_Ref successor; CPpmd_Void_Ref successor;
CPpmd_State *s; CPpmd_State *s;
c = SUFFIX(c); c = SUFFIX(c);
if (c->NumStats != 1) { if (c->NumStats != 1)
for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++) {
; for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
} else }
else
s = ONE_STATE(c); s = ONE_STATE(c);
successor = SUCCESSOR(s); successor = SUCCESSOR(s);
if (successor != upBranch) { if (successor != upBranch)
{
c = CTX(successor); c = CTX(successor);
if (numPs == 0) if (numPs == 0)
return c; return c;
@ -370,25 +376,26 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
if (c->NumStats == 1) if (c->NumStats == 1)
upState.Freq = ONE_STATE(c)->Freq; upState.Freq = ONE_STATE(c)->Freq;
else { else
{
UInt32 cf, s0; UInt32 cf, s0;
CPpmd_State *s; CPpmd_State *s;
for (s = STATS(c); s->Symbol != upState.Symbol; s++) for (s = STATS(c); s->Symbol != upState.Symbol; s++);
;
cf = s->Freq - 1; cf = s->Freq - 1;
s0 = c->SummFreq - c->NumStats - cf; s0 = c->SummFreq - c->NumStats - cf;
upState.Freq = (Byte)( upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
} }
do { do
{
/* Create Child */ /* Create Child */
CTX_PTR c1; /* = AllocContext(p); */ CTX_PTR c1; /* = AllocContext(p); */
if (p->HiUnit != p->LoUnit) if (p->HiUnit != p->LoUnit)
c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
else if (p->FreeList[0] != 0) else if (p->FreeList[0] != 0)
c1 = (CTX_PTR)RemoveNode(p, 0); c1 = (CTX_PTR)RemoveNode(p, 0);
else { else
{
c1 = (CTX_PTR)AllocUnitsRare(p, 0); c1 = (CTX_PTR)AllocUnitsRare(p, 0);
if (!c1) if (!c1)
return NULL; return NULL;
@ -398,7 +405,8 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
c1->Suffix = REF(c); c1->Suffix = REF(c);
SetSuccessor(ps[--numPs], REF(c1)); SetSuccessor(ps[--numPs], REF(c1));
c = c1; c = c1;
} while (numPs != 0); }
while (numPs != 0);
return c; return c;
} }
@ -416,34 +424,41 @@ static void UpdateModel(CPpmd7 *p)
CTX_PTR c; CTX_PTR c;
unsigned s0, ns; unsigned s0, ns;
if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) { if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
{
c = SUFFIX(p->MinContext); c = SUFFIX(p->MinContext);
if (c->NumStats == 1) { if (c->NumStats == 1)
{
CPpmd_State *s = ONE_STATE(c); CPpmd_State *s = ONE_STATE(c);
if (s->Freq < 32) if (s->Freq < 32)
s->Freq++; s->Freq++;
} else { }
else
{
CPpmd_State *s = STATS(c); CPpmd_State *s = STATS(c);
if (s->Symbol != p->FoundState->Symbol) { if (s->Symbol != p->FoundState->Symbol)
do { {
s++; do { s++; } while (s->Symbol != p->FoundState->Symbol);
} while (s->Symbol != p->FoundState->Symbol); if (s[0].Freq >= s[-1].Freq)
if (s[0].Freq >= s[-1].Freq) { {
SwapStates(&s[0], &s[-1]); SwapStates(&s[0], &s[-1]);
s--; s--;
} }
} }
if (s->Freq < MAX_FREQ - 9) { if (s->Freq < MAX_FREQ - 9)
{
s->Freq += 2; s->Freq += 2;
c->SummFreq += 2; c->SummFreq += 2;
} }
} }
} }
if (p->OrderFall == 0) { if (p->OrderFall == 0)
{
p->MinContext = p->MaxContext = CreateSuccessors(p, True); p->MinContext = p->MaxContext = CreateSuccessors(p, True);
if (p->MinContext == 0) { if (p->MinContext == 0)
{
RestartModel(p); RestartModel(p);
return; return;
} }
@ -453,43 +468,55 @@ static void UpdateModel(CPpmd7 *p)
*p->Text++ = p->FoundState->Symbol; *p->Text++ = p->FoundState->Symbol;
successor = REF(p->Text); successor = REF(p->Text);
if (p->Text >= p->UnitsStart) { if (p->Text >= p->UnitsStart)
{
RestartModel(p); RestartModel(p);
return; return;
} }
if (fSuccessor) { if (fSuccessor)
if (fSuccessor <= successor) { {
if (fSuccessor <= successor)
{
CTX_PTR cs = CreateSuccessors(p, False); CTX_PTR cs = CreateSuccessors(p, False);
if (cs == NULL) { if (cs == NULL)
{
RestartModel(p); RestartModel(p);
return; return;
} }
fSuccessor = REF(cs); fSuccessor = REF(cs);
} }
if (--p->OrderFall == 0) { if (--p->OrderFall == 0)
{
successor = fSuccessor; successor = fSuccessor;
p->Text -= (p->MaxContext != p->MinContext); p->Text -= (p->MaxContext != p->MinContext);
} }
} else { }
else
{
SetSuccessor(p->FoundState, successor); SetSuccessor(p->FoundState, successor);
fSuccessor = REF(p->MinContext); fSuccessor = REF(p->MinContext);
} }
s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) { for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
{
unsigned ns1; unsigned ns1;
UInt32 cf, sf; UInt32 cf, sf;
if ((ns1 = c->NumStats) != 1) { if ((ns1 = c->NumStats) != 1)
if ((ns1 & 1) == 0) { {
if ((ns1 & 1) == 0)
{
/* Expand for one UNIT */ /* Expand for one UNIT */
unsigned oldNU = ns1 >> 1; unsigned oldNU = ns1 >> 1;
unsigned i = U2I(oldNU); unsigned i = U2I(oldNU);
if (i != U2I(oldNU + 1)) { if (i != U2I(oldNU + 1))
{
void *ptr = AllocUnits(p, i + 1); void *ptr = AllocUnits(p, i + 1);
void *oldPtr; void *oldPtr;
if (!ptr) { if (!ptr)
{
RestartModel(p); RestartModel(p);
return; return;
} }
@ -499,11 +526,13 @@ static void UpdateModel(CPpmd7 *p)
c->Stats = STATS_REF(ptr); c->Stats = STATS_REF(ptr);
} }
} }
c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); }
} else { else
CPpmd_State *s = (CPpmd_State *)AllocUnits(p, 0); {
if (!s) { CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
if (!s)
{
RestartModel(p); RestartModel(p);
return; return;
} }
@ -517,10 +546,13 @@ static void UpdateModel(CPpmd7 *p)
} }
cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
sf = (UInt32)s0 + c->SummFreq; sf = (UInt32)s0 + c->SummFreq;
if (cf < 6 * sf) { if (cf < 6 * sf)
{
cf = 1 + (cf > sf) + (cf >= 4 * sf); cf = 1 + (cf > sf) + (cf >= 4 * sf);
c->SummFreq += 3; c->SummFreq += 3;
} else { }
else
{
cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
c->SummFreq = (UInt16)(c->SummFreq + cf); c->SummFreq = (UInt16)(c->SummFreq + cf);
} }
@ -553,11 +585,13 @@ static void Rescale(CPpmd7 *p)
sumFreq = s->Freq; sumFreq = s->Freq;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do { do
{
escFreq -= (++s)->Freq; escFreq -= (++s)->Freq;
s->Freq = (Byte)((s->Freq + adder) >> 1); s->Freq = (Byte)((s->Freq + adder) >> 1);
sumFreq += s->Freq; sumFreq += s->Freq;
if (s[0].Freq > s[-1].Freq) { if (s[0].Freq > s[-1].Freq)
{
CPpmd_State *s1 = s; CPpmd_State *s1 = s;
CPpmd_State tmp = *s1; CPpmd_State tmp = *s1;
do do
@ -565,22 +599,25 @@ static void Rescale(CPpmd7 *p)
while (--s1 != stats && tmp.Freq > s1[-1].Freq); while (--s1 != stats && tmp.Freq > s1[-1].Freq);
*s1 = tmp; *s1 = tmp;
} }
} while (--i); }
while (--i);
if (s->Freq == 0) { if (s->Freq == 0)
{
unsigned numStats = p->MinContext->NumStats; unsigned numStats = p->MinContext->NumStats;
unsigned n0, n1; unsigned n0, n1;
do { do { i++; } while ((--s)->Freq == 0);
i++;
} while ((--s)->Freq == 0);
escFreq += i; escFreq += i;
p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
if (p->MinContext->NumStats == 1) { if (p->MinContext->NumStats == 1)
{
CPpmd_State tmp = *stats; CPpmd_State tmp = *stats;
do { do
{
tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
escFreq >>= 1; escFreq >>= 1;
} while (escFreq > 1); }
while (escFreq > 1);
InsertNode(p, stats, U2I(((numStats + 1) >> 1))); InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
*(p->FoundState = ONE_STATE(p->MinContext)) = tmp; *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
return; return;
@ -598,18 +635,21 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
{ {
CPpmd_See *see; CPpmd_See *see;
unsigned nonMasked = p->MinContext->NumStats - numMasked; unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256) { if (p->MinContext->NumStats != 256)
{
see = p->See[p->NS2Indx[nonMasked - 1]] + see = p->See[p->NS2Indx[nonMasked - 1]] +
(nonMasked < (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
(unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
4 * (numMasked > nonMasked) + p->HiBitsFlag; 4 * (numMasked > nonMasked) +
p->HiBitsFlag;
{ {
unsigned r = (see->Summ >> see->Shift); unsigned r = (see->Summ >> see->Shift);
see->Summ = (UInt16)(see->Summ - r); see->Summ = (UInt16)(see->Summ - r);
*escFreq = r + (r == 0); *escFreq = r + (r == 0);
} }
} else { }
else
{
see = &p->DummySee; see = &p->DummySee;
*escFreq = 1; *escFreq = 1;
} }
@ -630,7 +670,8 @@ void Ppmd7_Update1(CPpmd7 *p)
CPpmd_State *s = p->FoundState; CPpmd_State *s = p->FoundState;
s->Freq += 4; s->Freq += 4;
p->MinContext->SummFreq += 4; p->MinContext->SummFreq += 4;
if (s[0].Freq > s[-1].Freq) { if (s[0].Freq > s[-1].Freq)
{
SwapStates(&s[0], &s[-1]); SwapStates(&s[0], &s[-1]);
p->FoundState = --s; p->FoundState = --s;
if (s->Freq > MAX_FREQ) if (s->Freq > MAX_FREQ)
@ -651,7 +692,7 @@ void Ppmd7_Update1_0(CPpmd7 *p)
void Ppmd7_UpdateBin(CPpmd7 *p) void Ppmd7_UpdateBin(CPpmd7 *p)
{ {
p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1 : 0)); p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
p->PrevSuccess = 1; p->PrevSuccess = 1;
p->RunLength++; p->RunLength++;
NextContext(p); NextContext(p);

View File

@ -22,14 +22,15 @@ 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;
@ -38,7 +39,8 @@ typedef struct 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;
@ -63,18 +65,19 @@ 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);
@ -83,8 +86,7 @@ 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->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
[p->PrevSuccess + \
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
@ -92,15 +94,18 @@ void Ppmd7_UpdateBin(CPpmd7 *p);
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;
@ -113,9 +118,11 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
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;

View File

@ -26,10 +26,12 @@ static UInt32 Range_GetThreshold(void *pp, UInt32 total)
static void Range_Normalize(CPpmd7z_RangeDec *p) static void Range_Normalize(CPpmd7z_RangeDec *p)
{ {
if (p->Range < kTopValue) { if (p->Range < kTopValue)
{
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
p->Range <<= 8; p->Range <<= 8;
if (p->Range < kTopValue) { if (p->Range < kTopValue)
{
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
p->Range <<= 8; p->Range <<= 8;
} }
@ -49,10 +51,13 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
UInt32 newBound = (p->Range >> 14) * size0; UInt32 newBound = (p->Range >> 14) * size0;
UInt32 symbol; UInt32 symbol;
if (p->Code < newBound) { if (p->Code < newBound)
{
symbol = 0; symbol = 0;
p->Range = newBound; p->Range = newBound;
} else { }
else
{
symbol = 1; symbol = 1;
p->Code -= newBound; p->Code -= newBound;
p->Range -= newBound; p->Range -= newBound;
@ -68,16 +73,19 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
p->p.DecodeBit = Range_DecodeBit; p->p.DecodeBit = Range_DecodeBit;
} }
#define MASK(sym) ((signed char *)charMask)[sym] #define MASK(sym) ((signed char *)charMask)[sym]
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
{ {
size_t charMask[256 / sizeof(size_t)]; size_t charMask[256 / sizeof(size_t)];
if (p->MinContext->NumStats != 1) { if (p->MinContext->NumStats != 1)
{
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
unsigned i; unsigned i;
UInt32 count, hiCnt; UInt32 count, hiCnt;
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) { if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
{
Byte symbol; Byte symbol;
rc->Decode(rc, 0, s->Freq); rc->Decode(rc, 0, s->Freq);
p->FoundState = s; p->FoundState = s;
@ -87,8 +95,10 @@ int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
} }
p->PrevSuccess = 0; p->PrevSuccess = 0;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do { do
if ((hiCnt += (++s)->Freq) > count) { {
if ((hiCnt += (++s)->Freq) > count)
{
Byte symbol; Byte symbol;
rc->Decode(rc, hiCnt - s->Freq, s->Freq); rc->Decode(rc, hiCnt - s->Freq, s->Freq);
p->FoundState = s; p->FoundState = s;
@ -96,7 +106,8 @@ int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
Ppmd7_Update1(p); Ppmd7_Update1(p);
return symbol; return symbol;
} }
} while (--i); }
while (--i);
if (count >= p->MinContext->SummFreq) if (count >= p->MinContext->SummFreq)
return -2; return -2;
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
@ -104,12 +115,13 @@ int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
PPMD_SetAllBitsIn256Bytes(charMask); PPMD_SetAllBitsIn256Bytes(charMask);
MASK(s->Symbol) = 0; MASK(s->Symbol) = 0;
i = p->MinContext->NumStats - 1; i = p->MinContext->NumStats - 1;
do { do { MASK((--s)->Symbol) = 0; } while (--i);
MASK((--s)->Symbol) = 0; }
} while (--i); else
} else { {
UInt16 *prob = Ppmd7_GetBinSumm(p); UInt16 *prob = Ppmd7_GetBinSumm(p);
if (rc->DecodeBit(rc, *prob) == 0) { if (rc->DecodeBit(rc, *prob) == 0)
{
Byte symbol; Byte symbol;
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
@ -122,37 +134,42 @@ int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
p->PrevSuccess = 0; p->PrevSuccess = 0;
} }
for (;;) { for (;;)
{
CPpmd_State *ps[256], *s; CPpmd_State *ps[256], *s;
UInt32 freqSum, count, hiCnt; UInt32 freqSum, count, hiCnt;
CPpmd_See *see; CPpmd_See *see;
unsigned i, num, numMasked = p->MinContext->NumStats; unsigned i, num, numMasked = p->MinContext->NumStats;
do { do
{
p->OrderFall++; p->OrderFall++;
if (!p->MinContext->Suffix) if (!p->MinContext->Suffix)
return -1; return -1;
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
} while (p->MinContext->NumStats == numMasked); }
while (p->MinContext->NumStats == numMasked);
hiCnt = 0; hiCnt = 0;
s = Ppmd7_GetStats(p, p->MinContext); s = Ppmd7_GetStats(p, p->MinContext);
i = 0; i = 0;
num = p->MinContext->NumStats - numMasked; num = p->MinContext->NumStats - numMasked;
do { do
{
int k = (int)(MASK(s->Symbol)); int k = (int)(MASK(s->Symbol));
hiCnt += (s->Freq & k); hiCnt += (s->Freq & k);
ps[i] = s++; ps[i] = s++;
i -= k; i -= k;
} while (i != num); }
while (i != num);
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
freqSum += hiCnt; freqSum += hiCnt;
count = rc->GetThreshold(rc, freqSum); count = rc->GetThreshold(rc, freqSum);
if (count < hiCnt) { if (count < hiCnt)
{
Byte symbol; Byte symbol;
CPpmd_State **pps = ps; CPpmd_State **pps = ps;
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++) for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
;
s = *pps; s = *pps;
rc->Decode(rc, hiCnt - s->Freq, s->Freq); rc->Decode(rc, hiCnt - s->Freq, s->Freq);
Ppmd_See_Update(see); Ppmd_See_Update(see);
@ -165,8 +182,6 @@ int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
return -2; return -2;
rc->Decode(rc, hiCnt, freqSum - hiCnt); rc->Decode(rc, hiCnt, freqSum - hiCnt);
see->Summ = (UInt16)(see->Summ + freqSum); see->Summ = (UInt16)(see->Summ + freqSum);
do { do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
MASK(ps[--i]->Symbol) = 0;
} while (i != 0);
} }
} }

View File

@ -49,12 +49,7 @@ typedef int WRes;
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) \ #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
{ \
int __result__ = (x); \
if (__result__ != 0) \
return __result__; \
}
#endif #endif
typedef unsigned char Byte; typedef unsigned char Byte;
@ -86,7 +81,7 @@ typedef unsigned __int64 UInt64;
#else #else
typedef long long int Int64; typedef long long int Int64;
typedef unsigned long long int UInt64; typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n##ULL #define UINT64_CONST(n) n ## ULL
#endif #endif
#endif #endif
@ -101,6 +96,7 @@ typedef int Bool;
#define True 1 #define True 1
#define False 0 #define False 0
#ifdef _WIN32 #ifdef _WIN32
#define MY_STD_CALL __stdcall #define MY_STD_CALL __stdcall
#else #else
@ -125,17 +121,21 @@ 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 */
@ -146,20 +146,28 @@ 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 { SZ_SEEK_SET = 0, SZ_SEEK_CUR = 1, SZ_SEEK_END = 2 } ESzSeek; typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct { typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ SRes (*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
@ -181,7 +189,8 @@ 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;
@ -192,27 +201,31 @@ typedef struct {
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;

View File

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

View File

@ -21,7 +21,7 @@
#include "RingBuffer.h" #include "RingBuffer.h"
#include "SoundDriver.h" #include "SoundDriver.h"
#include <SDL.h> #include "SDL.h"
class SoundSDL : public SoundDriver class SoundSDL : public SoundDriver
{ {

View File

@ -21,4 +21,13 @@ int ZEXPORT memgzclose(gzFile file);
long ZEXPORT memtell(gzFile file); long ZEXPORT memtell(gzFile file);
z_off_t ZEXPORT memgzseek(gzFile file, z_off_t off, int whence); z_off_t ZEXPORT memgzseek(gzFile file, z_off_t off, int whence);
// Newer version of zlib dropped gzio support
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
#endif // MEMGZIO_H #endif // MEMGZIO_H

View File

@ -28,7 +28,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <SDL.h> #include "SDL.h"
#include "../Util.h" #include "../Util.h"
#include "../common/ConfigManager.h" #include "../common/ConfigManager.h"

View File

@ -30,7 +30,7 @@
#include <gtkmm/messagedialog.h> #include <gtkmm/messagedialog.h>
#include <gtkmm/stock.h> #include <gtkmm/stock.h>
#include <SDL.h> #include "SDL.h"
#include "../Util.h" #include "../Util.h"
#include "../common/ConfigManager.h" #include "../common/ConfigManager.h"

View File

@ -33,6 +33,7 @@
#include <OpenGL/glext.h> #include <OpenGL/glext.h>
#include <OpenGL/glu.h> #include <OpenGL/glu.h>
#else #else
#include <GL/gl.h>
#include <GL/glext.h> #include <GL/glext.h>
#include <GL/glu.h> #include <GL/glu.h>
#endif #endif
@ -42,7 +43,7 @@
#include "../AutoBuild.h" #include "../AutoBuild.h"
#include "../version.h" #include "../version.h"
#include <SDL.h> #include "SDL.h"
#include "../Util.h" #include "../Util.h"
#include "../common/ConfigManager.h" #include "../common/ConfigManager.h"

View File

@ -18,7 +18,7 @@
#ifndef VBAM_SDL_INPUT_H #ifndef VBAM_SDL_INPUT_H
#define VBAM_SDL_INPUT_H #define VBAM_SDL_INPUT_H
#include <SDL.h> #include "SDL.h"
enum EKey { enum EKey {
KEY_LEFT, KEY_LEFT,

View File

@ -2416,6 +2416,9 @@ EVT_HANDLER(wxID_ABOUT, "About...")
ai.SetName(wxT("VisualBoyAdvance-M")); ai.SetName(wxT("VisualBoyAdvance-M"));
wxString version = wxT(""); wxString version = wxT("");
#ifndef FINAL_BUILD #ifndef FINAL_BUILD
#ifndef VERSION
# define VERSION "git"
#endif
if (!version.IsEmpty()) if (!version.IsEmpty())
version = version + wxT("-"); version = version + wxT("-");

View File

@ -1,7 +1,7 @@
#include "../common/ConfigManager.h" #include "../common/ConfigManager.h"
#include "../common/SoundSDL.h" #include "../common/SoundSDL.h"
#include "wxvbam.h" #include "wxvbam.h"
#include <SDL.h> #include "SDL.h"
#include <wx/ffile.h> #include <wx/ffile.h>
#include <wx/generic/prntdlgg.h> #include <wx/generic/prntdlgg.h>
#include <wx/print.h> #include <wx/print.h>

View File

@ -1,7 +1,9 @@
#ifndef WX_VIEWSUPT_H #ifndef WX_VIEWSUPT_H
#define WX_VIEWSUPT_H #define WX_VIEWSUPT_H
#include <wx/wx.h>
#include <wx/window.h> #include <wx/window.h>
#include <wx/image.h>
#include <wx/caret.h> #include <wx/caret.h>
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/dialog.h> #include <wx/dialog.h>

View File

@ -1,5 +1,5 @@
#include "wx/sdljoy.h" #include "wx/sdljoy.h"
#include <SDL.h> #include "SDL.h"
#include <SDL_joystick.h> #include <SDL_joystick.h>
#include <wx/window.h> #include <wx/window.h>