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 '7zip/Archive/7z/7zEncode.cpp')
-rwxr-xr-x7zip/Archive/7z/7zEncode.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/7zip/Archive/7z/7zEncode.cpp b/7zip/Archive/7z/7zEncode.cpp
index 5a9dd86e..a4fb7159 100755
--- a/7zip/Archive/7z/7zEncode.cpp
+++ b/7zip/Archive/7z/7zEncode.cpp
@@ -18,9 +18,10 @@ static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
#include "../../Compress/Copy/CopyCoder.h"
#endif
+static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
+
#ifdef COMPRESS_LZMA
#include "../../Compress/LZMA/LZMAEncoder.h"
-static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
#endif
#ifdef COMPRESS_PPMD
@@ -114,7 +115,7 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindI
folder.PackStreams.Add(bindInfo.InStreams[i]);
}
-HRESULT CEncoder::CreateMixerCoder()
+HRESULT CEncoder::CreateMixerCoder(const UInt64 *inSizeForReduce)
{
_mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
_mixerCoder = _mixerCoderSpec;
@@ -203,6 +204,30 @@ HRESULT CEncoder::CreateMixerCoder()
return E_FAIL;
#endif
}
+
+ bool tryReduce = false;
+ UInt32 reducedDictionarySize = 1 << 10;
+ if (inSizeForReduce != 0 && methodFull.MethodID == k_LZMA)
+ {
+ while (true)
+ {
+ const UInt32 step = (reducedDictionarySize >> 1);
+ if (reducedDictionarySize >= *inSizeForReduce)
+ {
+ tryReduce = true;
+ break;
+ }
+ reducedDictionarySize += step;
+ if (reducedDictionarySize >= *inSizeForReduce)
+ {
+ tryReduce = true;
+ break;
+ }
+ if (reducedDictionarySize >= ((UInt32)11 << 30))
+ break;
+ reducedDictionarySize += step;
+ }
+ }
if (methodFull.CoderProperties.Size() > 0)
{
@@ -215,7 +240,10 @@ HRESULT CEncoder::CreateMixerCoder()
{
const CProperty &property = methodFull.CoderProperties[i];
propIDs.Add(property.PropID);
- values[i] = property.Value;
+ NWindows::NCOM::CPropVariant value = property.Value;
+ if (tryReduce && property.PropID == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
+ value.ulVal = reducedDictionarySize;
+ values[i] = value;
}
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
if (methodFull.IsSimpleCoder())
@@ -308,7 +336,7 @@ HRESULT CEncoder::CreateMixerCoder()
}
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
- const UInt64 *inStreamSize,
+ const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
@@ -316,7 +344,7 @@ HRESULT CEncoder::Encode(ISequentialInStream *inStream,
{
if (_mixerCoderSpec == NULL)
{
- RINOK(CreateMixerCoder());
+ RINOK(CreateMixerCoder(inSizeForReduce));
}
_mixerCoderSpec->ReInit();
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);