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
11static const UInt64 k_LZMA = 0x030101;
12static const UInt64 k_LZMA2 = 0x21;
13
14HRESULT 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