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