1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// LzmaEncoder.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/Alloc.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/CWrappers.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/StreamUtils.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "LzmaEncoder.h" 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NCompress { 13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NLzma { 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 15baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); } 16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SzBigFree(void *, void *address) { BigFree(address); } 17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void *SzAlloc(void *, size_t size) { return MyAlloc(size); } 20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SzFree(void *, void *address) { MyFree(address); } 21baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic ISzAlloc g_Alloc = { SzAlloc, SzFree }; 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 23baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCEncoder::CEncoder() 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _encoder = 0; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _encoder = LzmaEnc_Create(&g_Alloc); 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_encoder == 0) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw 1; 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 31baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCEncoder::~CEncoder() 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_encoder != 0) 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LzmaEnc_Destroy(_encoder, &g_Alloc, &g_BigAlloc); 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 37baa3858d3f5d128a5c8466b700098109edcad5f2repo syncinline wchar_t GetUpperChar(wchar_t c) 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c >= 'a' && c <= 'z') 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c -= 0x20; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return c; 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 44baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes) 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t c = GetUpperChar(*s++); 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c == L'H') 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (GetUpperChar(*s++) != L'C') 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numHashBytesLoc = (int)(*s++ - L'0'); 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numHashBytesLoc < 4 || numHashBytesLoc > 4) 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (*s++ != 0) 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *btMode = 0; 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *numHashBytes = numHashBytesLoc; 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c != L'B') 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (GetUpperChar(*s++) != L'T') 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numHashBytesLoc = (int)(*s++ - L'0'); 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numHashBytesLoc < 2 || numHashBytesLoc > 4) 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = GetUpperChar(*s++); 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c != L'\0') 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *btMode = 1; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *numHashBytes = numHashBytesLoc; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 76baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep) 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (propID == NCoderPropID::kMatchFinder) 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_BSTR) 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_UI4) 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 v = prop.ulVal; 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch (propID) 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kNumFastBytes: ep.fb = v; break; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kMatchFinderCycles: ep.mc = v; break; 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kAlgorithm: ep.algo = v; break; 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kDictionarySize: ep.dictSize = v; break; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kPosStateBits: ep.pb = v; break; 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kLitPosBits: ep.lp = v; break; 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kLitContextBits: ep.lc = v; break; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: return E_INVALIDARG; 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 101baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const PROPVARIANT *coderProps, UInt32 numProps) 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CLzmaEncProps props; 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LzmaEncProps_Init(&props); 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < numProps; i++) 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const PROPVARIANT &prop = coderProps[i]; 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync PROPID propID = propIDs[i]; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch (propID) 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kEndMarker: 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break; 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NCoderPropID::kNumThreads: 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break; 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SetLzmaProp(propID, prop, props)); 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props)); 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 124baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte props[LZMA_PROPS_SIZE]; 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t size = LZMA_PROPS_SIZE; 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(LzmaEnc_WriteProperties(_encoder, props, &size)); 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return WriteStream(outStream, props, size); 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 132baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSeqInStreamWrap inWrap(inStream); 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSeqOutStreamWrap outWrap(outStream); 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCompressProgressWrap progressWrap(progress); 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc); 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_ERROR_READ && inWrap.Res != S_OK) 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return inWrap.Res; 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK) 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return outWrap.Res; 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK) 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return progressWrap.Res; 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return SResToHRESULT(res); 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 150