2
#include "DeflateDecoder.h"
7
static const UINT32 kWindowReservSize = (1 << 17) + 256;
10
m_MainDecoder(kStaticMainTableSize),
11
m_DistDecoder(kStaticDistTableSize),
12
m_LevelDecoder(kLevelTableSize)
15
void CCoder::DeCodeLevelTable(BYTE *aNewLevels, int aNumLevels)
18
while (i < aNumLevels)
20
UINT32 aNumber = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
21
if (aNumber < kTableDirectLevels)
22
aNewLevels[i++] = BYTE(aNumber);
25
if (aNumber == kTableLevelRepNumber)
27
int t = m_InBitStream.ReadBits(2) + 3;
28
for (int aReps = t; aReps > 0 && i < aNumLevels ; aReps--, i++)
29
aNewLevels[i] = aNewLevels[i - 1];
34
if (aNumber == kTableLevel0Number)
35
aNum = m_InBitStream.ReadBits(3) + 3;
37
aNum = m_InBitStream.ReadBits(7) + 11;
38
for (;aNum > 0 && i < aNumLevels; aNum--)
45
void CCoder::ReadTables(void)
47
if(m_FinalBlock) // test it
50
m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock);
52
int aBlockType = m_InBitStream.ReadBits(kBlockTypeFieldSize);
56
case NBlockType::kStored:
59
UINT32 aCurrentBitPosition = m_InBitStream.GetBitPosition();
60
UINT32 aNumBitsForAlign = aCurrentBitPosition > 0 ? (8 - aCurrentBitPosition): 0;
61
if (aNumBitsForAlign > 0)
62
m_InBitStream.ReadBits(aNumBitsForAlign);
63
m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
64
WORD anOnesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
65
if (m_StoredBlockSize != anOnesComplementReverse)
69
case NBlockType::kFixedHuffman:
70
case NBlockType::kDynamicHuffman:
73
BYTE aLitLenLevels[kStaticMainTableSize];
74
BYTE aDistLevels[kStaticDistTableSize];
75
if (aBlockType == NBlockType::kFixedHuffman)
79
// Leteral / length levels
80
for (i = 0; i < 144; i++)
86
for (; i < 288; i++) /* make a complete, but wrong code set */
90
for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize
93
else // in case when (aBlockType == kDeflateBlockTypeFixedHuffman)
95
int aNumLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) +
96
kDeflateNumberOfLitLenCodesMin;
97
int aNumDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) +
98
kDeflateNumberOfDistanceCodesMin;
99
int aNumLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) +
100
kDeflateNumberOfLevelCodesMin;
103
aNumLevels = kHeapTablesSizesSum;
105
BYTE aLevelLevels[kLevelTableSize];
107
for (i = 0; i < kLevelTableSize; i++)
109
int aPosition = kCodeLengthAlphabetOrder[i];
110
if(i < aNumLevelCodes)
111
aLevelLevels[aPosition] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
113
aLevelLevels[aPosition] = 0;
118
m_LevelDecoder.SetCodeLengths(aLevelLevels);
125
BYTE aTmpLevels[kStaticMaxTableSize];
126
DeCodeLevelTable(aTmpLevels, aNumLitLenLevels + aNumDistLevels);
128
memmove(aLitLenLevels, aTmpLevels, aNumLitLenLevels);
129
memset(aLitLenLevels + aNumLitLenLevels, 0,
130
kStaticMainTableSize - aNumLitLenLevels);
132
memmove(aDistLevels, aTmpLevels + aNumLitLenLevels, aNumDistLevels);
133
memset(aDistLevels + aNumDistLevels, 0, kStaticDistTableSize - aNumDistLevels);
137
m_MainDecoder.SetCodeLengths(aLitLenLevels);
138
m_DistDecoder.SetCodeLengths(aDistLevels);
151
HRESULT CCoder::CodeReal(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize)
153
if (m_OutWindowStream.GetBuffer() == 0)
157
m_OutWindowStream.Create(kHistorySize, kMatchMaxLen, kWindowReservSize);
161
return E_OUTOFMEMORY;
165
m_OutWindowStream.Init(anOutStream, false);
166
m_InBitStream.Init(anInStream);
168
m_FinalBlock = false;
175
for (UINT32 i = 0; i < m_StoredBlockSize; i++)
176
m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
177
aPos += m_StoredBlockSize;
182
UINT32 aNumber = m_MainDecoder.DecodeSymbol(&m_InBitStream);
185
if (anOutSize != NULL)
186
if (aPos >= *anOutSize)
188
m_OutWindowStream.PutOneByte(BYTE(aNumber));
192
else if (aNumber >= kMatchNumber)
194
if (anOutSize != NULL)
195
if (aPos >= *anOutSize)
197
aNumber -= kMatchNumber;
198
UINT32 aLength = UINT32(kLenStart[aNumber]) + kMatchMinLen;
200
if ((aNumBits = kLenDirectBits[aNumber]) > 0)
201
aLength += m_InBitStream.ReadBits(aNumBits);
203
aNumber = m_DistDecoder.DecodeSymbol(&m_InBitStream);
204
UINT32 aDistance = kDistStart[aNumber] + m_InBitStream.ReadBits(kDistDirectBits[aNumber]);
205
if (aDistance >= aPos)
207
m_OutWindowStream.CopyBackBlock(aDistance, aLength);
210
else if (aNumber == kReadTableNumber)
216
return m_OutWindowStream.Flush();
219
HRESULT CCoder::Code(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize)
222
return CodeReal(anInStream, anOutStream, anInSize, anOutSize);
223
} catch (HRESULT& e) {