summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix/CPP/7zip/Archive/DeflateProps.cpp
blob: 8498e0565e98b06575a2c3b54fb7940058926bf5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// DeflateProps.cpp

#include "StdAfx.h"

#include "Windows/PropVariant.h"

#include "Common/ParseProperties.h"

#include "DeflateProps.h"

namespace NArchive {

static const UInt32 kAlgo1 = 0;
static const UInt32 kAlgo5 = 1;

static const UInt32 kPasses1 = 1;
static const UInt32 kPasses7 = 3;
static const UInt32 kPasses9 = 10;

static const UInt32 kFb1 = 32;
static const UInt32 kFb7 = 64;
static const UInt32 kFb9 = 128;

void CDeflateProps::Normalize()
{
  UInt32 level = Level;
  if (level == 0xFFFFFFFF)
    level = 5;
  
  if (Algo == 0xFFFFFFFF)
    Algo = (level >= 5 ?
      kAlgo5 :
      kAlgo1);

  if (NumPasses == 0xFFFFFFFF)
    NumPasses =
      (level >= 9 ? kPasses9 :
      (level >= 7 ? kPasses7 :
                    kPasses1));
  if (Fb == 0xFFFFFFFF)
    Fb =
      (level >= 9 ? kFb9 :
      (level >= 7 ? kFb7 :
                    kFb1));
}

HRESULT CDeflateProps::SetCoderProperties(ICompressSetCoderProperties *setCoderProperties)
{
  Normalize();

  NWindows::NCOM::CPropVariant props[] =
  {
    Algo,
    NumPasses,
    Fb,
    Mc
  };
  PROPID propIDs[] =
  {
    NCoderPropID::kAlgorithm,
    NCoderPropID::kNumPasses,
    NCoderPropID::kNumFastBytes,
    NCoderPropID::kMatchFinderCycles
  };
  int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
  if (!McDefined)
    numProps--;
  return setCoderProperties->SetCoderProperties(propIDs, props, numProps);
}

HRESULT CDeflateProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
  Init();
  for (int i = 0; i < numProps; i++)
  {
    UString name = names[i];
    name.MakeUpper();
    if (name.IsEmpty())
      return E_INVALIDARG;
    const PROPVARIANT &prop = values[i];
    if (name[0] == L'X')
    {
      UInt32 a = 9;
      RINOK(ParsePropValue(name.Mid(1), prop, a));
      Level = a;
    }
    else if (name.Left(1) == L"A")
    {
      UInt32 a = kAlgo5;
      RINOK(ParsePropValue(name.Mid(1), prop, a));
      Algo = a;
    }
    else if (name.Left(4) == L"PASS")
    {
      UInt32 a = kPasses9;
      RINOK(ParsePropValue(name.Mid(4), prop, a));
      NumPasses = a;
    }
    else if (name.Left(2) == L"FB")
    {
      UInt32 a = kFb9;
      RINOK(ParsePropValue(name.Mid(2), prop, a));
      Fb = a;
    }
    else if (name.Left(2) == L"MC")
    {
      UInt32 a = 0xFFFFFFFF;
      RINOK(ParsePropValue(name.Mid(2), prop, a));
      Mc = a;
      McDefined = true;
    }
    else
      return E_INVALIDARG;
  }
  return S_OK;
}

}