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