xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/XzEncoder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // XzEncoder.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/Alloc.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyString.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StringToInt.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../Common/CWrappers.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "XzEncoder.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker namespace NCompress {
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker namespace NLzma2 {
18*f6dc9357SAndroid Build Coastguard Worker HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
19*f6dc9357SAndroid Build Coastguard Worker }
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker namespace NXz {
22*f6dc9357SAndroid Build Coastguard Worker 
InitCoderProps()23*f6dc9357SAndroid Build Coastguard Worker void CEncoder::InitCoderProps()
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker   XzProps_Init(&xzProps);
26*f6dc9357SAndroid Build Coastguard Worker }
27*f6dc9357SAndroid Build Coastguard Worker 
CEncoder()28*f6dc9357SAndroid Build Coastguard Worker CEncoder::CEncoder()
29*f6dc9357SAndroid Build Coastguard Worker {
30*f6dc9357SAndroid Build Coastguard Worker   XzProps_Init(&xzProps);
31*f6dc9357SAndroid Build Coastguard Worker   _encoder = NULL;
32*f6dc9357SAndroid Build Coastguard Worker   _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc);
33*f6dc9357SAndroid Build Coastguard Worker   if (!_encoder)
34*f6dc9357SAndroid Build Coastguard Worker     throw 1;
35*f6dc9357SAndroid Build Coastguard Worker }
36*f6dc9357SAndroid Build Coastguard Worker 
~CEncoder()37*f6dc9357SAndroid Build Coastguard Worker CEncoder::~CEncoder()
38*f6dc9357SAndroid Build Coastguard Worker {
39*f6dc9357SAndroid Build Coastguard Worker   if (_encoder)
40*f6dc9357SAndroid Build Coastguard Worker     XzEnc_Destroy(_encoder);
41*f6dc9357SAndroid Build Coastguard Worker }
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker struct CMethodNamePair
45*f6dc9357SAndroid Build Coastguard Worker {
46*f6dc9357SAndroid Build Coastguard Worker   UInt32 Id;
47*f6dc9357SAndroid Build Coastguard Worker   const char *Name;
48*f6dc9357SAndroid Build Coastguard Worker };
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker static const CMethodNamePair g_NamePairs[] =
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_Delta, "Delta" },
53*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_X86, "BCJ" },
54*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_PPC, "PPC" },
55*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_IA64, "IA64" },
56*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_ARM, "ARM" },
57*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_ARMT, "ARMT" },
58*f6dc9357SAndroid Build Coastguard Worker   { XZ_ID_SPARC, "SPARC" }
59*f6dc9357SAndroid Build Coastguard Worker   // { XZ_ID_LZMA2, "LZMA2" }
60*f6dc9357SAndroid Build Coastguard Worker };
61*f6dc9357SAndroid Build Coastguard Worker 
FilterIdFromName(const wchar_t * name)62*f6dc9357SAndroid Build Coastguard Worker static int FilterIdFromName(const wchar_t *name)
63*f6dc9357SAndroid Build Coastguard Worker {
64*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < Z7_ARRAY_SIZE(g_NamePairs); i++)
65*f6dc9357SAndroid Build Coastguard Worker   {
66*f6dc9357SAndroid Build Coastguard Worker     const CMethodNamePair &pair = g_NamePairs[i];
67*f6dc9357SAndroid Build Coastguard Worker     if (StringsAreEqualNoCase_Ascii(name, pair.Name))
68*f6dc9357SAndroid Build Coastguard Worker       return (int)pair.Id;
69*f6dc9357SAndroid Build Coastguard Worker   }
70*f6dc9357SAndroid Build Coastguard Worker   return -1;
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker 
SetCheckSize(UInt32 checkSizeInBytes)74*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes)
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker   unsigned id;
77*f6dc9357SAndroid Build Coastguard Worker   switch (checkSizeInBytes)
78*f6dc9357SAndroid Build Coastguard Worker   {
79*f6dc9357SAndroid Build Coastguard Worker     case  0: id = XZ_CHECK_NO; break;
80*f6dc9357SAndroid Build Coastguard Worker     case  4: id = XZ_CHECK_CRC32; break;
81*f6dc9357SAndroid Build Coastguard Worker     case  8: id = XZ_CHECK_CRC64; break;
82*f6dc9357SAndroid Build Coastguard Worker     case 32: id = XZ_CHECK_SHA256; break;
83*f6dc9357SAndroid Build Coastguard Worker     default: return E_INVALIDARG;
84*f6dc9357SAndroid Build Coastguard Worker   }
85*f6dc9357SAndroid Build Coastguard Worker   xzProps.checkId = id;
86*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
87*f6dc9357SAndroid Build Coastguard Worker }
88*f6dc9357SAndroid Build Coastguard Worker 
89*f6dc9357SAndroid Build Coastguard Worker 
SetCoderProp(PROPID propID,const PROPVARIANT & prop)90*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
91*f6dc9357SAndroid Build Coastguard Worker {
92*f6dc9357SAndroid Build Coastguard Worker   if (propID == NCoderPropID::kNumThreads)
93*f6dc9357SAndroid Build Coastguard Worker   {
94*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt != VT_UI4)
95*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
96*f6dc9357SAndroid Build Coastguard Worker     xzProps.numTotalThreads = (int)(prop.ulVal);
97*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
98*f6dc9357SAndroid Build Coastguard Worker   }
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker   if (propID == NCoderPropID::kCheckSize)
101*f6dc9357SAndroid Build Coastguard Worker   {
102*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt != VT_UI4)
103*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
104*f6dc9357SAndroid Build Coastguard Worker     return SetCheckSize(prop.ulVal);
105*f6dc9357SAndroid Build Coastguard Worker   }
106*f6dc9357SAndroid Build Coastguard Worker 
107*f6dc9357SAndroid Build Coastguard Worker   if (propID == NCoderPropID::kBlockSize2)
108*f6dc9357SAndroid Build Coastguard Worker   {
109*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_UI4)
110*f6dc9357SAndroid Build Coastguard Worker       xzProps.blockSize = prop.ulVal;
111*f6dc9357SAndroid Build Coastguard Worker     else if (prop.vt == VT_UI8)
112*f6dc9357SAndroid Build Coastguard Worker       xzProps.blockSize = prop.uhVal.QuadPart;
113*f6dc9357SAndroid Build Coastguard Worker     else
114*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
115*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
116*f6dc9357SAndroid Build Coastguard Worker   }
117*f6dc9357SAndroid Build Coastguard Worker 
118*f6dc9357SAndroid Build Coastguard Worker   if (propID == NCoderPropID::kReduceSize)
119*f6dc9357SAndroid Build Coastguard Worker   {
120*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_UI8)
121*f6dc9357SAndroid Build Coastguard Worker       xzProps.reduceSize = prop.uhVal.QuadPart;
122*f6dc9357SAndroid Build Coastguard Worker     else
123*f6dc9357SAndroid Build Coastguard Worker       return E_INVALIDARG;
124*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
125*f6dc9357SAndroid Build Coastguard Worker   }
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker   if (propID == NCoderPropID::kFilter)
128*f6dc9357SAndroid Build Coastguard Worker   {
129*f6dc9357SAndroid Build Coastguard Worker     if (prop.vt == VT_UI4)
130*f6dc9357SAndroid Build Coastguard Worker     {
131*f6dc9357SAndroid Build Coastguard Worker       const UInt32 id32 = prop.ulVal;
132*f6dc9357SAndroid Build Coastguard Worker       if (id32 == XZ_ID_Delta)
133*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
134*f6dc9357SAndroid Build Coastguard Worker       xzProps.filterProps.id = prop.ulVal;
135*f6dc9357SAndroid Build Coastguard Worker     }
136*f6dc9357SAndroid Build Coastguard Worker     else
137*f6dc9357SAndroid Build Coastguard Worker     {
138*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_BSTR)
139*f6dc9357SAndroid Build Coastguard Worker         return E_INVALIDARG;
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker       const wchar_t *name = prop.bstrVal;
142*f6dc9357SAndroid Build Coastguard Worker       const wchar_t *end;
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker       UInt32 id32 = ConvertStringToUInt32(name, &end);
145*f6dc9357SAndroid Build Coastguard Worker 
146*f6dc9357SAndroid Build Coastguard Worker       if (end != name)
147*f6dc9357SAndroid Build Coastguard Worker         name = end;
148*f6dc9357SAndroid Build Coastguard Worker       else
149*f6dc9357SAndroid Build Coastguard Worker       {
150*f6dc9357SAndroid Build Coastguard Worker         if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta"))
151*f6dc9357SAndroid Build Coastguard Worker         {
152*f6dc9357SAndroid Build Coastguard Worker           name += 5; // strlen("Delta");
153*f6dc9357SAndroid Build Coastguard Worker           id32 = XZ_ID_Delta;
154*f6dc9357SAndroid Build Coastguard Worker         }
155*f6dc9357SAndroid Build Coastguard Worker         else
156*f6dc9357SAndroid Build Coastguard Worker         {
157*f6dc9357SAndroid Build Coastguard Worker           const int filterId = FilterIdFromName(prop.bstrVal);
158*f6dc9357SAndroid Build Coastguard Worker           if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
159*f6dc9357SAndroid Build Coastguard Worker             return E_INVALIDARG;
160*f6dc9357SAndroid Build Coastguard Worker           id32 = (UInt32)(unsigned)filterId;
161*f6dc9357SAndroid Build Coastguard Worker         }
162*f6dc9357SAndroid Build Coastguard Worker       }
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker       if (id32 == XZ_ID_Delta)
165*f6dc9357SAndroid Build Coastguard Worker       {
166*f6dc9357SAndroid Build Coastguard Worker         const wchar_t c = *name;
167*f6dc9357SAndroid Build Coastguard Worker         if (c != '-' && c != ':')
168*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
169*f6dc9357SAndroid Build Coastguard Worker         name++;
170*f6dc9357SAndroid Build Coastguard Worker         const UInt32 delta = ConvertStringToUInt32(name, &end);
171*f6dc9357SAndroid Build Coastguard Worker         if (end == name || *end != 0 || delta == 0 || delta > 256)
172*f6dc9357SAndroid Build Coastguard Worker           return E_INVALIDARG;
173*f6dc9357SAndroid Build Coastguard Worker         xzProps.filterProps.delta = delta;
174*f6dc9357SAndroid Build Coastguard Worker       }
175*f6dc9357SAndroid Build Coastguard Worker 
176*f6dc9357SAndroid Build Coastguard Worker       xzProps.filterProps.id = id32;
177*f6dc9357SAndroid Build Coastguard Worker     }
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
180*f6dc9357SAndroid Build Coastguard Worker   }
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker   return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props);
183*f6dc9357SAndroid Build Coastguard Worker }
184*f6dc9357SAndroid Build Coastguard Worker 
185*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CEncoder::SetCoderProperties (const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps))186*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CEncoder::SetCoderProperties(const PROPID *propIDs,
187*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT *coderProps, UInt32 numProps))
188*f6dc9357SAndroid Build Coastguard Worker {
189*f6dc9357SAndroid Build Coastguard Worker   XzProps_Init(&xzProps);
190*f6dc9357SAndroid Build Coastguard Worker 
191*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numProps; i++)
192*f6dc9357SAndroid Build Coastguard Worker   {
193*f6dc9357SAndroid Build Coastguard Worker     RINOK(SetCoderProp(propIDs[i], coderProps[i]))
194*f6dc9357SAndroid Build Coastguard Worker   }
195*f6dc9357SAndroid Build Coastguard Worker 
196*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
197*f6dc9357SAndroid Build Coastguard Worker   // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps));
198*f6dc9357SAndroid Build Coastguard Worker }
199*f6dc9357SAndroid Build Coastguard Worker 
200*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt (const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps))201*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
202*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT *coderProps, UInt32 numProps))
203*f6dc9357SAndroid Build Coastguard Worker {
204*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < numProps; i++)
205*f6dc9357SAndroid Build Coastguard Worker   {
206*f6dc9357SAndroid Build Coastguard Worker     const PROPVARIANT &prop = coderProps[i];
207*f6dc9357SAndroid Build Coastguard Worker     const PROPID propID = propIDs[i];
208*f6dc9357SAndroid Build Coastguard Worker     if (propID == NCoderPropID::kExpectedDataSize)
209*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt == VT_UI8)
210*f6dc9357SAndroid Build Coastguard Worker         XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
211*f6dc9357SAndroid Build Coastguard Worker   }
212*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
213*f6dc9357SAndroid Build Coastguard Worker }
214*f6dc9357SAndroid Build Coastguard Worker 
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
217*f6dc9357SAndroid Build Coastguard Worker   if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
218*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CEncoder::Code (ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 *,ICompressProgressInfo * progress))219*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
220*f6dc9357SAndroid Build Coastguard Worker     const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress))
221*f6dc9357SAndroid Build Coastguard Worker {
222*f6dc9357SAndroid Build Coastguard Worker   CSeqInStreamWrap inWrap;
223*f6dc9357SAndroid Build Coastguard Worker   CSeqOutStreamWrap outWrap;
224*f6dc9357SAndroid Build Coastguard Worker   CCompressProgressWrap progressWrap;
225*f6dc9357SAndroid Build Coastguard Worker 
226*f6dc9357SAndroid Build Coastguard Worker   inWrap.Init(inStream);
227*f6dc9357SAndroid Build Coastguard Worker   outWrap.Init(outStream);
228*f6dc9357SAndroid Build Coastguard Worker   progressWrap.Init(progress);
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker   SRes res = XzEnc_SetProps(_encoder, &xzProps);
231*f6dc9357SAndroid Build Coastguard Worker   if (res == SZ_OK)
232*f6dc9357SAndroid Build Coastguard Worker     res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
233*f6dc9357SAndroid Build Coastguard Worker 
234*f6dc9357SAndroid Build Coastguard Worker   // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL);
235*f6dc9357SAndroid Build Coastguard Worker 
236*f6dc9357SAndroid Build Coastguard Worker   RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
237*f6dc9357SAndroid Build Coastguard Worker   RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
238*f6dc9357SAndroid Build Coastguard Worker   RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
239*f6dc9357SAndroid Build Coastguard Worker 
240*f6dc9357SAndroid Build Coastguard Worker   return SResToHRESULT(res);
241*f6dc9357SAndroid Build Coastguard Worker }
242*f6dc9357SAndroid Build Coastguard Worker 
243*f6dc9357SAndroid Build Coastguard Worker }}
244