1 // MethodProps.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../Common/MyCom.h"
6
7 #include "../ICoder.h"
8
9 #include "MethodProps.h"
10
11 static const UInt64 k_LZMA = 0x030101;
12 static const UInt64 k_LZMA2 = 0x21;
13
SetMethodProperties(const CMethod & method,const UInt64 * inSizeForReduce,IUnknown * coder)14 HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
15 {
16 bool tryReduce = false;
17 UInt32 reducedDictionarySize = 1 << 10;
18 if (inSizeForReduce != 0 && (method.Id == k_LZMA || method.Id == k_LZMA2))
19 {
20 for (;;)
21 {
22 const UInt32 step = (reducedDictionarySize >> 1);
23 if (reducedDictionarySize >= *inSizeForReduce)
24 {
25 tryReduce = true;
26 break;
27 }
28 reducedDictionarySize += step;
29 if (reducedDictionarySize >= *inSizeForReduce)
30 {
31 tryReduce = true;
32 break;
33 }
34 if (reducedDictionarySize >= ((UInt32)3 << 30))
35 break;
36 reducedDictionarySize += step;
37 }
38 }
39
40 {
41 int numProps = method.Props.Size();
42 CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
43 coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
44 if (setCoderProperties == NULL)
45 {
46 if (numProps != 0)
47 return E_INVALIDARG;
48 }
49 else
50 {
51 CRecordVector<PROPID> propIDs;
52 NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps];
53 HRESULT res = S_OK;
54 try
55 {
56 for (int i = 0; i < numProps; i++)
57 {
58 const CProp &prop = method.Props[i];
59 propIDs.Add(prop.Id);
60 NWindows::NCOM::CPropVariant &value = values[i];
61 value = prop.Value;
62 // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
63 if (tryReduce)
64 if (prop.Id == NCoderPropID::kDictionarySize)
65 if (value.vt == VT_UI4)
66 if (reducedDictionarySize < value.ulVal)
67 value.ulVal = reducedDictionarySize;
68 }
69 CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
70 coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
71 res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps);
72 }
73 catch(...)
74 {
75 delete []values;
76 throw;
77 }
78 delete []values;
79 RINOK(res);
80 }
81 }
82
83 /*
84 CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
85 coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
86 if (writeCoderProperties != NULL)
87 {
88 CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
89 CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
90 outStreamSpec->Init();
91 RINOK(writeCoderProperties->WriteCoderProperties(outStream));
92 size_t size = outStreamSpec->GetSize();
93 filterProps.SetCapacity(size);
94 memmove(filterProps, outStreamSpec->GetBuffer(), size);
95 }
96 */
97 return S_OK;
98 }
99
100