Skip to content

Commit 8844577

Browse files
authored
Merge pull request #405 from sebres/gh-403-zstd--max
Ultimate (and advanced max zstd) level
2 parents 0934111 + 85ec8c5 commit 8844577

File tree

12 files changed

+225
-42
lines changed

12 files changed

+225
-42
lines changed

CPP/7zip/Archive/7z/7zHandler.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ HRESULT CHandler::ObtainBlockMethods(CNum folderIndex, PROPVARIANT *prop, CHandl
604604
{
605605
UInt32 l = props[2];
606606
if (info) {
607-
if (l <= 22) {
607+
if (l <= 22 || l == Z7_ZSTD_ULTIMATE_LEV) {
608608
lev = l;
609609
} else {
610610
// todo: need parameter to set fast mode (to NCoderPropID::kFast)
@@ -625,6 +625,11 @@ HRESULT CHandler::ObtainBlockMethods(CNum folderIndex, PROPVARIANT *prop, CHandl
625625
if (l <= 22) {
626626
*dest++ = 'l';
627627
ConvertUInt32ToString(l, dest);
628+
} else if (l == Z7_ZSTD_ULTIMATE_LEV) { // special level for zstd --max (advanced ultra)
629+
*dest++ = 'm';
630+
*dest++ = 'a';
631+
*dest++ = 'x';
632+
*dest = '\0';
628633
} else {
629634
*dest++ = 'f';
630635
*dest++ = 'l';

CPP/7zip/Archive/Common/HandlerOut.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
184184
_level = 9;
185185
return ParsePropToUInt32(name, value, _level);
186186
}
187+
if (name == L"max")
188+
{
189+
bool _max;
190+
const HRESULT res = PROPVARIANT_to_bool(value, _max);
191+
if (res == S_OK && _max) {
192+
// adjust level (zstd --max), set it to the highest level too (e. g. setting of options.MaxFilter for BCJ2 etc)
193+
_level = Z7_ZSTD_ULTIMATE_LEV;
194+
}
195+
return res;
196+
}
187197

188198
if (name.IsPrefixedBy_Ascii_NoCase("yx"))
189199
{

CPP/7zip/Common/MethodProps.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ unsigned CMethodProps::GetLevel() const
369369
if (Props[(unsigned)i].Value.vt != VT_UI4)
370370
return 9;
371371
UInt32 level = Props[(unsigned)i].Value.ulVal;
372-
return level > 9 ? 9 : (unsigned)level;
372+
// return level > 9 ? 9 : (unsigned)level;
373+
return level;
373374
}
374375

375376
struct CNameToPropID
@@ -422,7 +423,8 @@ static const CNameToPropID g_NameToPropID[] =
422423
{ VT_UI4, "ldmhlog" },
423424
{ VT_UI4, "ldmslen" },
424425
{ VT_UI4, "ldmblog" },
425-
{ VT_UI4, "ldmhevery" }
426+
{ VT_UI4, "ldmhevery" },
427+
{ VT_BOOL, "max" }
426428
};
427429

428430
#if defined(static_assert) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || (_MSC_VER >= 1900)
@@ -581,11 +583,24 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
581583
}
582584
if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
583585
return E_INVALIDARG;
586+
if (prop.Id == NCoderPropID::kAdvMax && prop.Value.boolVal) {
587+
setMaxCompression();
588+
}
584589
}
585590
Props.Add(prop);
586591
return S_OK;
587592
}
588593

594+
void CMethodProps::setMaxCompression()
595+
{
596+
// adjust level (zstd --max), set it to the highest level too (e. g. setting of options.MaxFilter for BCJ2 etc)
597+
CProp prop;
598+
prop.Id = (unsigned)NCoderPropID::kLevel;
599+
prop.Value.vt = VT_UI4;
600+
prop.Value.ulVal = Z7_ZSTD_ULTIMATE_LEV;
601+
Props.Add(prop);
602+
}
603+
589604
HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
590605
{
591606
UStringVector params;
@@ -631,6 +646,9 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
631646
{
632647
if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
633648
return E_INVALIDARG;
649+
if (prop.Id == NCoderPropID::kAdvMax && prop.Value.boolVal) {
650+
setMaxCompression();
651+
}
634652
}
635653
Props.Add(prop);
636654
return S_OK;

CPP/7zip/Common/MethodProps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct CProps
8686
class CMethodProps: public CProps
8787
{
8888
HRESULT SetParam(const UString &name, const UString &value);
89+
void setMaxCompression();
8990
public:
9091
unsigned GetLevel() const;
9192
int Get_NumThreads() const

CPP/7zip/Compress/ZstdEncoder.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ CEncoder::CEncoder():
1717
_processedIn(0),
1818
_processedOut(0),
1919
_numThreads(NWindows::NSystem::GetNumberOfProcessors()),
20+
_Max(false),
2021
_Long(-1),
2122
_Level(ZSTD_CLEVEL_DEFAULT),
2223
_Strategy(-1),
@@ -70,22 +71,33 @@ Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
7071
_Strategy = v;
7172
break;
7273
}
74+
case NCoderPropID::kAdvMax:
75+
if (!v)
76+
break;
77+
#if Z7_ZSTD_ADVMAX_ALLOWED // 64-bit only
78+
_Max = true;
79+
#endif
80+
v = Z7_ZSTD_ULTIMATE_LEV;
7381
case NCoderPropID::kLevel:
7482
{
75-
_Level = v;
83+
_Level = !_Max ? v : Z7_ZSTD_ULTIMATE_LEV;
7684
if (v < 1) {
7785
_Level = 1;
7886
} else if ((Int32)v > ZSTD_maxCLevel()) {
87+
#if Z7_ZSTD_ADVMAX_ALLOWED // 64-bit only
88+
_Max = (_Level == Z7_ZSTD_ULTIMATE_LEV); // special case (level from GUI)
89+
#endif
7990
_Level = ZSTD_maxCLevel();
8091
}
8192

8293
/**
83-
* zstd default levels: _Level => 1..ZSTD_maxCLevel()
94+
* zstd default levels: _Level => 1..ZSTD_maxCLevel(), Z7_ZSTD_ULTIMATE_LEV (128) == --max
8495
*/
85-
_props._level = static_cast < Byte > (_Level);
96+
_props._level = static_cast < Byte > (!_Max ? _Level : Z7_ZSTD_ULTIMATE_LEV);
8697
break;
8798
}
8899
case NCoderPropID::kFast:
100+
if (!_Max)
89101
{
90102
/* like --fast in zstd cli program */
91103
UInt32 _Fast = v;
@@ -256,6 +268,26 @@ Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream,
256268
if (!_dstBuf)
257269
return E_OUTOFMEMORY;
258270

271+
#if Z7_ZSTD_ADVMAX_ALLOWED // 64-bit only
272+
// params from setMaxCompression(), https://github.com/facebook/zstd/blob/v1.5.7/programs/zstdcli.c#L642 :
273+
if (_Max) {
274+
_Long = 1;
275+
_WindowLog = ZSTD_WINDOWLOG_MAX;
276+
_ChainLog = ZSTD_CHAINLOG_MAX;
277+
_HashLog = ZSTD_HASHLOG_MAX;
278+
_SearchLog = ZSTD_SEARCHLOG_MAX;
279+
_MinMatch = ZSTD_MINMATCH_MIN;
280+
_TargetLen = ZSTD_TARGETLENGTH_MAX;
281+
_Strategy = ZSTD_STRATEGY_MAX;
282+
_OverlapLog = ZSTD_OVERLAPLOG_MAX;
283+
_LdmHashLog = ZSTD_LDM_HASHLOG_MAX;
284+
_LdmHashRateLog = 0; /* automatically derived */
285+
_LdmMinMatch = 16; /* heuristic */
286+
_LdmBucketSizeLog = ZSTD_LDM_BUCKETSIZELOG_MAX;
287+
_Level = ZSTD_maxCLevel();
288+
}
289+
#endif
290+
259291
/* setup level */
260292
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_compressionLevel, (UInt32)_Level);
261293
if (ZSTD_isError(err)) return E_INVALIDARG;

CPP/7zip/Compress/ZstdEncoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Z7_CLASS_IMP_COM_5(
5353
UInt32 _numThreads;
5454

5555
/* zstd advanced compression options */
56+
bool _Max;
5657
Int32 _Long;
5758
Int32 _Level;
5859
Int32 _Strategy;

CPP/7zip/ICoder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,18 @@ namespace NCoderPropID
152152
kLdmSearchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64).
153153
kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3).
154154
kLdmHashRateLog, // VT_UI4 The default value is wlog - ldmhlog.
155+
kAdvMax, // VT_BOOL 1=ZSTD --max (advanced max compression)
155156
k_NUM_DEFINED
156157
};
157158
}
158159

160+
/* artificial level used to specify max possible level (for ZSTD advanced max compression, equivalent of --max) */
161+
#define Z7_ZSTD_ULTIMATE_LEV 255
162+
163+
#if !defined (Z7_ZSTD_ADVMAX_ALLOWED) && INTPTR_MAX == INT64_MAX // allowed for 64-bit only
164+
#define Z7_ZSTD_ADVMAX_ALLOWED 1
165+
#endif
166+
159167
#define Z7_IFACEM_ICompressSetCoderPropertiesOpt(x) \
160168
x(SetCoderPropertiesOpt(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps))
161169
Z7_IFACE_CONSTR_CODER(ICompressSetCoderPropertiesOpt, 0x1F)

CPP/7zip/UI/Console/Main.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,10 @@ DECLARE_AND_SET_CLIENT_VERSION_VAR
123123
#endif
124124

125125

126-
static const char * const kCopyrightString = "\n7-Zip"
127-
PROG_POSTFIX_2
128-
" " MY_VERSION_CPU
126+
#define kVersionString "7-Zip" PROG_POSTFIX_2 " " MY_VERSION_CPU
127+
128+
static const char * const kCopyrightString = "\n"
129+
kVersionString
129130
" : " MY_COPYRIGHT_DATE "\n";
130131

131132
static const char * const kHelpString =
@@ -145,6 +146,7 @@ static const char * const kHelpString =
145146
" t : Test integrity of archive\n"
146147
" u : Update files to archive\n"
147148
" x : eXtract files with full paths\n"
149+
" --version : Show version information\n"
148150
"\n"
149151
"<Switches>\n"
150152
" -- : Stop switches and @listfile parsing\n"
@@ -881,6 +883,11 @@ int Main2(
881883
return 0;
882884
}
883885

886+
if (commandStrings.Size() == 1 && commandStrings[0] == L"--version") {
887+
*g_StdStream << kVersionString;
888+
return 0;
889+
}
890+
884891
CArcCmdLineOptions options;
885892

886893
CArcCmdLineParser parser;

CPP/7zip/UI/GUI/CompressDialog.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,6 @@ static const EMethodID g_XzMethods[] =
284284
kLZMA2
285285
};
286286

287-
/*
288-
static const EMethodID g_ZstdMethods[] =
289-
{
290-
kZSTD
291-
};
292-
*/
293-
294287
/*
295288
static const EMethodID g_SwfcMethods[] =
296289
{
@@ -1673,11 +1666,12 @@ void CCompressDialog::SetLevel2()
16731666
UInt32 LevelsMask = fi.LevelsMask;
16741667
UInt32 LevelsStart = 1;
16751668
UInt32 LevelsEnd = 9;
1669+
int id = -1;
16761670
if (ai.LevelsMask != 0xFFFFFFFF)
16771671
LevelsMask = ai.LevelsMask;
16781672
else
16791673
{
1680-
int id = GetMethodID();
1674+
id = GetMethodID();
16811675
if (id == kCopy) {
16821676
LevelsStart = 0;
16831677
LevelsEnd = 0;
@@ -1699,12 +1693,14 @@ void CCompressDialog::SetLevel2()
16991693
}
17001694
}
17011695
UInt32 level = m_Level.GetCount() > 0 ? (UInt32)m_Level.GetItemData_of_CurSel() : (LevelsEnd - LevelsStart + 1) / 2;
1696+
UInt32 readLevel = (UInt32)-1;
17021697
m_Level.ResetContent();
17031698
{
17041699
int index = FindRegistryFormat(ai.Name);
17051700
if (index >= 0)
17061701
{
17071702
const NCompression::CFormatOptions &fo = m_RegistryInfo.Formats[index];
1703+
readLevel = fo.Level;
17081704
if (fo.Level <= LevelsEnd)
17091705
level = fo.Level;
17101706
else if (fo.Level == (UInt32)(Int32)-1)
@@ -1735,7 +1731,7 @@ void CCompressDialog::SetLevel2()
17351731
{
17361732
UString s = t;
17371733
s.Add_UInt32(i);
1738-
s += L" (";
1734+
s += L" "; if (i <= 9) s += L" "; s += L"(";
17391735
s += LangString(g_Levels[langID]);
17401736
s += L")";
17411737
int index = (int)m_Level.AddString(s);
@@ -1748,6 +1744,13 @@ void CCompressDialog::SetLevel2()
17481744
m_Level.SetItemData(index, i);
17491745
}
17501746
}
1747+
if (1) { // ultimate level (max possible or zstd --max if allowed)
1748+
int index = (int)m_Level.AddString(L"-mmax (Ultimate)");
1749+
m_Level.SetItemData(index, Z7_ZSTD_ULTIMATE_LEV);
1750+
if (readLevel == Z7_ZSTD_ULTIMATE_LEV) { // exception (available for any method), restore read from registry
1751+
level = readLevel;
1752+
}
1753+
}
17511754
SetNearestSelectComboBox(m_Level, level);
17521755
}
17531756

tests/7z.tcl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ proc 7z_get_info {args} {
8383
# to unix time (UTC, TZ independend)
8484
set v [clock scan [regsub {\.\d+$} $v {}]]
8585
}
86+
if {$n eq "Method"} {
87+
# remove version from method (unneeded and expecting adjustment of all tests by later version upgrades):
88+
regsub -all {v\d+\.\d+,?} $v {} v
89+
}
8690
lappend fi $n $v
8791
}
8892
if {[llength $fi]} { lappend flst $fi }

tests/regr-arc/test-sol.zstd.max.7z

261 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)