1370b324cSopenharmony_ci// XzEncoder.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../C/Alloc.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "../../Common/MyString.h"
8370b324cSopenharmony_ci#include "../../Common/StringToInt.h"
9370b324cSopenharmony_ci
10370b324cSopenharmony_ci#include "../Common/CWrappers.h"
11370b324cSopenharmony_ci#include "../Common/StreamUtils.h"
12370b324cSopenharmony_ci
13370b324cSopenharmony_ci#include "XzEncoder.h"
14370b324cSopenharmony_ci
15370b324cSopenharmony_cinamespace NCompress {
16370b324cSopenharmony_ci
17370b324cSopenharmony_cinamespace NLzma2 {
18370b324cSopenharmony_ciHRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
19370b324cSopenharmony_ci}
20370b324cSopenharmony_ci
21370b324cSopenharmony_cinamespace NXz {
22370b324cSopenharmony_ci
23370b324cSopenharmony_civoid CEncoder::InitCoderProps()
24370b324cSopenharmony_ci{
25370b324cSopenharmony_ci  XzProps_Init(&xzProps);
26370b324cSopenharmony_ci}
27370b324cSopenharmony_ci
28370b324cSopenharmony_ciCEncoder::CEncoder()
29370b324cSopenharmony_ci{
30370b324cSopenharmony_ci  XzProps_Init(&xzProps);
31370b324cSopenharmony_ci  _encoder = NULL;
32370b324cSopenharmony_ci  _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc);
33370b324cSopenharmony_ci  if (!_encoder)
34370b324cSopenharmony_ci    throw 1;
35370b324cSopenharmony_ci}
36370b324cSopenharmony_ci
37370b324cSopenharmony_ciCEncoder::~CEncoder()
38370b324cSopenharmony_ci{
39370b324cSopenharmony_ci  if (_encoder)
40370b324cSopenharmony_ci    XzEnc_Destroy(_encoder);
41370b324cSopenharmony_ci}
42370b324cSopenharmony_ci
43370b324cSopenharmony_ci
44370b324cSopenharmony_cistruct CMethodNamePair
45370b324cSopenharmony_ci{
46370b324cSopenharmony_ci  UInt32 Id;
47370b324cSopenharmony_ci  const char *Name;
48370b324cSopenharmony_ci};
49370b324cSopenharmony_ci
50370b324cSopenharmony_cistatic const CMethodNamePair g_NamePairs[] =
51370b324cSopenharmony_ci{
52370b324cSopenharmony_ci  { XZ_ID_Delta, "Delta" },
53370b324cSopenharmony_ci  { XZ_ID_X86, "BCJ" },
54370b324cSopenharmony_ci  { XZ_ID_PPC, "PPC" },
55370b324cSopenharmony_ci  { XZ_ID_IA64, "IA64" },
56370b324cSopenharmony_ci  { XZ_ID_ARM, "ARM" },
57370b324cSopenharmony_ci  { XZ_ID_ARMT, "ARMT" },
58370b324cSopenharmony_ci  { XZ_ID_SPARC, "SPARC" }
59370b324cSopenharmony_ci  // { XZ_ID_LZMA2, "LZMA2" }
60370b324cSopenharmony_ci};
61370b324cSopenharmony_ci
62370b324cSopenharmony_cistatic int FilterIdFromName(const wchar_t *name)
63370b324cSopenharmony_ci{
64370b324cSopenharmony_ci  for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++)
65370b324cSopenharmony_ci  {
66370b324cSopenharmony_ci    const CMethodNamePair &pair = g_NamePairs[i];
67370b324cSopenharmony_ci    if (StringsAreEqualNoCase_Ascii(name, pair.Name))
68370b324cSopenharmony_ci      return (int)pair.Id;
69370b324cSopenharmony_ci  }
70370b324cSopenharmony_ci  return -1;
71370b324cSopenharmony_ci}
72370b324cSopenharmony_ci
73370b324cSopenharmony_ci
74370b324cSopenharmony_ciHRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes)
75370b324cSopenharmony_ci{
76370b324cSopenharmony_ci  unsigned id;
77370b324cSopenharmony_ci  switch (checkSizeInBytes)
78370b324cSopenharmony_ci  {
79370b324cSopenharmony_ci    case  0: id = XZ_CHECK_NO; break;
80370b324cSopenharmony_ci    case  4: id = XZ_CHECK_CRC32; break;
81370b324cSopenharmony_ci    case  8: id = XZ_CHECK_CRC64; break;
82370b324cSopenharmony_ci    case 32: id = XZ_CHECK_SHA256; break;
83370b324cSopenharmony_ci    default: return E_INVALIDARG;
84370b324cSopenharmony_ci  }
85370b324cSopenharmony_ci  xzProps.checkId = id;
86370b324cSopenharmony_ci  return S_OK;
87370b324cSopenharmony_ci}
88370b324cSopenharmony_ci
89370b324cSopenharmony_ci
90370b324cSopenharmony_ciHRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
91370b324cSopenharmony_ci{
92370b324cSopenharmony_ci  if (propID == NCoderPropID::kNumThreads)
93370b324cSopenharmony_ci  {
94370b324cSopenharmony_ci    if (prop.vt != VT_UI4)
95370b324cSopenharmony_ci      return E_INVALIDARG;
96370b324cSopenharmony_ci    xzProps.numTotalThreads = (int)(prop.ulVal);
97370b324cSopenharmony_ci    return S_OK;
98370b324cSopenharmony_ci  }
99370b324cSopenharmony_ci
100370b324cSopenharmony_ci  if (propID == NCoderPropID::kCheckSize)
101370b324cSopenharmony_ci  {
102370b324cSopenharmony_ci    if (prop.vt != VT_UI4)
103370b324cSopenharmony_ci      return E_INVALIDARG;
104370b324cSopenharmony_ci    return SetCheckSize(prop.ulVal);
105370b324cSopenharmony_ci  }
106370b324cSopenharmony_ci
107370b324cSopenharmony_ci  if (propID == NCoderPropID::kBlockSize2)
108370b324cSopenharmony_ci  {
109370b324cSopenharmony_ci    if (prop.vt == VT_UI4)
110370b324cSopenharmony_ci      xzProps.blockSize = prop.ulVal;
111370b324cSopenharmony_ci    else if (prop.vt == VT_UI8)
112370b324cSopenharmony_ci      xzProps.blockSize = prop.uhVal.QuadPart;
113370b324cSopenharmony_ci    else
114370b324cSopenharmony_ci      return E_INVALIDARG;
115370b324cSopenharmony_ci    return S_OK;
116370b324cSopenharmony_ci  }
117370b324cSopenharmony_ci
118370b324cSopenharmony_ci  if (propID == NCoderPropID::kReduceSize)
119370b324cSopenharmony_ci  {
120370b324cSopenharmony_ci    if (prop.vt == VT_UI8)
121370b324cSopenharmony_ci      xzProps.reduceSize = prop.uhVal.QuadPart;
122370b324cSopenharmony_ci    else
123370b324cSopenharmony_ci      return E_INVALIDARG;
124370b324cSopenharmony_ci    return S_OK;
125370b324cSopenharmony_ci  }
126370b324cSopenharmony_ci
127370b324cSopenharmony_ci  if (propID == NCoderPropID::kFilter)
128370b324cSopenharmony_ci  {
129370b324cSopenharmony_ci    if (prop.vt == VT_UI4)
130370b324cSopenharmony_ci    {
131370b324cSopenharmony_ci      const UInt32 id32 = prop.ulVal;
132370b324cSopenharmony_ci      if (id32 == XZ_ID_Delta)
133370b324cSopenharmony_ci        return E_INVALIDARG;
134370b324cSopenharmony_ci      xzProps.filterProps.id = prop.ulVal;
135370b324cSopenharmony_ci    }
136370b324cSopenharmony_ci    else
137370b324cSopenharmony_ci    {
138370b324cSopenharmony_ci      if (prop.vt != VT_BSTR)
139370b324cSopenharmony_ci        return E_INVALIDARG;
140370b324cSopenharmony_ci
141370b324cSopenharmony_ci      const wchar_t *name = prop.bstrVal;
142370b324cSopenharmony_ci      const wchar_t *end;
143370b324cSopenharmony_ci
144370b324cSopenharmony_ci      UInt32 id32 = ConvertStringToUInt32(name, &end);
145370b324cSopenharmony_ci
146370b324cSopenharmony_ci      if (end != name)
147370b324cSopenharmony_ci        name = end;
148370b324cSopenharmony_ci      else
149370b324cSopenharmony_ci      {
150370b324cSopenharmony_ci        if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta"))
151370b324cSopenharmony_ci        {
152370b324cSopenharmony_ci          name += 5; // strlen("Delta");
153370b324cSopenharmony_ci          id32 = XZ_ID_Delta;
154370b324cSopenharmony_ci        }
155370b324cSopenharmony_ci        else
156370b324cSopenharmony_ci        {
157370b324cSopenharmony_ci          const int filterId = FilterIdFromName(prop.bstrVal);
158370b324cSopenharmony_ci          if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
159370b324cSopenharmony_ci            return E_INVALIDARG;
160370b324cSopenharmony_ci          id32 = (unsigned)filterId;
161370b324cSopenharmony_ci        }
162370b324cSopenharmony_ci      }
163370b324cSopenharmony_ci
164370b324cSopenharmony_ci      if (id32 == XZ_ID_Delta)
165370b324cSopenharmony_ci      {
166370b324cSopenharmony_ci        const wchar_t c = *name;
167370b324cSopenharmony_ci        if (c != '-' && c != ':')
168370b324cSopenharmony_ci          return E_INVALIDARG;
169370b324cSopenharmony_ci        name++;
170370b324cSopenharmony_ci        const UInt32 delta = ConvertStringToUInt32(name, &end);
171370b324cSopenharmony_ci        if (end == name || *end != 0 || delta == 0 || delta > 256)
172370b324cSopenharmony_ci          return E_INVALIDARG;
173370b324cSopenharmony_ci        xzProps.filterProps.delta = delta;
174370b324cSopenharmony_ci      }
175370b324cSopenharmony_ci
176370b324cSopenharmony_ci      xzProps.filterProps.id = id32;
177370b324cSopenharmony_ci    }
178370b324cSopenharmony_ci
179370b324cSopenharmony_ci    return S_OK;
180370b324cSopenharmony_ci  }
181370b324cSopenharmony_ci
182370b324cSopenharmony_ci  return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props);
183370b324cSopenharmony_ci}
184370b324cSopenharmony_ci
185370b324cSopenharmony_ci
186370b324cSopenharmony_ciZ7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs,
187370b324cSopenharmony_ci    const PROPVARIANT *coderProps, UInt32 numProps))
188370b324cSopenharmony_ci{
189370b324cSopenharmony_ci  XzProps_Init(&xzProps);
190370b324cSopenharmony_ci
191370b324cSopenharmony_ci  for (UInt32 i = 0; i < numProps; i++)
192370b324cSopenharmony_ci  {
193370b324cSopenharmony_ci    RINOK(SetCoderProp(propIDs[i], coderProps[i]))
194370b324cSopenharmony_ci  }
195370b324cSopenharmony_ci
196370b324cSopenharmony_ci  return S_OK;
197370b324cSopenharmony_ci  // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps));
198370b324cSopenharmony_ci}
199370b324cSopenharmony_ci
200370b324cSopenharmony_ci
201370b324cSopenharmony_ciZ7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
202370b324cSopenharmony_ci    const PROPVARIANT *coderProps, UInt32 numProps))
203370b324cSopenharmony_ci{
204370b324cSopenharmony_ci  for (UInt32 i = 0; i < numProps; i++)
205370b324cSopenharmony_ci  {
206370b324cSopenharmony_ci    const PROPVARIANT &prop = coderProps[i];
207370b324cSopenharmony_ci    const PROPID propID = propIDs[i];
208370b324cSopenharmony_ci    if (propID == NCoderPropID::kExpectedDataSize)
209370b324cSopenharmony_ci      if (prop.vt == VT_UI8)
210370b324cSopenharmony_ci        XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
211370b324cSopenharmony_ci  }
212370b324cSopenharmony_ci  return S_OK;
213370b324cSopenharmony_ci}
214370b324cSopenharmony_ci
215370b324cSopenharmony_ci
216370b324cSopenharmony_ci#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
217370b324cSopenharmony_ci  if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
218370b324cSopenharmony_ci
219370b324cSopenharmony_ciZ7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
220370b324cSopenharmony_ci    const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress))
221370b324cSopenharmony_ci{
222370b324cSopenharmony_ci  CSeqInStreamWrap inWrap;
223370b324cSopenharmony_ci  CSeqOutStreamWrap outWrap;
224370b324cSopenharmony_ci  CCompressProgressWrap progressWrap;
225370b324cSopenharmony_ci
226370b324cSopenharmony_ci  inWrap.Init(inStream);
227370b324cSopenharmony_ci  outWrap.Init(outStream);
228370b324cSopenharmony_ci  progressWrap.Init(progress);
229370b324cSopenharmony_ci
230370b324cSopenharmony_ci  SRes res = XzEnc_SetProps(_encoder, &xzProps);
231370b324cSopenharmony_ci  if (res == SZ_OK)
232370b324cSopenharmony_ci    res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
233370b324cSopenharmony_ci
234370b324cSopenharmony_ci  // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL);
235370b324cSopenharmony_ci
236370b324cSopenharmony_ci  RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
237370b324cSopenharmony_ci  RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
238370b324cSopenharmony_ci  RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
239370b324cSopenharmony_ci
240370b324cSopenharmony_ci  return SResToHRESULT(res);
241370b324cSopenharmony_ci}
242370b324cSopenharmony_ci
243370b324cSopenharmony_ci}}
244