• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Lzma2Encoder.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../C/Alloc.h"
6 
7 #include "../Common/CWrappers.h"
8 #include "../Common/StreamUtils.h"
9 
10 #include "Lzma2Encoder.h"
11 
12 namespace NCompress {
13 
14 namespace NLzma {
15 
16 HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep);
17 
18 }
19 
20 namespace NLzma2 {
21 
CEncoder()22 CEncoder::CEncoder()
23 {
24   _encoder = NULL;
25   _encoder = Lzma2Enc_Create(&g_AlignedAlloc, &g_BigAlloc);
26   if (!_encoder)
27     throw 1;
28 }
29 
~CEncoder()30 CEncoder::~CEncoder()
31 {
32   if (_encoder)
33     Lzma2Enc_Destroy(_encoder);
34 }
35 
36 
SetLzma2Prop(PROPID propID,const PROPVARIANT & prop,CLzma2EncProps & lzma2Props)37 HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)
38 {
39   switch (propID)
40   {
41     case NCoderPropID::kBlockSize:
42     {
43       if (prop.vt == VT_UI4)
44         lzma2Props.blockSize = prop.ulVal;
45       else if (prop.vt == VT_UI8)
46         lzma2Props.blockSize = prop.uhVal.QuadPart;
47       else
48         return E_INVALIDARG;
49       break;
50     }
51     case NCoderPropID::kNumThreads:
52       if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;
53     default:
54       RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps));
55   }
56   return S_OK;
57 }
58 
59 
SetCoderProperties(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)60 STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
61     const PROPVARIANT *coderProps, UInt32 numProps)
62 {
63   CLzma2EncProps lzma2Props;
64   Lzma2EncProps_Init(&lzma2Props);
65 
66   for (UInt32 i = 0; i < numProps; i++)
67   {
68     RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props));
69   }
70   return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
71 }
72 
73 
SetCoderPropertiesOpt(const PROPID * propIDs,const PROPVARIANT * coderProps,UInt32 numProps)74 STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
75     const PROPVARIANT *coderProps, UInt32 numProps)
76 {
77   for (UInt32 i = 0; i < numProps; i++)
78   {
79     const PROPVARIANT &prop = coderProps[i];
80     PROPID propID = propIDs[i];
81     if (propID == NCoderPropID::kExpectedDataSize)
82       if (prop.vt == VT_UI8)
83         Lzma2Enc_SetDataSize(_encoder, prop.uhVal.QuadPart);
84   }
85   return S_OK;
86 }
87 
88 
WriteCoderProperties(ISequentialOutStream * outStream)89 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
90 {
91   Byte prop = Lzma2Enc_WriteProperties(_encoder);
92   return WriteStream(outStream, &prop, 1);
93 }
94 
95 
96 #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
97   if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
98 
Code(ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 *,ICompressProgressInfo * progress)99 STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
100     const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
101 {
102   CSeqInStreamWrap inWrap;
103   CSeqOutStreamWrap outWrap;
104   CCompressProgressWrap progressWrap;
105 
106   inWrap.Init(inStream);
107   outWrap.Init(outStream);
108   progressWrap.Init(progress);
109 
110   SRes res = Lzma2Enc_Encode2(_encoder,
111       &outWrap.vt, NULL, NULL,
112       &inWrap.vt, NULL, 0,
113       progress ? &progressWrap.vt : NULL);
114 
115   RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
116   RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
117   RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
118 
119   return SResToHRESULT(res);
120 }
121 
122 }}
123