This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View File

@@ -188,6 +188,14 @@ SOURCE=..\..\Common\OutBuffer.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\CRC.cpp
# End Source File
# Begin Source File
@@ -210,6 +218,26 @@ SOURCE=..\..\..\Common\NewHandler.h
# Begin Group "LZ"
# PROP Default_Filter ""
# Begin Group "BinTree"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\LZ\BinTree\BinTree.h
# End Source File
# Begin Source File
SOURCE=..\LZ\BinTree\BinTree3Z.h
# End Source File
# Begin Source File
SOURCE=..\LZ\BinTree\BinTreeMain.h
# End Source File
# End Group
# Begin Source File
SOURCE=..\LZ\IMatchFinder.h
# End Source File
# Begin Source File
SOURCE=..\LZ\LZInWindow.cpp

View File

@@ -1,7 +1,5 @@
// DeflateConst.h
#pragma once
#ifndef __DEFLATE_CONST_H
#define __DEFLATE_CONST_H
@@ -10,59 +8,59 @@
namespace NCompress {
namespace NDeflate {
const UINT32 kLenTableSize = 29;
const UInt32 kLenTableSize = 29;
const UINT32 kStaticDistTableSize = 32;
const UINT32 kStaticLenTableSize = 31;
const UInt32 kStaticDistTableSize = 32;
const UInt32 kStaticLenTableSize = 31;
const UINT32 kReadTableNumber = 0x100;
const UINT32 kMatchNumber = kReadTableNumber + 1;
const UInt32 kReadTableNumber = 0x100;
const UInt32 kMatchNumber = kReadTableNumber + 1;
const UINT32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
const UINT32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298;
const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298;
const UINT32 kDistTableStart = kMainTableSize;
const UInt32 kDistTableStart = kMainTableSize;
const UINT32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32;
const UINT32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64;
const UInt32 kHeapTablesSizesSum32 = kMainTableSize + kDistTableSize32;
const UInt32 kHeapTablesSizesSum64 = kMainTableSize + kDistTableSize64;
const UINT32 kLevelTableSize = 19;
const UInt32 kLevelTableSize = 19;
const UINT32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it
const UINT32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it
const UInt32 kMaxTableSize32 = kHeapTablesSizesSum32; // test it
const UInt32 kMaxTableSize64 = kHeapTablesSizesSum64; // test it
const UINT32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize;
const UINT32 kTableDirectLevels = 16;
const UINT32 kTableLevelRepNumber = kTableDirectLevels;
const UINT32 kTableLevel0Number = kTableLevelRepNumber + 1;
const UINT32 kTableLevel0Number2 = kTableLevel0Number + 1;
const UInt32 kTableDirectLevels = 16;
const UInt32 kTableLevelRepNumber = kTableDirectLevels;
const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1;
const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1;
const UINT32 kLevelMask = 0xF;
const UInt32 kLevelMask = 0xF;
const BYTE kLenStart32[kLenTableSize] =
const Byte kLenStart32[kLenTableSize] =
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
const BYTE kLenStart64[kLenTableSize] =
const Byte kLenStart64[kLenTableSize] =
{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 0};
const BYTE kLenDirectBits32[kLenTableSize] =
const Byte kLenDirectBits32[kLenTableSize] =
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
const BYTE kLenDirectBits64[kLenTableSize] =
const Byte kLenDirectBits64[kLenTableSize] =
{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16};
const UINT32 kDistStart[kDistTableSize64] =
const UInt32 kDistStart[kDistTableSize64] =
{0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,
1024,1536,2048,3072,4096,6144,8192,12288,16384,24576, 32768, 49152};
const BYTE kDistDirectBits[kDistTableSize64] =
const Byte kDistDirectBits[kDistTableSize64] =
{0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14};
const BYTE kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
const BYTE kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
const UINT32 kMatchMinLen = 3;
const UINT32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it
const UINT32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it
const UInt32 kMatchMinLen = 3;
const UInt32 kMatchMaxLen32 = kNumLenCombinations32 + kMatchMinLen - 1; //256 + 2; test it
const UInt32 kMatchMaxLen64 = kNumLenCombinations64 + kMatchMinLen - 1; //255 + 2; test it
const int kFinalBlockFieldSize = 1;
@@ -88,18 +86,18 @@ namespace NBlockType
};
}
const UINT32 kDeflateNumberOfLengthCodesFieldSize = 5;
const UINT32 kDeflateNumberOfDistanceCodesFieldSize = 5;
const UINT32 kDeflateNumberOfLevelCodesFieldSize = 4;
const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5;
const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5;
const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4;
const UINT32 kDeflateNumberOfLitLenCodesMin = 257;
const UInt32 kDeflateNumberOfLitLenCodesMin = 257;
const UINT32 kDeflateNumberOfDistanceCodesMin = 1;
const UINT32 kDeflateNumberOfLevelCodesMin = 4;
const UInt32 kDeflateNumberOfDistanceCodesMin = 1;
const UInt32 kDeflateNumberOfLevelCodesMin = 4;
const UINT32 kDeflateLevelCodeFieldSize = 3;
const UInt32 kDeflateLevelCodeFieldSize = 3;
const UINT32 kDeflateStoredBlockLengthFieldSizeSize = 16;
const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16;
}}

View File

@@ -3,29 +3,21 @@
#include "StdAfx.h"
#include "DeflateDecoder.h"
#include "DeflateConst.h"
#include "Windows/Defs.h"
namespace NCompress {
namespace NDeflate {
namespace NDecoder {
CCoder::CCoder(bool deflate64Mode):
m_MainDecoder(kStaticMainTableSize),
m_DistDecoder(kStaticDistTableSize),
m_LevelDecoder(kLevelTableSize),
_deflate64Mode(deflate64Mode)
{}
CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode) {}
void CCoder::DeCodeLevelTable(BYTE *newLevels, int numLevels)
void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels)
{
int i = 0;
while (i < numLevels)
{
UINT32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream);
if (number < kTableDirectLevels)
newLevels[i++] = BYTE(number);
newLevels[i++] = Byte(number);
else
{
if (number == kTableLevelRepNumber)
@@ -62,12 +54,12 @@ void CCoder::ReadTables(void)
case NBlockType::kStored:
{
m_StoredMode = true;
UINT32 currentBitPosition = m_InBitStream.GetBitPosition();
UINT32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0;
if (numBitsForAlign > 0)
m_InBitStream.ReadBits(numBitsForAlign);
m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize);
WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize));
if (m_StoredBlockSize != onesComplementReverse)
throw CException(CException::kData);
break;
@@ -76,8 +68,8 @@ void CCoder::ReadTables(void)
case NBlockType::kDynamicHuffman:
{
m_StoredMode = false;
BYTE litLenLevels[kStaticMainTableSize];
BYTE distLevels[kStaticDistTableSize];
Byte litLenLevels[kStaticMainTableSize];
Byte distLevels[kStaticDistTableSize];
if (blockType == NBlockType::kFixedHuffman)
{
int i;
@@ -108,13 +100,13 @@ void CCoder::ReadTables(void)
int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 :
kHeapTablesSizesSum32;
BYTE levelLevels[kLevelTableSize];
Byte levelLevels[kLevelTableSize];
int i;
for (i = 0; i < kLevelTableSize; i++)
{
int position = kCodeLengthAlphabetOrder[i];
if(i < numLevelCodes)
levelLevels[position] = BYTE(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize));
else
levelLevels[position] = 0;
}
@@ -128,7 +120,7 @@ void CCoder::ReadTables(void)
throw CException(CException::kData);
}
BYTE tmpLevels[kStaticMaxTableSize];
Byte tmpLevels[kStaticMaxTableSize];
DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels);
memmove(litLenLevels, tmpLevels, numLitLenLevels);
@@ -155,23 +147,19 @@ void CCoder::ReadTables(void)
}
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
{
try
{
m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32 /* , kMatchMaxLen */);
}
catch(...)
{
return E_OUTOFMEMORY;
}
}
UINT64 pos = 0;
m_OutWindowStream.Init(outStream, false);
m_InBitStream.Init(inStream);
// CCoderReleaser coderReleaser(this);
if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
return E_OUTOFMEMORY;
if (!m_InBitStream.Create(1 << 17))
return E_OUTOFMEMORY;
UInt64 pos = 0;
m_OutWindowStream.SetStream(outStream);
m_OutWindowStream.Init(false);
m_InBitStream.SetStream(inStream);
m_InBitStream.Init();
CCoderReleaser coderReleaser(this);
m_FinalBlock = false;
@@ -179,14 +167,14 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
{
if (progress != NULL)
{
UINT64 packSize = m_InBitStream.GetProcessedSize();
UInt64 packSize = m_InBitStream.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &pos));
}
ReadTables();
if(m_StoredMode)
{
for (UINT32 i = 0; i < m_StoredBlockSize; i++)
m_OutWindowStream.PutOneByte(BYTE(m_InBitStream.ReadBits(8)));
for (UInt32 i = 0; i < m_StoredBlockSize; i++)
m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8)));
pos += m_StoredBlockSize;
continue;
}
@@ -195,13 +183,13 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
if (m_InBitStream.NumExtraBytes > 4)
throw CException(CException::kData);
UINT32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream);
if (number < 256)
{
if (outSize != NULL)
if (pos >= *outSize)
throw CException(CException::kData);
m_OutWindowStream.PutOneByte(BYTE(number));
m_OutWindowStream.PutByte(Byte(number));
pos++;
continue;
}
@@ -212,28 +200,28 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
throw CException(CException::kData);
number -= kMatchNumber;
UINT32 length;
UInt32 length;
if (_deflate64Mode)
{
length = UINT32(kLenStart64[number]) + kMatchMinLen;
UINT32 numBits = kLenDirectBits64[number];
length = UInt32(kLenStart64[number]) + kMatchMinLen;
UInt32 numBits = kLenDirectBits64[number];
if (numBits > 0)
length += m_InBitStream.ReadBits(numBits);
}
else
{
length = UINT32(kLenStart32[number]) + kMatchMinLen;
UINT32 numBits = kLenDirectBits32[number];
length = UInt32(kLenStart32[number]) + kMatchMinLen;
UInt32 numBits = kLenDirectBits32[number];
if (numBits > 0)
length += m_InBitStream.ReadBits(numBits);
}
number = m_DistDecoder.DecodeSymbol(&m_InBitStream);
UINT32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]);
if (distance >= pos)
throw "data error";
m_OutWindowStream.CopyBackBlock(distance, length);
m_OutWindowStream.CopyBlock(distance, length);
pos += length;
}
else if (number == kReadTableNumber)
@@ -242,11 +230,12 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
throw CException(CException::kData);
}
}
coderReleaser.NeedFlush = false;
return m_OutWindowStream.Flush();
}
HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
@@ -255,7 +244,7 @@ HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
catch(...) { return S_FALSE; }
}
HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value)
HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value)
{
if (value == NULL)
return E_INVALIDARG;
@@ -263,25 +252,25 @@ HRESULT CCoder::BaseGetInStreamProcessedSize(UINT64 *value)
return S_OK;
}
STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UINT64 *value)
STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UInt64 *value)
{
return BaseGetInStreamProcessedSize(value);
}
HRESULT CCOMCoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
return BaseCode(inStream, outStream, inSize, outSize, progress);
}
STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UINT64 *value)
STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UInt64 *value)
{
return BaseGetInStreamProcessedSize(value);
}
HRESULT CCOMCoder64::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
return BaseCode(inStream, outStream, inSize, outSize, progress);

View File

@@ -1,11 +1,9 @@
// DeflateDecoder.h
#pragma once
#ifndef __DEFLATE_DECODER_H
#define __DEFLATE_DECODER_H
#include "Common/MyCom.h"
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
#include "../../Common/LSBFDecoder.h"
@@ -14,6 +12,7 @@
#include "../Huffman/HuffmanDecoder.h"
#include "DeflateExtConst.h"
#include "DeflateConst.h"
namespace NCompress {
namespace NDeflate {
@@ -30,26 +29,24 @@ public:
};
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
typedef NCompress::NHuffman::CDecoder<kNumHuffmanBits> CHuffmanDecoder;
class CCoder
{
CLZOutWindow m_OutWindowStream;
CInBit m_InBitStream;
CHuffmanDecoder m_MainDecoder;
CHuffmanDecoder m_DistDecoder;
CHuffmanDecoder m_LevelDecoder; // table for decoding other tables;
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder;
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder;
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
bool m_FinalBlock;
bool m_StoredMode;
UINT32 m_StoredBlockSize;
UInt32 m_StoredBlockSize;
bool _deflate64Mode;
void DeCodeLevelTable(BYTE *newLevels, int numLevels);
void DeCodeLevelTable(Byte *newLevels, int numLevels);
void ReadTables();
/*
void CCoder::ReleaseStreams()
{
m_OutWindowStream.ReleaseStream();
@@ -59,29 +56,30 @@ class CCoder
{
CCoder *m_Coder;
public:
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
bool NeedFlush;
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
~CCoderReleaser()
{
m_Coder->m_OutWindowStream.Flush();
if (NeedFlush)
m_Coder->m_OutWindowStream.Flush();
m_Coder->ReleaseStreams();
}
};
friend class CCoderReleaser;
*/
public:
CCoder(bool deflate64Mode = false);
HRESULT CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
HRESULT BaseCode(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// IGetInStreamProcessedSize
HRESULT BaseGetInStreamProcessedSize(UINT64 *aValue);
HRESULT BaseGetInStreamProcessedSize(UInt64 *aValue);
};
class CCOMCoder :
@@ -95,11 +93,11 @@ public:
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// IGetInStreamProcessedSize
STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue);
CCOMCoder(): CCoder(false) {}
};
@@ -114,11 +112,11 @@ public:
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// IGetInStreamProcessedSize
STDMETHOD(GetInStreamProcessedSize)(UINT64 *aValue);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue);
CCOMCoder64(): CCoder(true) {}
};

View File

@@ -7,7 +7,8 @@
#include "Windows/Defs.h"
#include "Common/ComTry.h"
#include "../LZ/BinTree/BinTree3ZMain.h"
#include "../../../Common/Alloc.h"
#include "../LZ/BinTree/BinTree3Z.h"
namespace NCompress {
namespace NDeflate {
@@ -25,22 +26,22 @@ static const int kValueBlockSize = 0x2000;
static const int kMaxCodeBitLength = 15;
static const int kMaxLevelBitLength = 7;
static const BYTE kFlagImm = 0;
static const BYTE kFlagLenPos = 4;
static const Byte kFlagImm = 0;
static const Byte kFlagLenPos = 4;
static const UINT32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!!
static const UInt32 kMaxUncompressedBlockSize = 0xFFFF; // test it !!!
static const UINT32 kBlockUncompressedSizeThreshold =
static const UInt32 kBlockUncompressedSizeThreshold =
kMaxUncompressedBlockSize - kMatchMaxLen32 - kNumOpts;
static const int kNumGoodBacks = 0x10000;
static BYTE kNoLiteralDummy = 13;
static BYTE kNoLenDummy = 13;
static BYTE kNoPosDummy = 6;
static Byte kNoLiteralDummy = 13;
static Byte kNoLenDummy = 13;
static Byte kNoPosDummy = 6;
static BYTE g_LenSlots[kNumLenCombinations32];
static BYTE g_FastPos[1 << 9];
static Byte g_LenSlots[kNumLenCombinations32];
static Byte g_FastPos[1 << 9];
class CFastPosInit
{
@@ -53,15 +54,15 @@ public:
int c = kLenStart32[i];
int j = 1 << kLenDirectBits32[i];
for(int k = 0; k < j; k++, c++)
g_LenSlots[c] = i;
g_LenSlots[c] = (Byte)i;
}
const int kFastSlots = 18;
int c = 0;
for (BYTE slotFast = 0; slotFast < kFastSlots; slotFast++)
for (Byte slotFast = 0; slotFast < kFastSlots; slotFast++)
{
UINT32 k = (1 << kDistDirectBits[slotFast]);
for (UINT32 j = 0; j < k; j++, c++)
UInt32 k = (1 << kDistDirectBits[slotFast]);
for (UInt32 j = 0; j < k; j++, c++)
g_FastPos[c] = slotFast;
}
}
@@ -70,9 +71,9 @@ public:
static CFastPosInit g_FastPosInit;
inline UINT32 GetPosSlot(UINT32 pos)
inline UInt32 GetPosSlot(UInt32 pos)
{
// for (UINT32 i = 1; pos >= kDistStart[i]; i++);
// for (UInt32 i = 1; pos >= kDistStart[i]; i++);
// return i - 1;
if (pos < 0x200)
return g_FastPos[pos];
@@ -81,11 +82,6 @@ inline UINT32 GetPosSlot(UINT32 pos)
CCoder::CCoder(bool deflate64Mode):
_deflate64Mode(deflate64Mode),
m_MainCoder(kMainTableSize,
deflate64Mode ? kLenDirectBits64 : kLenDirectBits32,
kMatchNumber, kMaxCodeBitLength),
m_DistCoder(deflate64Mode ? kDistTableSize64 : kDistTableSize32, kDistDirectBits, 0, kMaxCodeBitLength),
m_LevelCoder(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength),
m_NumPasses(1),
m_NumFastBytes(32),
m_OnePosMatchesMemory(0),
@@ -99,47 +95,57 @@ CCoder::CCoder(bool deflate64Mode):
kNumLenCombinations32;
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
m_LenDirectBits = deflate64Mode ? kLenDirectBits64 : kLenDirectBits32;
m_Values = new CCodeValue[kValueBlockSize + kNumOpts];
}
HRESULT CCoder::Create()
{
COM_TRY_BEGIN
m_MatchFinder.Create(
_deflate64Mode ? kHistorySize64 : kHistorySize32,
kNumOpts + kNumGoodBacks, m_NumFastBytes,
m_MatchMaxLen - m_NumFastBytes);
if (!m_MatchFinder)
{
m_MatchFinder = new NBT3Z::CMatchFinderBinTree;
if (m_MatchFinder == 0)
return E_OUTOFMEMORY;
}
if (m_Values == 0)
{
m_Values = (CCodeValue *)MyAlloc((kValueBlockSize + kNumOpts) * sizeof(CCodeValue));
if (m_Values == 0)
return E_OUTOFMEMORY;
}
RINOK(m_MatchFinder->Create(_deflate64Mode ? kHistorySize64 : kHistorySize32,
kNumOpts + kNumGoodBacks, m_NumFastBytes, m_MatchMaxLen - m_NumFastBytes));
if (!m_OutStream.Create(1 << 20))
return E_OUTOFMEMORY;
m_MatchLengthEdge = m_NumFastBytes + 1;
Free();
if (m_NumPasses > 1)
{
m_OnePosMatchesMemory = new UINT16[kNumGoodBacks * (m_NumFastBytes + 1)];
try
{
m_OnePosMatchesArray = new COnePosMatches[kNumGoodBacks];
}
catch(...)
{
delete []m_OnePosMatchesMemory;
m_OnePosMatchesMemory = 0;
throw;
}
UINT16 *goodBacksWordsCurrent = m_OnePosMatchesMemory;
m_OnePosMatchesMemory = (UInt16 *)BigAlloc(kNumGoodBacks * (m_NumFastBytes + 1) * sizeof(UInt16));
if (m_OnePosMatchesMemory == 0)
return E_OUTOFMEMORY;
m_OnePosMatchesArray = (COnePosMatches *)MyAlloc(kNumGoodBacks * sizeof(COnePosMatches));
if (m_OnePosMatchesArray == 0)
return E_OUTOFMEMORY;
UInt16 *goodBacksWordsCurrent = m_OnePosMatchesMemory;
for(int i = 0; i < kNumGoodBacks; i++, goodBacksWordsCurrent += (m_NumFastBytes + 1))
m_OnePosMatchesArray[i].Init(goodBacksWordsCurrent);
}
else
m_MatchDistances = new UINT16[m_NumFastBytes + 1];
{
m_MatchDistances = (UInt16 *)MyAlloc((m_NumFastBytes + 1) * sizeof(UInt16));
if (m_MatchDistances == 0)
return E_OUTOFMEMORY;
}
return S_OK;
COM_TRY_END
}
// ICompressSetEncoderProperties2
HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties)
const PROPVARIANT *properties, UInt32 numProperties)
{
for(UINT32 i = 0; i < numProperties; i++)
for(UInt32 i = 0; i < numProperties; i++)
{
const PROPVARIANT &property = properties[i];
switch(propIDs[i])
@@ -171,52 +177,52 @@ void CCoder::Free()
{
if (m_NumPasses > 1)
{
delete []m_OnePosMatchesMemory;
delete []m_OnePosMatchesArray;
BigFree(m_OnePosMatchesMemory);
MyFree(m_OnePosMatchesArray);
}
else
delete []m_MatchDistances;
MyFree(m_MatchDistances);
}
}
CCoder::~CCoder()
{
Free();
delete []m_Values;
MyFree(m_Values);
}
void CCoder::ReadGoodBacks()
{
UINT32 goodIndex;
UInt32 goodIndex;
if (m_NumPasses > 1)
{
goodIndex = m_FinderPos % kNumGoodBacks;
m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
}
UINT32 distanceTmp[kMatchMaxLen32 + 1];
UINT32 len = m_MatchFinder.GetLongestMatch(distanceTmp);
for(UINT32 i = kMatchMinLen; i <= len; i++)
m_MatchDistances[i] = distanceTmp[i];
UInt32 distanceTmp[kMatchMaxLen32 + 1];
UInt32 len = m_MatchFinder->GetLongestMatch(distanceTmp);
for(UInt32 i = kMatchMinLen; i <= len; i++)
m_MatchDistances[i] = (UInt16)distanceTmp[i];
m_LongestMatchDistance = m_MatchDistances[len];
if (len == m_NumFastBytes && m_NumFastBytes != m_MatchMaxLen)
m_LongestMatchLength = len + m_MatchFinder.GetMatchLen(len,
m_LongestMatchLength = len + m_MatchFinder->GetMatchLen(len,
m_LongestMatchDistance, m_MatchMaxLen - len);
else
m_LongestMatchLength = len;
if (m_NumPasses > 1)
{
m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UINT16(m_LongestMatchDistance);
m_OnePosMatchesArray[goodIndex].LongestMatchLength = UINT16(m_LongestMatchLength);
m_OnePosMatchesArray[goodIndex].LongestMatchDistance = UInt16(m_LongestMatchDistance);
m_OnePosMatchesArray[goodIndex].LongestMatchLength = UInt16(m_LongestMatchLength);
}
HRESULT result = m_MatchFinder.MovePos();
HRESULT result = m_MatchFinder->MovePos();
if (result != S_OK)
throw CMatchFinderException(result);
m_FinderPos++;
m_AdditionalOffset++;
}
void CCoder::GetBacks(UINT32 pos)
void CCoder::GetBacks(UInt32 pos)
{
if(pos == m_FinderPos)
ReadGoodBacks();
@@ -230,7 +236,7 @@ void CCoder::GetBacks(UINT32 pos)
}
else
{
UINT32 goodIndex = pos % kNumGoodBacks;
UInt32 goodIndex = pos % kNumGoodBacks;
m_MatchDistances = m_OnePosMatchesArray[goodIndex].MatchDistances;
m_LongestMatchDistance = m_OnePosMatchesArray[goodIndex].LongestMatchDistance;
m_LongestMatchLength = m_OnePosMatchesArray[goodIndex].LongestMatchLength;
@@ -239,19 +245,19 @@ void CCoder::GetBacks(UINT32 pos)
}
void CCoder::MovePos(UINT32 num)
void CCoder::MovePos(UInt32 num)
{
if (m_NumPasses > 1)
{
for(UINT32 i = 0; i < num; i++)
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1));
for(UInt32 i = 0; i < num; i++)
GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + i + 1));
}
else
{
for (;num > 0; num--)
{
m_MatchFinder.DummyLongestMatch();
HRESULT result = m_MatchFinder.MovePos();
m_MatchFinder->DummyLongestMatch();
HRESULT result = m_MatchFinder->MovePos();
if (result != S_OK)
throw CMatchFinderException(result);
m_FinderPos++;
@@ -260,21 +266,21 @@ void CCoder::MovePos(UINT32 num)
}
}
static const UINT32 kIfinityPrice = 0xFFFFFFF;
static const UInt32 kIfinityPrice = 0xFFFFFFF;
UINT32 CCoder::Backward(UINT32 &backRes, UINT32 cur)
UInt32 CCoder::Backward(UInt32 &backRes, UInt32 cur)
{
m_OptimumEndIndex = cur;
UINT32 posMem = m_Optimum[cur].PosPrev;
UINT16 backMem = m_Optimum[cur].BackPrev;
UInt32 posMem = m_Optimum[cur].PosPrev;
UInt16 backMem = m_Optimum[cur].BackPrev;
do
{
UINT32 posPrev = posMem;
UINT16 backCur = backMem;
UInt32 posPrev = posMem;
UInt16 backCur = backMem;
backMem = m_Optimum[posPrev].BackPrev;
posMem = m_Optimum[posPrev].PosPrev;
m_Optimum[posPrev].BackPrev = backCur;
m_Optimum[posPrev].PosPrev = cur;
m_Optimum[posPrev].PosPrev = (UInt16)cur;
cur = posPrev;
}
while(cur > 0);
@@ -283,11 +289,11 @@ UINT32 CCoder::Backward(UINT32 &backRes, UINT32 cur)
return m_OptimumCurrentIndex;
}
UINT32 CCoder::GetOptimal(UINT32 &backRes)
UInt32 CCoder::GetOptimal(UInt32 &backRes)
{
if(m_OptimumEndIndex != m_OptimumCurrentIndex)
{
UINT32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex;
UInt32 len = m_Optimum[m_OptimumCurrentIndex].PosPrev - m_OptimumCurrentIndex;
backRes = m_Optimum[m_OptimumCurrentIndex].BackPrev;
m_OptimumCurrentIndex = m_Optimum[m_OptimumCurrentIndex].PosPrev;
return len;
@@ -295,10 +301,10 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
m_OptimumCurrentIndex = 0;
m_OptimumEndIndex = 0;
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize));
GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize));
UINT32 lenMain = m_LongestMatchLength;
UINT32 backMain = m_LongestMatchDistance;
UInt32 lenMain = m_LongestMatchLength;
UInt32 backMain = m_LongestMatchDistance;
if(lenMain < kMatchMinLen)
return 1;
@@ -308,13 +314,13 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
MovePos(lenMain - 1);
return lenMain;
}
m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset)];
m_Optimum[1].Price = m_LiteralPrices[m_MatchFinder->GetIndexByte(0 - m_AdditionalOffset)];
m_Optimum[1].PosPrev = 0;
m_Optimum[2].Price = kIfinityPrice;
m_Optimum[2].PosPrev = 1;
for(UINT32 i = kMatchMinLen; i <= lenMain; i++)
for(UInt32 i = kMatchMinLen; i <= lenMain; i++)
{
m_Optimum[i].PosPrev = 0;
m_Optimum[i].BackPrev = m_MatchDistances[i];
@@ -322,26 +328,26 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
}
UINT32 cur = 0;
UINT32 lenEnd = lenMain;
UInt32 cur = 0;
UInt32 lenEnd = lenMain;
while(true)
{
cur++;
if(cur == lenEnd)
return Backward(backRes, cur);
GetBacks(UINT32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur));
UINT32 newLen = m_LongestMatchLength;
GetBacks(UInt32(m_BlockStartPostion + m_CurrentBlockUncompressedSize + cur));
UInt32 newLen = m_LongestMatchLength;
if(newLen >= m_MatchLengthEdge)
return Backward(backRes, cur);
UINT32 curPrice = m_Optimum[cur].Price;
UINT32 curAnd1Price = curPrice +
m_LiteralPrices[m_MatchFinder.GetIndexByte(cur - m_AdditionalOffset)];
UInt32 curPrice = m_Optimum[cur].Price;
UInt32 curAnd1Price = curPrice +
m_LiteralPrices[m_MatchFinder->GetIndexByte(cur - m_AdditionalOffset)];
COptimal &optimum = m_Optimum[cur + 1];
if (curAnd1Price < optimum.Price)
{
optimum.Price = curAnd1Price;
optimum.PosPrev = cur;
optimum.PosPrev = (UInt16)cur;
}
if (newLen < kMatchMinLen)
continue;
@@ -349,24 +355,24 @@ UINT32 CCoder::GetOptimal(UINT32 &backRes)
{
if (cur + newLen > kNumOpts - 1)
newLen = kNumOpts - 1 - cur;
UINT32 lenEndNew = cur + newLen;
UInt32 lenEndNew = cur + newLen;
if (lenEnd < lenEndNew)
{
for(UINT32 i = lenEnd + 1; i <= lenEndNew; i++)
for(UInt32 i = lenEnd + 1; i <= lenEndNew; i++)
m_Optimum[i].Price = kIfinityPrice;
lenEnd = lenEndNew;
}
}
for(UINT32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++)
for(UInt32 lenTest = kMatchMinLen; lenTest <= newLen; lenTest++)
{
UINT16 curBack = m_MatchDistances[lenTest];
UINT32 curAndLenPrice = curPrice +
UInt16 curBack = m_MatchDistances[lenTest];
UInt32 curAndLenPrice = curPrice +
m_LenPrices[lenTest - kMatchMinLen] + m_PosPrices[GetPosSlot(curBack)];
COptimal &optimum = m_Optimum[cur + lenTest];
if (curAndLenPrice < optimum.Price)
{
optimum.Price = curAndLenPrice;
optimum.PosPrev = cur;
optimum.PosPrev = (UInt16)cur;
optimum.BackPrev = curBack;
}
}
@@ -389,13 +395,13 @@ void CCoder::InitStructures()
m_MainCoder.StartNewBlock();
m_DistCoder.StartNewBlock();
UINT32 i;
UInt32 i;
for(i = 0; i < 256; i++)
m_LiteralPrices[i] = 8;
for(i = 0; i < m_NumLenCombinations; i++)
m_LenPrices[i] = 5 + m_LenDirectBits[g_LenSlots[i]]; // test it
m_LenPrices[i] = (Byte)(5 + m_LenDirectBits[g_LenSlots[i]]); // test it
for(i = 0; i < kDistTableSize64; i++)
m_PosPrices[i] = 5 + kDistDirectBits[i];
m_PosPrices[i] = (Byte)(5 + kDistDirectBits[i]);
}
void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
@@ -407,27 +413,27 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
{
if(method == NBlockType::kStored)
{
for(UINT32 i = 0; i < m_CurrentBlockUncompressedSize; i++)
for(UInt32 i = 0; i < m_CurrentBlockUncompressedSize; i++)
{
BYTE b = m_MatchFinder.GetIndexByte(i - m_AdditionalOffset -
Byte b = m_MatchFinder->GetIndexByte(i - m_AdditionalOffset -
m_CurrentBlockUncompressedSize);
m_OutStream.WriteBits(b, 8);
}
}
else
{
for (UINT32 i = 0; i < m_ValueIndex; i++)
for (UInt32 i = 0; i < m_ValueIndex; i++)
{
if (m_Values[i].Flag == kFlagImm)
m_MainCoder.CodeOneValue(&m_ReverseOutStream, m_Values[i].Imm);
else if (m_Values[i].Flag == kFlagLenPos)
{
UINT32 len = m_Values[i].Len;
UINT32 lenSlot = g_LenSlots[len];
UInt32 len = m_Values[i].Len;
UInt32 lenSlot = g_LenSlots[len];
m_MainCoder.CodeOneValue(&m_ReverseOutStream, kMatchNumber + lenSlot);
m_OutStream.WriteBits(len - m_LenStart[lenSlot], m_LenDirectBits[lenSlot]);
UINT32 dist = m_Values[i].Pos;
UINT32 posSlot = GetPosSlot(dist);
UInt32 dist = m_Values[i].Pos;
UInt32 posSlot = GetPosSlot(dist);
m_DistCoder.CodeOneValue(&m_ReverseOutStream, posSlot);
m_OutStream.WriteBits(dist - kDistStart[posSlot], kDistDirectBits[posSlot]);
}
@@ -438,7 +444,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
m_MainCoder.StartNewBlock();
m_DistCoder.StartNewBlock();
m_ValueIndex = 0;
UINT32 i;
UInt32 i;
for(i = 0; i < 256; i++)
if(m_LastLevels[i] != 0)
m_LiteralPrices[i] = m_LastLevels[i];
@@ -449,8 +455,8 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
for(i = 0; i < m_NumLenCombinations; i++)
{
UINT32 slot = g_LenSlots[i];
BYTE dummy = m_LastLevels[kMatchNumber + slot];
UInt32 slot = g_LenSlots[i];
Byte dummy = m_LastLevels[kMatchNumber + slot];
if (dummy != 0)
m_LenPrices[i] = dummy;
else
@@ -459,7 +465,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
}
for(i = 0; i < kDistTableSize64; i++)
{
BYTE dummy = m_LastLevels[kDistTableStart + i];
Byte dummy = m_LastLevels[kDistTableStart + i];
if (dummy != 0)
m_PosPrices[i] = dummy;
else
@@ -468,7 +474,7 @@ void CCoder::WriteBlockData(bool writeMode, bool finalBlock)
}
}
void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
void CCoder::CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode)
{
int prevLen = 0xFF; // last emitted length
int nextLen = newLevels[0]; // length of next code
@@ -480,7 +486,7 @@ void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
maxCount = 138;
minCount = 3;
}
BYTE oldValueInGuardElement = newLevels[numLevels]; // push guard value
Byte oldValueInGuardElement = newLevels[numLevels]; // push guard value
try
{
newLevels[numLevels] = 0xFF; // guard already set
@@ -568,7 +574,7 @@ void CCoder::CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode)
int CCoder::WriteTables(bool writeMode, bool finalBlock)
{
BYTE newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard
Byte newLevels[kMaxTableSize64 + 1]; // (+ 1) for guard
m_MainCoder.BuildTree(&newLevels[0]);
m_DistCoder.BuildTree(&newLevels[kDistTableStart]);
@@ -604,22 +610,22 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock)
memcpy(m_LastLevels, newLevels, kMaxTableSize64);
BYTE levelLevels[kLevelTableSize];
Byte levelLevels[kLevelTableSize];
m_LevelCoder.BuildTree(levelLevels);
BYTE levelLevelsStream[kLevelTableSize];
Byte levelLevelsStream[kLevelTableSize];
int numLevelCodes = kDeflateNumberOfLevelCodesMin;
int i;
for (i = 0; i < kLevelTableSize; i++)
{
int streamPos = kCodeLengthAlphabetOrder[i];
int level = levelLevels[streamPos];
Byte level = levelLevels[streamPos];
if (level > 0 && i >= numLevelCodes)
numLevelCodes = i + 1;
levelLevelsStream[i] = level;
}
UINT32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength();
UInt32 numLZHuffmanBits = m_MainCoder.GetBlockBitLength();
numLZHuffmanBits += m_DistCoder.GetBlockBitLength();
numLZHuffmanBits += m_LevelCoder.GetBlockBitLength();
numLZHuffmanBits += kDeflateNumberOfLengthCodesFieldSize +
@@ -627,18 +633,18 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock)
kDeflateNumberOfLevelCodesFieldSize;
numLZHuffmanBits += numLevelCodes * kDeflateLevelCodeFieldSize;
UINT32 nextBitPosition =
UInt32 nextBitPosition =
(m_OutStream.GetBitPosition() + kBlockTypeFieldSize) % 8;
UINT32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
UInt32 numBitsForAlign = nextBitPosition > 0 ? (8 - nextBitPosition): 0;
UINT32 numStoreBits = numBitsForAlign + (2 * sizeof(UINT16)) * 8;
UInt32 numStoreBits = numBitsForAlign + (2 * 2) * 8;
numStoreBits += m_CurrentBlockUncompressedSize * 8;
if(numStoreBits < numLZHuffmanBits)
{
m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize); // test it
m_OutStream.WriteBits(0, numBitsForAlign); // test it
UINT16 currentBlockUncompressedSize = UINT16(m_CurrentBlockUncompressedSize);
UINT16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize;
UInt16 currentBlockUncompressedSize = UInt16(m_CurrentBlockUncompressedSize);
UInt16 currentBlockUncompressedSizeNot = ~currentBlockUncompressedSize;
m_OutStream.WriteBits(currentBlockUncompressedSize, kDeflateStoredBlockLengthFieldSizeSize);
m_OutStream.WriteBits(currentBlockUncompressedSizeNot, kDeflateStoredBlockLengthFieldSizeSize);
return NBlockType::kStored;
@@ -669,23 +675,33 @@ int CCoder::WriteTables(bool writeMode, bool finalBlock)
}
HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
if (!m_Created)
{
RINOK(Create());
if (!m_MainCoder.Create(kMainTableSize, _deflate64Mode ? kLenDirectBits64 : kLenDirectBits32,
kMatchNumber, kMaxCodeBitLength))
return E_OUTOFMEMORY;
if (!m_DistCoder.Create(_deflate64Mode ? kDistTableSize64 : kDistTableSize32,
kDistDirectBits, 0, kMaxCodeBitLength))
return E_OUTOFMEMORY;
if (!m_LevelCoder.Create(kLevelTableSize, kLevelDirectBits, 0, kMaxLevelBitLength))
return E_OUTOFMEMORY;
m_Created = true;
}
UINT64 nowPos = 0;
UInt64 nowPos = 0;
m_FinderPos = 0;
RINOK(m_MatchFinder.Init(inStream));
m_OutStream.Init(outStream);
RINOK(m_MatchFinder->Init(inStream));
m_OutStream.SetStream(outStream);
m_OutStream.Init();
m_ReverseOutStream.Init(&m_OutStream);
// CCoderReleaser coderReleaser(this);
CCoderReleaser coderReleaser(this);
InitStructures();
while(true)
@@ -696,29 +712,29 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
{
while(true)
{
noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder.GetNumAvailableBytes() == 0);
noMoreBytes = (m_AdditionalOffset == 0 && m_MatchFinder->GetNumAvailableBytes() == 0);
if (((m_CurrentBlockUncompressedSize >= kBlockUncompressedSizeThreshold ||
m_ValueIndex >= kValueBlockSize) &&
(m_OptimumEndIndex == m_OptimumCurrentIndex))
|| noMoreBytes)
break;
UINT32 pos;
UINT32 len = GetOptimal(pos);
UInt32 pos;
UInt32 len = GetOptimal(pos);
if (len >= kMatchMinLen)
{
UINT32 newLen = len - kMatchMinLen;
UInt32 newLen = len - kMatchMinLen;
m_Values[m_ValueIndex].Flag = kFlagLenPos;
m_Values[m_ValueIndex].Len = BYTE(newLen);
UINT32 lenSlot = g_LenSlots[newLen];
m_Values[m_ValueIndex].Len = Byte(newLen);
UInt32 lenSlot = g_LenSlots[newLen];
m_MainCoder.AddSymbol(kMatchNumber + lenSlot);
m_Values[m_ValueIndex].Pos = UINT16(pos);
UINT32 posSlot = GetPosSlot(pos);
m_Values[m_ValueIndex].Pos = UInt16(pos);
UInt32 posSlot = GetPosSlot(pos);
m_DistCoder.AddSymbol(posSlot);
}
else if (len == 1)
{
BYTE b = m_MatchFinder.GetIndexByte(0 - m_AdditionalOffset);
Byte b = m_MatchFinder->GetIndexByte(0 - m_AdditionalOffset);
len = 1;
m_MainCoder.AddSymbol(b);
m_Values[m_ValueIndex].Flag = kFlagImm;
@@ -738,14 +754,14 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
if (writeMode)
break;
nowPos = m_BlockStartPostion;
m_AdditionalOffset = UINT32(m_FinderPos - m_BlockStartPostion);
m_AdditionalOffset = UInt32(m_FinderPos - m_BlockStartPostion);
m_CurrentBlockUncompressedSize = 0;
}
m_BlockStartPostion += m_CurrentBlockUncompressedSize;
m_CurrentBlockUncompressedSize = 0;
if (progress != NULL)
{
UINT64 packSize = m_OutStream.GetProcessedSize();
UInt64 packSize = m_OutStream.GetProcessedSize();
RINOK(progress->SetRatioInfo(&nowPos, &packSize));
}
if (noMoreBytes)
@@ -755,7 +771,7 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream,
}
HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
@@ -765,21 +781,21 @@ HRESULT CCoder::BaseCode(ISequentialInStream *inStream,
}
STDMETHODIMP CCOMCoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{ return BaseCode(inStream, outStream, inSize, outSize, progress); }
STDMETHODIMP CCOMCoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties)
const PROPVARIANT *properties, UInt32 numProperties)
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
STDMETHODIMP CCOMCoder64::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress)
{ return BaseCode(inStream, outStream, inSize, outSize, progress); }
STDMETHODIMP CCOMCoder64::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties)
const PROPVARIANT *properties, UInt32 numProperties)
{ return BaseSetEncoderProperties2(propIDs, properties, numProperties); }
}}}

View File

@@ -1,7 +1,5 @@
// DeflateEncoder.h
#pragma once
#ifndef __DEFLATE_ENCODER_H
#define __DEFLATE_ENCODER_H
@@ -9,7 +7,7 @@
#include "../../ICoder.h"
#include "../../Common/LSBFEncoder.h"
#include "../LZ/BinTree/BinTree3Z.h"
#include "../LZ/IMatchFinder.h"
#include "../Huffman/HuffmanEncoder.h"
#include "DeflateConst.h"
@@ -20,22 +18,22 @@ namespace NEncoder {
struct CCodeValue
{
BYTE Flag;
Byte Flag;
union
{
BYTE Imm;
BYTE Len;
Byte Imm;
Byte Len;
};
UINT16 Pos;
UInt16 Pos;
};
class COnePosMatches
{
public:
UINT16 *MatchDistances;
UINT16 LongestMatchLength;
UINT16 LongestMatchDistance;
void Init(UINT16 *matchDistances)
UInt16 *MatchDistances;
UInt16 LongestMatchLength;
UInt16 LongestMatchDistance;
void Init(UInt16 *matchDistances)
{
MatchDistances = matchDistances;
};
@@ -43,21 +41,20 @@ public:
struct COptimal
{
UINT32 Price;
UINT16 PosPrev;
UINT16 BackPrev;
UInt32 Price;
UInt16 PosPrev;
UInt16 BackPrev;
};
const int kNumOpts = 0x1000;
class CCoder
{
UINT32 m_FinderPos;
UInt32 m_FinderPos;
COptimal m_Optimum[kNumOpts];
// CComPtr<IInWindowStreamMatch> m_MatchFinder;
NBT3Z::CInTree m_MatchFinder;
CMyComPtr<IMatchFinder> m_MatchFinder;
NStream::NLSBF::CEncoder m_OutStream;
NStream::NLSBF::CReverseEncoder m_ReverseOutStream;
@@ -66,93 +63,88 @@ class CCoder
NCompression::NHuffman::CEncoder m_DistCoder;
NCompression::NHuffman::CEncoder m_LevelCoder;
BYTE m_LastLevels[kMaxTableSize64];
Byte m_LastLevels[kMaxTableSize64];
UINT32 m_ValueIndex;
UInt32 m_ValueIndex;
CCodeValue *m_Values;
UINT32 m_OptimumEndIndex;
UINT32 m_OptimumCurrentIndex;
UINT32 m_AdditionalOffset;
UInt32 m_OptimumEndIndex;
UInt32 m_OptimumCurrentIndex;
UInt32 m_AdditionalOffset;
UINT32 m_LongestMatchLength;
UINT32 m_LongestMatchDistance;
UINT16 *m_MatchDistances;
UInt32 m_LongestMatchLength;
UInt32 m_LongestMatchDistance;
UInt16 *m_MatchDistances;
UINT32 m_NumFastBytes;
UINT32 m_MatchLengthEdge;
UInt32 m_NumFastBytes;
UInt32 m_MatchLengthEdge;
BYTE m_LiteralPrices[256];
Byte m_LiteralPrices[256];
BYTE m_LenPrices[kNumLenCombinations32];
BYTE m_PosPrices[kDistTableSize64];
Byte m_LenPrices[kNumLenCombinations32];
Byte m_PosPrices[kDistTableSize64];
UINT32 m_CurrentBlockUncompressedSize;
UInt32 m_CurrentBlockUncompressedSize;
COnePosMatches *m_OnePosMatchesArray;
UINT16 *m_OnePosMatchesMemory;
UInt16 *m_OnePosMatchesMemory;
UINT64 m_BlockStartPostion;
UInt64 m_BlockStartPostion;
int m_NumPasses;
bool m_Created;
bool _deflate64Mode;
UINT32 m_NumLenCombinations;
UINT32 m_MatchMaxLen;
const BYTE *m_LenStart;
const BYTE *m_LenDirectBits;
UInt32 m_NumLenCombinations;
UInt32 m_MatchMaxLen;
const Byte *m_LenStart;
const Byte *m_LenDirectBits;
HRESULT Create();
void Free();
void GetBacks(UINT32 aPos);
void GetBacks(UInt32 aPos);
void ReadGoodBacks();
void MovePos(UINT32 num);
UINT32 Backward(UINT32 &backRes, UINT32 cur);
UINT32 GetOptimal(UINT32 &backRes);
void MovePos(UInt32 num);
UInt32 Backward(UInt32 &backRes, UInt32 cur);
UInt32 GetOptimal(UInt32 &backRes);
void InitStructures();
void CodeLevelTable(BYTE *newLevels, int numLevels, bool codeMode);
void CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode);
int WriteTables(bool writeMode, bool finalBlock);
void CopyBackBlockOp(UINT32 distance, UINT32 length);
void CopyBackBlockOp(UInt32 distance, UInt32 length);
void WriteBlockData(bool writeMode, bool finalBlock);
/*
void CCoder::ReleaseStreams()
{
m_MatchFinder.ReleaseStream();
// m_MatchFinder.ReleaseStream();
m_OutStream.ReleaseStream();
}
class CCoderReleaser
{
CCoder *m_Coder;
public:
CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {}
~CCoderReleaser()
{
m_Coder->ReleaseStreams();
}
CCoderReleaser(CCoder *coder): m_Coder(coder) {}
~CCoderReleaser() { m_Coder->ReleaseStreams(); }
};
friend class CCoderReleaser;
*/
public:
CCoder(bool deflate64Mode = false);
~CCoder();
HRESULT CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
HRESULT BaseCode(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// ICompressSetCoderProperties
HRESULT BaseSetEncoderProperties2(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties);
const PROPVARIANT *properties, UInt32 numProperties);
};
///////////////////////////////////////////////////////////////
@@ -167,11 +159,11 @@ public:
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
CCOMCoder(): CCoder(false) {};
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// ICompressSetCoderProperties
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties);
const PROPVARIANT *properties, UInt32 numProperties);
};
class CCOMCoder64 :
@@ -184,11 +176,11 @@ public:
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
CCOMCoder64(): CCoder(true) {};
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
// ICompressSetCoderProperties
STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
const PROPVARIANT *properties, UINT32 numProperties);
const PROPVARIANT *properties, UInt32 numProperties);
};

View File

@@ -1,7 +1,5 @@
// DeflateExtConst.h
#pragma once
#ifndef __DEFLATE_EXTCONST_H
#define __DEFLATE_EXTCONST_H
@@ -10,17 +8,17 @@
namespace NCompress {
namespace NDeflate {
// const UINT32 kDistTableSize = 30;
const UINT32 kDistTableSize32 = 30;
const UINT32 kDistTableSize64 = 32;
// const UInt32 kDistTableSize = 30;
const UInt32 kDistTableSize32 = 30;
const UInt32 kDistTableSize64 = 32;
const UINT32 kHistorySize32 = 0x8000;
const UINT32 kHistorySize64 = 0x10000;
const UINT32 kNumLenCombinations32 = 256;
const UINT32 kNumLenCombinations64 = 255;
const UInt32 kHistorySize32 = 0x8000;
const UInt32 kHistorySize64 = 0x10000;
const UInt32 kNumLenCombinations32 = 256;
const UInt32 kNumLenCombinations64 = 255;
// don't change kNumLenCombinations64. It must be less than 255.
const UINT32 kNumHuffmanBits = 15;
const UInt32 kNumHuffmanBits = 15;
}}

View File

@@ -2,11 +2,11 @@
#include "StdAfx.h"
#define INITGUID
#include "Common/MyInitGuid.h"
#include "Common/ComTry.h"
#include "DeflateEncoder.h"
#include "DeflateDecoder.h"
#include "Common/ComTry.h"
// {23170F69-40C1-278B-0401-080000000000}

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp
#include "stdafx.h"
#include "StdAfx.h"

View File

@@ -1,8 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include "../../../Common/MyWindows.h"
#endif
#endif

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,9,2,0
PRODUCTVERSION 3,9,2,0
FILEVERSION 4,19,0,0
PRODUCTVERSION 4,19,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -85,14 +85,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "Deflate Coder\0"
VALUE "FileVersion", "3, 9, 2, 0\0"
VALUE "FileVersion", "4, 19, 0, 0\0"
VALUE "InternalName", "Deflate\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "Deflate.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "3, 9, 2, 0\0"
VALUE "ProductVersion", "4, 19, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END