diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-03-29 16:04:01 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-03-29 16:04:01 +0100 |
commit | 88083f8c683c18f4de68a20c863a82a9da65db8f (patch) | |
tree | 926656892d9d80260da02ea8ea71031b140c51df /other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp | |
parent | f999f544aad04069b03704d994a99352263f600b (diff) | |
parent | 843e4ceffd6ce21a6e6db37419335eafdc543e18 (diff) | |
download | UXP-88083f8c683c18f4de68a20c863a82a9da65db8f.tar UXP-88083f8c683c18f4de68a20c863a82a9da65db8f.tar.gz UXP-88083f8c683c18f4de68a20c863a82a9da65db8f.tar.lz UXP-88083f8c683c18f4de68a20c863a82a9da65db8f.tar.xz UXP-88083f8c683c18f4de68a20c863a82a9da65db8f.zip |
Merge branch 'master' into Sync-weave
Diffstat (limited to 'other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp')
-rw-r--r-- | other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp new file mode 100644 index 000000000..3151c3d21 --- /dev/null +++ b/other-licenses/7zstub/src/CPP/7zip/Compress/LzmaEncoder.cpp @@ -0,0 +1,182 @@ +// LzmaEncoder.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/Alloc.h"
+
+#include "../Common/CWrappers.h"
+#include "../Common/StreamUtils.h"
+
+#include "LzmaEncoder.h"
+
+namespace NCompress {
+namespace NLzma {
+
+CEncoder::CEncoder()
+{
+ _encoder = NULL;
+ _encoder = LzmaEnc_Create(&g_AlignedAlloc);
+ if (!_encoder)
+ throw 1;
+}
+
+CEncoder::~CEncoder()
+{
+ if (_encoder)
+ LzmaEnc_Destroy(_encoder, &g_AlignedAlloc, &g_BigAlloc);
+}
+
+static inline wchar_t GetUpperChar(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ return c;
+}
+
+static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
+{
+ wchar_t c = GetUpperChar(*s++);
+ if (c == L'H')
+ {
+ if (GetUpperChar(*s++) != L'C')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
+ return 0;
+ if (*s != 0)
+ return 0;
+ *btMode = 0;
+ *numHashBytes = numHashBytesLoc;
+ return 1;
+ }
+
+ if (c != L'B')
+ return 0;
+ if (GetUpperChar(*s++) != L'T')
+ return 0;
+ int numHashBytesLoc = (int)(*s++ - L'0');
+ if (numHashBytesLoc < 2 || numHashBytesLoc > 4)
+ return 0;
+ if (*s != 0)
+ return 0;
+ *btMode = 1;
+ *numHashBytes = numHashBytesLoc;
+ return 1;
+}
+
+#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
+
+HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
+{
+ if (propID == NCoderPropID::kMatchFinder)
+ {
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
+ }
+
+ if (propID > NCoderPropID::kReduceSize)
+ return S_OK;
+
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8)
+ ep.reduceSize = prop.uhVal.QuadPart;
+ else
+ return E_INVALIDARG;
+ return S_OK;
+ }
+
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = prop.ulVal;
+ switch (propID)
+ {
+ case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break;
+ SET_PROP_32(kLevel, level)
+ SET_PROP_32(kNumFastBytes, fb)
+ SET_PROP_32(kMatchFinderCycles, mc)
+ SET_PROP_32(kAlgorithm, algo)
+ SET_PROP_32(kDictionarySize, dictSize)
+ SET_PROP_32(kPosStateBits, pb)
+ SET_PROP_32(kLitPosBits, lp)
+ SET_PROP_32(kLitContextBits, lc)
+ SET_PROP_32(kNumThreads, numThreads)
+ default: return E_INVALIDARG;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ switch (propID)
+ {
+ case NCoderPropID::kEndMarker:
+ if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal != VARIANT_FALSE); break;
+ default:
+ RINOK(SetLzmaProp(propID, prop, props));
+ }
+ }
+ return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props));
+}
+
+
+STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
+ const PROPVARIANT *coderProps, UInt32 numProps)
+{
+ for (UInt32 i = 0; i < numProps; i++)
+ {
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID == NCoderPropID::kExpectedDataSize)
+ if (prop.vt == VT_UI8)
+ LzmaEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ Byte props[LZMA_PROPS_SIZE];
+ size_t size = LZMA_PROPS_SIZE;
+ RINOK(LzmaEnc_WriteProperties(_encoder, props, &size));
+ return WriteStream(outStream, props, size);
+}
+
+
+#define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
+ if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
+{
+ CSeqInStreamWrap inWrap;
+ CSeqOutStreamWrap outWrap;
+ CCompressProgressWrap progressWrap;
+
+ inWrap.Init(inStream);
+ outWrap.Init(outStream);
+ progressWrap.Init(progress);
+
+ SRes res = LzmaEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt,
+ progress ? &progressWrap.vt : NULL, &g_AlignedAlloc, &g_BigAlloc);
+
+ _inputProcessed = inWrap.Processed;
+
+ RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
+ RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
+ RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
+
+ return SResToHRESULT(res);
+}
+
+}}
|