Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Compress/Deflate/DeflateEncoder.cpp')
-rwxr-xr-xCPP/7zip/Compress/Deflate/DeflateEncoder.cpp80
1 files changed, 60 insertions, 20 deletions
diff --git a/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp b/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
index a574fa3c..ac68ff35 100755
--- a/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
+++ b/CPP/7zip/Compress/Deflate/DeflateEncoder.cpp
@@ -104,6 +104,8 @@ CCoder::CCoder(bool deflate64Mode):
m_NumPasses(1),
m_NumDivPasses(1),
m_NumFastBytes(32),
+ _fastMode(false),
+ _btMode(true),
m_OnePosMatchesMemory(0),
m_DistanceMemory(0),
m_Created(false),
@@ -157,7 +159,7 @@ HRESULT CCoder::Create()
if (!m_Created)
{
- _lzInWindow.btMode = 1;
+ _lzInWindow.btMode = _btMode ? 1 : 0;
_lzInWindow.numHashBytes = 3;
if (!MatchFinder_Create(&_lzInWindow,
m_Deflate64Mode ? kHistorySize64 : kHistorySize32,
@@ -213,6 +215,15 @@ HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs,
m_MatchFinderCycles = prop.ulVal;
break;
}
+ case NCoderPropID::kAlgorithm:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 maximize = prop.ulVal;
+ _fastMode = (maximize == 0);
+ _btMode = !_fastMode;
+ break;
+ }
default:
return E_INVALIDARG;
}
@@ -238,7 +249,7 @@ CCoder::~CCoder()
MatchFinder_Free(&_lzInWindow, &g_Alloc);
}
-void CCoder::GetMatches()
+NO_INLINE void CCoder::GetMatches()
{
if (m_IsMultiPass)
{
@@ -252,7 +263,10 @@ void CCoder::GetMatches()
UInt32 distanceTmp[kMatchMaxLen * 2 + 3];
- UInt32 numPairs = Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp);
+ UInt32 numPairs = (_btMode) ?
+ Bt3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp):
+ Hc3Zip_MatchFinder_GetMatches(&_lzInWindow, distanceTmp);
+
*m_MatchDistances = (UInt16)numPairs;
if (numPairs > 0)
@@ -285,7 +299,10 @@ void CCoder::MovePos(UInt32 num)
{
if (!m_SecondPass && num > 0)
{
- Bt3Zip_MatchFinder_Skip(&_lzInWindow, num);
+ if (_btMode)
+ Bt3Zip_MatchFinder_Skip(&_lzInWindow, num);
+ else
+ Hc3Zip_MatchFinder_Skip(&_lzInWindow, num);
m_AdditionalOffset += num;
}
}
@@ -420,6 +437,18 @@ NO_INLINE UInt32 CCoder::GetOptimal(UInt32 &backRes)
}
}
+UInt32 CCoder::GetOptimalFast(UInt32 &backRes)
+{
+ GetMatches();
+ UInt32 numDistancePairs = m_MatchDistances[0];
+ if (numDistancePairs == 0)
+ return 1;
+ UInt32 lenMain = m_MatchDistances[numDistancePairs - 1];
+ backRes = m_MatchDistances[numDistancePairs];
+ MovePos(lenMain - 1);
+ return lenMain;
+}
+
void CTables::InitStructures()
{
UInt32 i;
@@ -489,8 +518,13 @@ NO_INLINE void CCoder::LevelTableDummy(const Byte *levels, int numLevels, UInt32
}
}
+NO_INLINE void CCoder::WriteBits(UInt32 value, int numBits)
+{
+ m_OutStream.WriteBits(value, numBits);
+}
+
#define WRITE_HF2(codes, lens, i) m_OutStream.WriteBits(codes[i], lens[i])
-#define WRITE_HF(i) m_OutStream.WriteBits(codes[i], lens[i])
+#define WRITE_HF(i) WriteBits(codes[i], lens[i])
NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const Byte *lens, const UInt32 *codes)
{
@@ -523,17 +557,17 @@ NO_INLINE void CCoder::LevelTableCode(const Byte *levels, int numLevels, const B
count--;
}
WRITE_HF(kTableLevelRepNumber);
- m_OutStream.WriteBits(count - 3, 2);
+ WriteBits(count - 3, 2);
}
else if (count <= 10)
{
WRITE_HF(kTableLevel0Number);
- m_OutStream.WriteBits(count - 3, 3);
+ WriteBits(count - 3, 3);
}
else
{
WRITE_HF(kTableLevel0Number2);
- m_OutStream.WriteBits(count - 11, 7);
+ WriteBits(count - 11, 7);
}
count = 0;
@@ -602,7 +636,11 @@ NO_INLINE void CCoder::TryBlock()
break;
}
UInt32 pos;
- UInt32 len = GetOptimal(pos);
+ UInt32 len;
+ if (_fastMode)
+ len = GetOptimalFast(pos);
+ else
+ len = GetOptimal(pos);
CCodeValue &codeValue = m_Values[m_ValueIndex++];
if (len >= kMatchMinLen)
{
@@ -629,6 +667,8 @@ NO_INLINE void CCoder::TryBlock()
NO_INLINE void CCoder::SetPrices(const CLevels &levels)
{
+ if (_fastMode)
+ return;
UInt32 i;
for(i = 0; i < 256; i++)
{
@@ -709,11 +749,11 @@ void CCoder::WriteStoreBlock(UInt32 blockSize, UInt32 additionalOffset, bool fin
{
UInt32 curBlockSize = (blockSize < (1 << 16)) ? blockSize : (1 << 16) - 1;
blockSize -= curBlockSize;
- m_OutStream.WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
- m_OutStream.WriteBits(NBlockType::kStored, kBlockTypeFieldSize);
+ WriteBits((finalBlock && (blockSize == 0) ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
+ WriteBits(NBlockType::kStored, kBlockTypeFieldSize);
m_OutStream.FlushByte();
- m_OutStream.WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize);
- m_OutStream.WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize);
+ WriteBits((UInt16)curBlockSize, kStoredBlockLengthFieldSize);
+ WriteBits((UInt16)~curBlockSize, kStoredBlockLengthFieldSize);
const Byte *data = Inline_MatchFinder_GetPointerToCurrentPos(&_lzInWindow)- additionalOffset;
for(UInt32 i = 0; i < curBlockSize; i++)
m_OutStream.WriteByte(data[i]);
@@ -847,10 +887,10 @@ void CCoder::CodeBlock(int tableIndex, bool finalBlock)
WriteStoreBlock(t.BlockSizeRes, m_AdditionalOffset, finalBlock);
else
{
- m_OutStream.WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
+ WriteBits((finalBlock ? NFinalBlockField::kFinalBlock: NFinalBlockField::kNotFinalBlock), kFinalBlockFieldSize);
if (t.StaticMode)
{
- m_OutStream.WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize);
+ WriteBits(NBlockType::kFixedHuffman, kBlockTypeFieldSize);
TryFixedBlock(tableIndex);
int i;
for (i = 0; i < kFixedMainTableSize; i++)
@@ -863,13 +903,13 @@ void CCoder::CodeBlock(int tableIndex, bool finalBlock)
{
if (m_NumDivPasses > 1 || m_CheckStatic)
TryDynBlock(tableIndex, 1);
- m_OutStream.WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
- m_OutStream.WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize);
- m_OutStream.WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize);
- m_OutStream.WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize);
+ WriteBits(NBlockType::kDynamicHuffman, kBlockTypeFieldSize);
+ WriteBits(m_NumLitLenLevels - kNumLitLenCodesMin, kNumLenCodesFieldSize);
+ WriteBits(m_NumDistLevels - kNumDistCodesMin, kNumDistCodesFieldSize);
+ WriteBits(m_NumLevelCodes - kNumLevelCodesMin, kNumLevelCodesFieldSize);
for (UInt32 i = 0; i < m_NumLevelCodes; i++)
- m_OutStream.WriteBits(m_LevelLevels[i], kLevelFieldSize);
+ WriteBits(m_LevelLevels[i], kLevelFieldSize);
Huffman_ReverseBits(levelCodes, levelLens, kLevelTableSize);
LevelTableCode(m_NewLevels.litLenLevels, m_NumLitLenLevels, levelLens, levelCodes);