📄 lzmadecode.c.svn-base
字号:
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
#ifdef _LZMA_OUT_READ
if (rep0 > distanceLimit)
#else
if (rep0 > nowPos)
#endif
return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do
{
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
RC_NORMALIZE;
#ifdef _LZMA_OUT_READ
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
#endif
#ifdef _LZMA_IN_CB
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
#else
*inSizeProcessed = (SizeT)(Buffer - inStream);
#endif
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}
#ifdef COMPILE_BOOT
/* Huffman code lookup table entry--this entry is four bytes for machines
that have 16-bit pointers (e.g. PC's in the small or medium model).
Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16
means that v is a literal, 16 < e < 32 means that v is a pointer to
the next table, which codes e - 16 bits, and lastly e == 99 indicates
an unused code. If a code with e == 99 is looked up, this implies an
error in the data. */
struct huft {
uch e; /* number of extra bits or operation */
uch b; /* number of bits in this code or subcode */
union {
ush n; /* literal, length base, or distance base */
struct huft *t; /* pointer to next level of table */
} v;
};
static struct huft huft_temp[0x10000];
static int huft_flag = 0;
static char huft_free_idx = 0;
static char huft_free_end = -1;
struct huft *malloc(int size)
{
struct huft *huft_p;
if(huft_flag+size>(0x10000-1)) return 0;
huft_p = &huft_temp[huft_flag];
huft_flag+=size;
huft_free_end++;
memset(huft_p, 0, sizeof(struct huft)*size);
return huft_p;
}
void free(struct huft *memblk)
{
if(huft_free_idx>huft_free_end) return;
huft_free_idx++;
if(huft_free_idx>huft_free_end) {
huft_flag=0;
huft_free_idx = 0;
huft_free_end = -1;
}
}
#endif
int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
{
CBuffer *bo = (CBuffer *)object;
*buffer = bo->Buffer;
bo->Buffer+=kInBufferSize;
*size = kInBufferSize;
return LZMA_RESULT_OK;
}
int ZEXPORT uncompressLZMA (ptrDest, destLen, ptrSrc, sourceLen)
Bytef *ptrDest;
uLongf *destLen;
Bytef *ptrSrc;
uLong sourceLen;
{
/* We use two 32-bit integers to construct 64-bit integer for file size.
You can remove outSizeHigh, if you don't need >= 4GB supporting,
or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
UInt32 outSize = 0;
UInt32 outSizeHigh = 0;
#ifndef _LZMA_OUT_READ
SizeT outSizeFull;
#endif
int waitEOS = 1;
/* waitEOS = 1, if there is no uncompressed size in headers,
so decoder will wait EOS (End of Stream Marker) in compressed stream */
#ifndef _LZMA_IN_CB
SizeT compressedSize;
//unsigned char *inStream;
#endif
CBuffer g_InBuffer;
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
unsigned char properties[LZMA_PROPERTIES_SIZE];
int res;
#ifdef _LZMA_IN_CB
g_InBuffer.Buffer = ptrSrc;
#endif
#ifndef _LZMA_IN_CB
{
long length;
fseek(inFile, 0, SEEK_END);
length = ftell(inFile);
fseek(inFile, 0, SEEK_SET);
if ((long)(SizeT)length != length)
return PrintError(rs, "Too big compressed stream");
compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
}
#endif
/* Read LZMA properties for compressed stream */
memcpy(properties, ptrSrc, sizeof(properties));
g_InBuffer.Buffer+=sizeof(properties);
/* Read uncompressed size */
{
int i;
for (i = 0; i < 8; i++)
{
unsigned char b;
b=*g_InBuffer.Buffer;
if (b != 0xFF)
waitEOS = 0;
if (i < 4)
outSize += (UInt32)(b) << (i * 8);
else
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
g_InBuffer.Buffer++;
}
*destLen = outSize;
#ifndef _LZMA_OUT_READ
if (waitEOS)
return Z_DATA_ERROR;
outSizeFull = (SizeT)outSize;
if (sizeof(SizeT) >= 8)
outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
return Z_DATA_ERROR;
#endif
}
/* Decode LZMA properties and allocate memory */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return Z_DATA_ERROR;
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
#ifdef _LZMA_OUT_READ
if (state.Properties.DictionarySize == 0)
state.Dictionary = 0;
else
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
#else
//if (outSizeFull == 0)
// outStream = 0;
//else
// outStream = (unsigned char *)malloc(outSizeFull);
#endif
#ifndef _LZMA_IN_CB
if (compressedSize == 0)
inStream = 0;
else
inStream = (unsigned char *)malloc(compressedSize);
#endif
if (state.Probs == 0
#ifdef _LZMA_OUT_READ
|| (state.Dictionary == 0 && state.Properties.DictionarySize != 0)
#else
//|| (outStream == 0 && outSizeFull != 0)
#endif
#ifndef _LZMA_IN_CB
|| (inStream == 0 && compressedSize != 0)
#endif
)
{
free(state.Probs);
#ifdef _LZMA_OUT_READ
free(state.Dictionary);
#else
//free(outStream);
#endif
#ifndef _LZMA_IN_CB
free(inStream);
#endif
return Z_MEM_ERROR;
}
/* Decompress */
#ifdef _LZMA_IN_CB
g_InBuffer.InCallback.Read = LzmaReadCompressed;
#else
if (!MyReadFileAndCheck(inFile, inStream, compressedSize))
return PrintError(rs, kCantReadMessage);
#endif
#ifdef _LZMA_OUT_READ
{
#ifndef _LZMA_IN_CB
SizeT inAvail = compressedSize;
const unsigned char *inBuffer = inStream;
#endif
LzmaDecoderInit(&state);
do
{
#ifndef _LZMA_IN_CB
SizeT inProcessed;
#endif
SizeT outProcessed;
SizeT outAvail = kOutBufferSize;
if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
outAvail = (SizeT)outSize;
res = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&g_InBuffer.InCallback,
#else
inBuffer, inAvail, &inProcessed,
#endif
g_OutBuffer, outAvail, &outProcessed);
if (res != 0)
{
sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
break;
}
#ifndef _LZMA_IN_CB
inAvail -= inProcessed;
inBuffer += inProcessed;
#endif
if (outFile != 0)
if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed))
{
PrintError(rs, kCantWriteMessage);
res = 1;
break;
}
if (outSize < outProcessed)
outSizeHigh--;
outSize -= (UInt32)outProcessed;
outSize &= 0xFFFFFFFF;
if (outProcessed == 0)
{
if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
res = 1;
break;
}
}
while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
}
#else
{
#ifndef _LZMA_IN_CB
SizeT inProcessed;
#endif
SizeT outProcessed;
res = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&g_InBuffer.InCallback,
#else
inStream, compressedSize, &inProcessed,
#endif
ptrDest, outSizeFull, &outProcessed);
if (res != 0)
{
res = Z_DATA_ERROR;
}
}
#endif
free(state.Probs);
#ifdef _LZMA_OUT_READ
free(state.Dictionary);
#else
//free(outStream);
#endif
#ifndef _LZMA_IN_CB
free(inStream);
#endif
return res;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -