2 * lzma zlib simplified wrapper
4 * Copyright (c) 2005-2006 Oleg I. Vdovikin <oleg@cs.msu.su>
6 * This library is free software; you can redistribute
7 * it and/or modify it under the terms of the GNU Lesser
8 * General Public License as published by the Free Software
9 * Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be
13 * useful, but WITHOUT ANY WARRANTY; without even the implied
14 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License
18 * You should have received a copy of the GNU Lesser General
19 * Public License along with this library; if not, write to
20 * the Free Software Foundation, Inc., 59 Temple Place,
21 * Suite 330, Boston, MA 02111-1307 USA
25 * default values for encoder/decoder used by wrapper
40 #include "../../../Common/MyWindows.h"
41 #include "../LZMA/LZMADecoder.h"
42 #include "../LZMA/LZMAEncoder.h"
44 #define STG_E_SEEKERROR ((HRESULT)0x80030019L)
45 #define STG_E_MEDIUMFULL ((HRESULT)0x80030070L)
47 class CInMemoryStream
:
49 public IStreamGetSize
,
53 CInMemoryStream(const Bytef
*data
, UInt64 size
) :
54 m_data(data
), m_size(size
), m_offset(0) {}
56 virtual ~CInMemoryStream() {}
58 MY_UNKNOWN_IMP2(IInStream
, IStreamGetSize
)
60 STDMETHOD(Read
)(void *data
, UInt32 size
, UInt32
*processedSize
)
62 if (size
> m_size
- m_offset
)
63 size
= m_size
- m_offset
;
66 memcpy(data
, m_data
+ m_offset
, size
);
72 *processedSize
= size
;
77 STDMETHOD(ReadPart
)(void *data
, UInt32 size
, UInt32
*processedSize
)
79 return Read(data
, size
, processedSize
);
82 STDMETHOD(Seek
)(Int64 offset
, UInt32 seekOrigin
, UInt64
*newPosition
)
86 if (seekOrigin
== STREAM_SEEK_SET
) _offset
= offset
;
87 else if (seekOrigin
== STREAM_SEEK_CUR
) _offset
= m_offset
+ offset
;
88 else if (seekOrigin
== STREAM_SEEK_END
) _offset
= m_size
;
89 else return STG_E_INVALIDFUNCTION
;
91 if (_offset
< 0 || _offset
> m_size
)
92 return STG_E_SEEKERROR
;
97 *newPosition
= m_offset
;
102 STDMETHOD(GetSize
)(UInt64
*size
)
113 class COutMemoryStream
:
118 COutMemoryStream(Bytef
*data
, UInt64 maxsize
) :
119 m_data(data
), m_size(0), m_maxsize(maxsize
), m_offset(0) {}
120 virtual ~COutMemoryStream() {}
122 MY_UNKNOWN_IMP1(IOutStream
)
124 STDMETHOD(Write
)(const void *data
, UInt32 size
, UInt32
*processedSize
)
126 if (size
> m_maxsize
- m_offset
)
127 size
= m_maxsize
- m_offset
;
130 memcpy(m_data
+ m_offset
, data
, size
);
135 if (m_offset
> m_size
)
139 *processedSize
= size
;
144 STDMETHOD(WritePart
)(const void *data
, UInt32 size
, UInt32
*processedSize
)
146 return Write(data
, size
, processedSize
);
149 STDMETHOD(Seek
)(Int64 offset
, UInt32 seekOrigin
, UInt64
*newPosition
)
153 if (seekOrigin
== STREAM_SEEK_SET
) _offset
= offset
;
154 else if (seekOrigin
== STREAM_SEEK_CUR
) _offset
= m_offset
+ offset
;
155 else if (seekOrigin
== STREAM_SEEK_END
) _offset
= m_size
;
156 else return STG_E_INVALIDFUNCTION
;
158 if (_offset
< 0 || _offset
> m_maxsize
)
159 return STG_E_SEEKERROR
;
164 *newPosition
= m_offset
;
169 STDMETHOD(SetSize
)(Int64 newSize
)
171 if ((UInt64
)newSize
> m_maxsize
)
172 return STG_E_MEDIUMFULL
;
183 ZEXTERN
int ZEXPORT compress2
OF((Bytef
*dest
, uLongf
*destLen
,
184 const Bytef
*source
, uLong sourceLen
,
187 CInMemoryStream
*inStreamSpec
= new CInMemoryStream(source
, sourceLen
);
188 CMyComPtr
<ISequentialInStream
> inStream
= inStreamSpec
;
190 COutMemoryStream
*outStreamSpec
= new COutMemoryStream(dest
, *destLen
);
191 CMyComPtr
<ISequentialOutStream
> outStream
= outStreamSpec
;
193 NCompress::NLZMA::CEncoder
*encoderSpec
=
194 new NCompress::NLZMA::CEncoder
;
195 CMyComPtr
<ICompressCoder
> encoder
= encoderSpec
;
199 NCoderPropID::kDictionarySize
,
200 NCoderPropID::kPosStateBits
,
201 NCoderPropID::kLitContextBits
,
202 NCoderPropID::kLitPosBits
,
203 NCoderPropID::kAlgorithm
,
204 NCoderPropID::kNumFastBytes
,
205 NCoderPropID::kMatchFinder
,
206 NCoderPropID::kEndMarker
208 const int kNumProps
= sizeof(propIDs
) / sizeof(propIDs
[0]);
210 PROPVARIANT properties
[kNumProps
];
211 for (int p
= 0; p
< 6; p
++)
212 properties
[p
].vt
= VT_UI4
;
213 properties
[0].ulVal
= UInt32(1 << (level
+ 14));
214 properties
[1].ulVal
= UInt32(ZLIB_PB
);
215 properties
[2].ulVal
= UInt32(ZLIB_LC
); // for normal files
216 properties
[3].ulVal
= UInt32(ZLIB_LP
); // for normal files
217 properties
[4].ulVal
= UInt32(2);
218 properties
[5].ulVal
= UInt32(128);
220 properties
[6].vt
= VT_BSTR
;
221 properties
[6].bstrVal
= (BSTR
)(const wchar_t *)L
"BT4";
223 properties
[7].vt
= VT_BOOL
;
224 properties
[7].boolVal
= VARIANT_TRUE
;
226 if (encoderSpec
->SetCoderProperties(propIDs
, properties
, kNumProps
) != S_OK
)
227 return Z_MEM_ERROR
; // should not happen
229 HRESULT result
= encoder
->Code(inStream
, outStream
, 0, 0, 0);
230 if (result
== E_OUTOFMEMORY
)
234 else if (result
!= S_OK
)
236 return Z_BUF_ERROR
; // should not happen
240 outStreamSpec
->Seek(0, STREAM_SEEK_END
, &fileSize
);
246 ZEXTERN
int ZEXPORT uncompress
OF((Bytef
*dest
, uLongf
*destLen
,
247 const Bytef
*source
, uLong sourceLen
))
249 CInMemoryStream
*inStreamSpec
= new CInMemoryStream(source
, sourceLen
);
250 CMyComPtr
<ISequentialInStream
> inStream
= inStreamSpec
;
252 COutMemoryStream
*outStreamSpec
= new COutMemoryStream(dest
, *destLen
);
253 CMyComPtr
<ISequentialOutStream
> outStream
= outStreamSpec
;
255 NCompress::NLZMA::CDecoder
*decoderSpec
=
256 new NCompress::NLZMA::CDecoder
;
257 CMyComPtr
<ICompressCoder
> decoder
= decoderSpec
;
259 if (decoderSpec
->SetDecoderPropertiesRaw(ZLIB_LC
,
260 ZLIB_LP
, ZLIB_PB
, (1 << 23)) != S_OK
) return Z_DATA_ERROR
;
262 UInt64 fileSize
= *destLen
;
264 if (decoder
->Code(inStream
, outStream
, 0, &fileSize
, 0) != S_OK
)
269 outStreamSpec
->Seek(0, STREAM_SEEK_END
, &fileSize
);