mirror of
https://github.com/holub/mame
synced 2025-05-30 17:41:47 +03:00
346 lines
8.9 KiB
C++
346 lines
8.9 KiB
C++
// MethodProps.h
|
|
|
|
#ifndef __7Z_METHOD_PROPS_H
|
|
#define __7Z_METHOD_PROPS_H
|
|
|
|
#include "../../Common/MyString.h"
|
|
#include "../../Common/Defs.h"
|
|
|
|
#include "../../Windows/Defs.h"
|
|
|
|
#include "../../Windows/PropVariant.h"
|
|
|
|
#include "../ICoder.h"
|
|
|
|
// UInt64 GetMemoryUsage_LZMA(UInt32 dict, bool isBt, UInt32 numThreads);
|
|
|
|
inline UInt64 Calc_From_Val_Percents_Less100(UInt64 val, UInt64 percents)
|
|
{
|
|
if (percents == 0)
|
|
return 0;
|
|
if (val <= (UInt64)(Int64)-1 / percents)
|
|
return val * percents / 100;
|
|
return val / 100 * percents;
|
|
}
|
|
|
|
UInt64 Calc_From_Val_Percents(UInt64 val, UInt64 percents);
|
|
|
|
bool StringToBool(const wchar_t *s, bool &res);
|
|
HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
|
|
unsigned ParseStringToUInt32(const UString &srcString, UInt32 &number);
|
|
|
|
/*
|
|
if (name.IsEmpty() && prop.vt == VT_EMPTY), it doesn't change (resValue) and returns S_OK.
|
|
So you must set (resValue) for default value before calling */
|
|
HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
|
|
|
/* input: (numThreads = the_number_of_processors) */
|
|
HRESULT ParseMtProp2(const UString &name, const PROPVARIANT &prop, UInt32 &numThreads, bool &force);
|
|
|
|
inline HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 numCPUs, UInt32 &numThreads)
|
|
{
|
|
bool forced = false;
|
|
numThreads = numCPUs;
|
|
return ParseMtProp2(name, prop, numThreads, forced);
|
|
}
|
|
|
|
|
|
struct CProp
|
|
{
|
|
PROPID Id;
|
|
bool IsOptional;
|
|
NWindows::NCOM::CPropVariant Value;
|
|
CProp(): IsOptional(false) {}
|
|
};
|
|
|
|
struct CProps
|
|
{
|
|
CObjectVector<CProp> Props;
|
|
|
|
void Clear() { Props.Clear(); }
|
|
|
|
bool AreThereNonOptionalProps() const
|
|
{
|
|
FOR_VECTOR (i, Props)
|
|
if (!Props[i].IsOptional)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void AddProp32(PROPID propid, UInt32 val);
|
|
|
|
void AddPropBool(PROPID propid, bool val);
|
|
|
|
void AddProp_Ascii(PROPID propid, const char *s)
|
|
{
|
|
CProp &prop = Props.AddNew();
|
|
prop.IsOptional = true;
|
|
prop.Id = propid;
|
|
prop.Value = s;
|
|
}
|
|
|
|
HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce = NULL) const;
|
|
HRESULT SetCoderProps_DSReduce_Aff(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce, const UInt64 *affinity) const;
|
|
};
|
|
|
|
class CMethodProps: public CProps
|
|
{
|
|
HRESULT SetParam(const UString &name, const UString &value);
|
|
public:
|
|
unsigned GetLevel() const;
|
|
int Get_NumThreads() const
|
|
{
|
|
const int i = FindProp(NCoderPropID::kNumThreads);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_UI4)
|
|
return (int)val.ulVal;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool Get_DicSize(UInt64 &res) const
|
|
{
|
|
res = 0;
|
|
const int i = FindProp(NCoderPropID::kDictionarySize);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_UI4)
|
|
{
|
|
res = val.ulVal;
|
|
return true;
|
|
}
|
|
if (val.vt == VT_UI8)
|
|
{
|
|
res = val.uhVal.QuadPart;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int FindProp(PROPID id) const;
|
|
|
|
UInt32 Get_Lzma_Algo() const
|
|
{
|
|
int i = FindProp(NCoderPropID::kAlgorithm);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_UI4)
|
|
return val.ulVal;
|
|
}
|
|
return GetLevel() >= 5 ? 1 : 0;
|
|
}
|
|
|
|
UInt64 Get_Lzma_DicSize() const
|
|
{
|
|
UInt64 v;
|
|
if (Get_DicSize(v))
|
|
return v;
|
|
const unsigned level = GetLevel();
|
|
const UInt32 dictSize =
|
|
( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) :
|
|
( level <= 6 ? ((UInt32)1 << (level + 19)) :
|
|
( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26)
|
|
)));
|
|
return dictSize;
|
|
}
|
|
|
|
bool Get_Lzma_MatchFinder_IsBt() const
|
|
{
|
|
const int i = FindProp(NCoderPropID::kMatchFinder);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_BSTR)
|
|
return ((val.bstrVal[0] | 0x20) != 'h'); // check for "hc"
|
|
}
|
|
return GetLevel() >= 5;
|
|
}
|
|
|
|
bool Get_Lzma_Eos() const
|
|
{
|
|
const int i = FindProp(NCoderPropID::kEndMarker);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_BOOL)
|
|
return VARIANT_BOOLToBool(val.boolVal);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Are_Lzma_Model_Props_Defined() const
|
|
{
|
|
if (FindProp(NCoderPropID::kPosStateBits) >= 0) return true;
|
|
if (FindProp(NCoderPropID::kLitContextBits) >= 0) return true;
|
|
if (FindProp(NCoderPropID::kLitPosBits) >= 0) return true;
|
|
return false;
|
|
}
|
|
|
|
UInt32 Get_Lzma_NumThreads() const
|
|
{
|
|
if (Get_Lzma_Algo() == 0)
|
|
return 1;
|
|
int numThreads = Get_NumThreads();
|
|
if (numThreads >= 0)
|
|
return numThreads < 2 ? 1 : 2;
|
|
return 2;
|
|
}
|
|
|
|
UInt64 Get_Lzma_MemUsage(bool addSlidingWindowSize) const;
|
|
|
|
/* returns -1, if numThreads is unknown */
|
|
int Get_Xz_NumThreads(UInt32 &lzmaThreads) const
|
|
{
|
|
lzmaThreads = 1;
|
|
int numThreads = Get_NumThreads();
|
|
if (numThreads >= 0 && numThreads <= 1)
|
|
return 1;
|
|
if (Get_Lzma_Algo() != 0)
|
|
lzmaThreads = 2;
|
|
return numThreads;
|
|
}
|
|
|
|
UInt64 GetProp_BlockSize(PROPID id) const
|
|
{
|
|
const int i = FindProp(id);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_UI4) { return val.ulVal; }
|
|
if (val.vt == VT_UI8) { return val.uhVal.QuadPart; }
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
UInt64 Get_Xz_BlockSize() const
|
|
{
|
|
{
|
|
UInt64 blockSize1 = GetProp_BlockSize(NCoderPropID::kBlockSize);
|
|
UInt64 blockSize2 = GetProp_BlockSize(NCoderPropID::kBlockSize2);
|
|
UInt64 minSize = MyMin(blockSize1, blockSize2);
|
|
if (minSize != 0)
|
|
return minSize;
|
|
UInt64 maxSize = MyMax(blockSize1, blockSize2);
|
|
if (maxSize != 0)
|
|
return maxSize;
|
|
}
|
|
const UInt32 kMinSize = (UInt32)1 << 20;
|
|
const UInt32 kMaxSize = (UInt32)1 << 28;
|
|
const UInt64 dictSize = Get_Lzma_DicSize();
|
|
/* lzma2 code uses fake 4 GiB to calculate ChunkSize. So we do same */
|
|
UInt64 blockSize = (UInt64)dictSize << 2;
|
|
if (blockSize < kMinSize) blockSize = kMinSize;
|
|
if (blockSize > kMaxSize) blockSize = kMaxSize;
|
|
if (blockSize < dictSize) blockSize = dictSize;
|
|
blockSize += (kMinSize - 1);
|
|
blockSize &= ~(UInt64)(kMinSize - 1);
|
|
return blockSize;
|
|
}
|
|
|
|
|
|
UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
|
|
{
|
|
fixedNumber = false;
|
|
int numThreads = Get_NumThreads();
|
|
if (numThreads >= 0)
|
|
{
|
|
fixedNumber = true;
|
|
if (numThreads < 1) return 1;
|
|
const unsigned kNumBZip2ThreadsMax = 64;
|
|
if ((unsigned)numThreads > kNumBZip2ThreadsMax) return kNumBZip2ThreadsMax;
|
|
return (unsigned)numThreads;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
UInt32 Get_BZip2_BlockSize() const
|
|
{
|
|
const int i = FindProp(NCoderPropID::kDictionarySize);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_UI4)
|
|
{
|
|
UInt32 blockSize = val.ulVal;
|
|
const UInt32 kDicSizeMin = 100000;
|
|
const UInt32 kDicSizeMax = 900000;
|
|
if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
|
|
if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
|
|
return blockSize;
|
|
}
|
|
}
|
|
const unsigned level = GetLevel();
|
|
return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
|
|
}
|
|
|
|
UInt64 Get_Ppmd_MemSize() const
|
|
{
|
|
const int i = FindProp(NCoderPropID::kUsedMemorySize);
|
|
if (i >= 0)
|
|
{
|
|
const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
|
|
if (val.vt == VT_UI4)
|
|
return val.ulVal;
|
|
if (val.vt == VT_UI8)
|
|
return val.uhVal.QuadPart;
|
|
}
|
|
const unsigned level = GetLevel();
|
|
const UInt32 mem = (UInt32)1 << (level + 19);
|
|
return mem;
|
|
}
|
|
|
|
void AddProp_Level(UInt32 level)
|
|
{
|
|
AddProp32(NCoderPropID::kLevel, level);
|
|
}
|
|
|
|
void AddProp_NumThreads(UInt32 numThreads)
|
|
{
|
|
AddProp32(NCoderPropID::kNumThreads, numThreads);
|
|
}
|
|
|
|
void AddProp_EndMarker_if_NotFound(bool eos)
|
|
{
|
|
if (FindProp(NCoderPropID::kEndMarker) < 0)
|
|
AddPropBool(NCoderPropID::kEndMarker, eos);
|
|
}
|
|
|
|
void AddProp_BlockSize2(UInt64 blockSize2)
|
|
{
|
|
if (FindProp(NCoderPropID::kBlockSize2) < 0)
|
|
{
|
|
CProp &prop = Props.AddNew();
|
|
prop.IsOptional = true;
|
|
prop.Id = NCoderPropID::kBlockSize2;
|
|
prop.Value = blockSize2;
|
|
}
|
|
}
|
|
|
|
HRESULT ParseParamsFromString(const UString &srcString);
|
|
HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
|
|
};
|
|
|
|
class COneMethodInfo: public CMethodProps
|
|
{
|
|
public:
|
|
AString MethodName;
|
|
UString PropsString;
|
|
|
|
void Clear()
|
|
{
|
|
CMethodProps::Clear();
|
|
MethodName.Empty();
|
|
PropsString.Empty();
|
|
}
|
|
bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); }
|
|
HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
|
|
HRESULT ParseMethodFromString(const UString &s);
|
|
};
|
|
|
|
#endif
|