| 1 | --- a/C/7zip/Compress/LZMA/LZMADecoder.cpp |
| 2 | +++ b/C/7zip/Compress/LZMA/LZMADecoder.cpp |
| 3 | @@ -274,12 +274,17 @@ STDMETHODIMP CDecoder::SetDecoderPropert |
| 4 | Byte remainder = (Byte)(properties[0] / 9); |
| 5 | int lp = remainder % 5; |
| 6 | int pb = remainder / 5; |
| 7 | - if (pb > NLength::kNumPosStatesBitsMax) |
| 8 | - return E_INVALIDARG; |
| 9 | - _posStateMask = (1 << pb) - 1; |
| 10 | UInt32 dictionarySize = 0; |
| 11 | for (int i = 0; i < 4; i++) |
| 12 | dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); |
| 13 | + return SetDecoderPropertiesRaw(lc, lp, pb, dictionarySize); |
| 14 | +} |
| 15 | + |
| 16 | +STDMETHODIMP CDecoder::SetDecoderPropertiesRaw(int lc, int lp, int pb, UInt32 dictionarySize) |
| 17 | +{ |
| 18 | + if (pb > NLength::kNumPosStatesBitsMax) |
| 19 | + return E_INVALIDARG; |
| 20 | + _posStateMask = (1 << pb) - 1; |
| 21 | if (!_outWindowStream.Create(dictionarySize)) |
| 22 | return E_OUTOFMEMORY; |
| 23 | if (!_literalDecoder.Create(lp, lc)) |
| 24 | --- a/C/7zip/Compress/LZMA/LZMADecoder.h |
| 25 | +++ b/C/7zip/Compress/LZMA/LZMADecoder.h |
| 26 | @@ -228,6 +228,7 @@ public: |
| 27 | ICompressProgressInfo *progress); |
| 28 | |
| 29 | STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); |
| 30 | + STDMETHOD(SetDecoderPropertiesRaw)(int lc, int lp, int pb, UInt32 dictionarySize); |
| 31 | |
| 32 | STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); |
| 33 | |
| 34 | --- /dev/null |
| 35 | +++ b/C/7zip/Compress/LZMA_Lib/makefile |
| 36 | @@ -0,0 +1,92 @@ |
| 37 | +PROG = liblzma.a |
| 38 | +CXX = g++ -O3 -Wall |
| 39 | +AR = ar |
| 40 | +RM = rm -f |
| 41 | +CFLAGS = -c -I ../../../ |
| 42 | + |
| 43 | +OBJS = \ |
| 44 | + ZLib.o \ |
| 45 | + LZMADecoder.o \ |
| 46 | + LZMAEncoder.o \ |
| 47 | + LZInWindow.o \ |
| 48 | + LZOutWindow.o \ |
| 49 | + RangeCoderBit.o \ |
| 50 | + InBuffer.o \ |
| 51 | + OutBuffer.o \ |
| 52 | + FileStreams.o \ |
| 53 | + Alloc.o \ |
| 54 | + C_FileIO.o \ |
| 55 | + CommandLineParser.o \ |
| 56 | + CRC.o \ |
| 57 | + StreamUtils.o \ |
| 58 | + String.o \ |
| 59 | + StringConvert.o \ |
| 60 | + StringToInt.o \ |
| 61 | + Vector.o \ |
| 62 | + |
| 63 | + |
| 64 | +all: $(PROG) |
| 65 | + |
| 66 | +$(PROG): $(OBJS) |
| 67 | + $(AR) r $(PROG) $(OBJS) |
| 68 | + |
| 69 | +ZLib.o: ZLib.cpp |
| 70 | + $(CXX) $(CFLAGS) ZLib.cpp |
| 71 | + |
| 72 | +LZMADecoder.o: ../LZMA/LZMADecoder.cpp |
| 73 | + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp |
| 74 | + |
| 75 | +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp |
| 76 | + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp |
| 77 | + |
| 78 | +LZInWindow.o: ../LZ/LZInWindow.cpp |
| 79 | + $(CXX) $(CFLAGS) ../LZ/LZInWindow.cpp |
| 80 | + |
| 81 | +LZOutWindow.o: ../LZ/LZOutWindow.cpp |
| 82 | + $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp |
| 83 | + |
| 84 | +RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp |
| 85 | + $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp |
| 86 | + |
| 87 | +InBuffer.o: ../../Common/InBuffer.cpp |
| 88 | + $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp |
| 89 | + |
| 90 | +OutBuffer.o: ../../Common/OutBuffer.cpp |
| 91 | + $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp |
| 92 | + |
| 93 | +StreamUtils.o: ../../Common/StreamUtils.cpp |
| 94 | + $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp |
| 95 | + |
| 96 | +FileStreams.o: ../../Common/FileStreams.cpp |
| 97 | + $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp |
| 98 | + |
| 99 | +Alloc.o: ../../../Common/Alloc.cpp |
| 100 | + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp |
| 101 | + |
| 102 | +C_FileIO.o: ../../../Common/C_FileIO.cpp |
| 103 | + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp |
| 104 | + |
| 105 | +CommandLineParser.o: ../../../Common/CommandLineParser.cpp |
| 106 | + $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp |
| 107 | + |
| 108 | +CRC.o: ../../../Common/CRC.cpp |
| 109 | + $(CXX) $(CFLAGS) ../../../Common/CRC.cpp |
| 110 | + |
| 111 | +MyWindows.o: ../../../Common/MyWindows.cpp |
| 112 | + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp |
| 113 | + |
| 114 | +String.o: ../../../Common/String.cpp |
| 115 | + $(CXX) $(CFLAGS) ../../../Common/String.cpp |
| 116 | + |
| 117 | +StringConvert.o: ../../../Common/StringConvert.cpp |
| 118 | + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp |
| 119 | + |
| 120 | +StringToInt.o: ../../../Common/StringToInt.cpp |
| 121 | + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp |
| 122 | + |
| 123 | +Vector.o: ../../../Common/Vector.cpp |
| 124 | + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp |
| 125 | + |
| 126 | +clean: |
| 127 | + -$(RM) $(PROG) $(OBJS) |
| 128 | + |
| 129 | --- /dev/null |
| 130 | +++ b/C/7zip/Compress/LZMA_Lib/ZLib.cpp |
| 131 | @@ -0,0 +1,273 @@ |
| 132 | +/* |
| 133 | + * lzma zlib simplified wrapper |
| 134 | + * |
| 135 | + * Copyright (c) 2005-2006 Oleg I. Vdovikin <oleg@cs.msu.su> |
| 136 | + * |
| 137 | + * This library is free software; you can redistribute |
| 138 | + * it and/or modify it under the terms of the GNU Lesser |
| 139 | + * General Public License as published by the Free Software |
| 140 | + * Foundation; either version 2.1 of the License, or |
| 141 | + * (at your option) any later version. |
| 142 | + * |
| 143 | + * This library is distributed in the hope that it will be |
| 144 | + * useful, but WITHOUT ANY WARRANTY; without even the implied |
| 145 | + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 146 | + * PURPOSE. See the GNU Lesser General Public License |
| 147 | + * for more details. |
| 148 | + * |
| 149 | + * You should have received a copy of the GNU Lesser General |
| 150 | + * Public License along with this library; if not, write to |
| 151 | + * the Free Software Foundation, Inc., 59 Temple Place, |
| 152 | + * Suite 330, Boston, MA 02111-1307 USA |
| 153 | + */ |
| 154 | + |
| 155 | +/* |
| 156 | + * default values for encoder/decoder used by wrapper |
| 157 | + */ |
| 158 | + |
| 159 | +#include <zlib.h> |
| 160 | + |
| 161 | +#define ZLIB_LC 3 |
| 162 | +#define ZLIB_LP 0 |
| 163 | +#define ZLIB_PB 2 |
| 164 | + |
| 165 | +#ifdef WIN32 |
| 166 | +#include <initguid.h> |
| 167 | +#else |
| 168 | +#define INITGUID |
| 169 | +#endif |
| 170 | + |
| 171 | +#include "../../../Common/MyWindows.h" |
| 172 | +#include "../LZMA/LZMADecoder.h" |
| 173 | +#include "../LZMA/LZMAEncoder.h" |
| 174 | + |
| 175 | +#define STG_E_SEEKERROR ((HRESULT)0x80030019L) |
| 176 | +#define STG_E_MEDIUMFULL ((HRESULT)0x80030070L) |
| 177 | + |
| 178 | +class CInMemoryStream: |
| 179 | + public IInStream, |
| 180 | + public IStreamGetSize, |
| 181 | + public CMyUnknownImp |
| 182 | +{ |
| 183 | +public: |
| 184 | + CInMemoryStream(const Bytef *data, UInt64 size) : |
| 185 | + m_data(data), m_size(size), m_offset(0) {} |
| 186 | + |
| 187 | + virtual ~CInMemoryStream() {} |
| 188 | + |
| 189 | + MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) |
| 190 | + |
| 191 | + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) |
| 192 | + { |
| 193 | + if (size > m_size - m_offset) |
| 194 | + size = m_size - m_offset; |
| 195 | + |
| 196 | + if (size) { |
| 197 | + memcpy(data, m_data + m_offset, size); |
| 198 | + } |
| 199 | + |
| 200 | + m_offset += size; |
| 201 | + |
| 202 | + if (processedSize) |
| 203 | + *processedSize = size; |
| 204 | + |
| 205 | + return S_OK; |
| 206 | + } |
| 207 | + |
| 208 | + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) |
| 209 | + { |
| 210 | + return Read(data, size, processedSize); |
| 211 | + } |
| 212 | + |
| 213 | + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) |
| 214 | + { |
| 215 | + UInt64 _offset; |
| 216 | + |
| 217 | + if (seekOrigin == STREAM_SEEK_SET) _offset = offset; |
| 218 | + else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset; |
| 219 | + else if (seekOrigin == STREAM_SEEK_END) _offset = m_size; |
| 220 | + else return STG_E_INVALIDFUNCTION; |
| 221 | + |
| 222 | + if (_offset < 0 || _offset > m_size) |
| 223 | + return STG_E_SEEKERROR; |
| 224 | + |
| 225 | + m_offset = _offset; |
| 226 | + |
| 227 | + if (newPosition) |
| 228 | + *newPosition = m_offset; |
| 229 | + |
| 230 | + return S_OK; |
| 231 | + } |
| 232 | + |
| 233 | + STDMETHOD(GetSize)(UInt64 *size) |
| 234 | + { |
| 235 | + *size = m_size; |
| 236 | + return S_OK; |
| 237 | + } |
| 238 | +protected: |
| 239 | + const Bytef *m_data; |
| 240 | + UInt64 m_size; |
| 241 | + UInt64 m_offset; |
| 242 | +}; |
| 243 | + |
| 244 | +class COutMemoryStream: |
| 245 | + public IOutStream, |
| 246 | + public CMyUnknownImp |
| 247 | +{ |
| 248 | +public: |
| 249 | + COutMemoryStream(Bytef *data, UInt64 maxsize) : |
| 250 | + m_data(data), m_size(0), m_maxsize(maxsize), m_offset(0) {} |
| 251 | + virtual ~COutMemoryStream() {} |
| 252 | + |
| 253 | + MY_UNKNOWN_IMP1(IOutStream) |
| 254 | + |
| 255 | + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) |
| 256 | + { |
| 257 | + if (size > m_maxsize - m_offset) |
| 258 | + size = m_maxsize - m_offset; |
| 259 | + |
| 260 | + if (size) { |
| 261 | + memcpy(m_data + m_offset, data, size); |
| 262 | + } |
| 263 | + |
| 264 | + m_offset += size; |
| 265 | + |
| 266 | + if (m_offset > m_size) |
| 267 | + m_size = m_offset; |
| 268 | + |
| 269 | + if (processedSize) |
| 270 | + *processedSize = size; |
| 271 | + |
| 272 | + return S_OK; |
| 273 | + } |
| 274 | + |
| 275 | + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) |
| 276 | + { |
| 277 | + return Write(data, size, processedSize); |
| 278 | + } |
| 279 | + |
| 280 | + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) |
| 281 | + { |
| 282 | + UInt64 _offset; |
| 283 | + |
| 284 | + if (seekOrigin == STREAM_SEEK_SET) _offset = offset; |
| 285 | + else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset; |
| 286 | + else if (seekOrigin == STREAM_SEEK_END) _offset = m_size; |
| 287 | + else return STG_E_INVALIDFUNCTION; |
| 288 | + |
| 289 | + if (_offset < 0 || _offset > m_maxsize) |
| 290 | + return STG_E_SEEKERROR; |
| 291 | + |
| 292 | + m_offset = _offset; |
| 293 | + |
| 294 | + if (newPosition) |
| 295 | + *newPosition = m_offset; |
| 296 | + |
| 297 | + return S_OK; |
| 298 | + } |
| 299 | + |
| 300 | + STDMETHOD(SetSize)(Int64 newSize) |
| 301 | + { |
| 302 | + if ((UInt64)newSize > m_maxsize) |
| 303 | + return STG_E_MEDIUMFULL; |
| 304 | + |
| 305 | + return S_OK; |
| 306 | + } |
| 307 | +protected: |
| 308 | + Bytef *m_data; |
| 309 | + UInt64 m_size; |
| 310 | + UInt64 m_maxsize; |
| 311 | + UInt64 m_offset; |
| 312 | +}; |
| 313 | + |
| 314 | +ZEXTERN int ZEXPORT compress2 (Bytef *dest, uLongf *destLen, |
| 315 | + const Bytef *source, uLong sourceLen, |
| 316 | + int level) |
| 317 | +{ |
| 318 | + CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen); |
| 319 | + CMyComPtr<ISequentialInStream> inStream = inStreamSpec; |
| 320 | + |
| 321 | + COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen); |
| 322 | + CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; |
| 323 | + |
| 324 | + NCompress::NLZMA::CEncoder *encoderSpec = |
| 325 | + new NCompress::NLZMA::CEncoder; |
| 326 | + CMyComPtr<ICompressCoder> encoder = encoderSpec; |
| 327 | + |
| 328 | + PROPID propIDs[] = |
| 329 | + { |
| 330 | + NCoderPropID::kDictionarySize, |
| 331 | + NCoderPropID::kPosStateBits, |
| 332 | + NCoderPropID::kLitContextBits, |
| 333 | + NCoderPropID::kLitPosBits, |
| 334 | + NCoderPropID::kAlgorithm, |
| 335 | + NCoderPropID::kNumFastBytes, |
| 336 | + NCoderPropID::kMatchFinder, |
| 337 | + NCoderPropID::kEndMarker |
| 338 | + }; |
| 339 | + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); |
| 340 | + |
| 341 | + PROPVARIANT properties[kNumProps]; |
| 342 | + for (int p = 0; p < 6; p++) |
| 343 | + properties[p].vt = VT_UI4; |
| 344 | + properties[0].ulVal = UInt32(1 << (level + 14)); |
| 345 | + properties[1].ulVal = UInt32(ZLIB_PB); |
| 346 | + properties[2].ulVal = UInt32(ZLIB_LC); // for normal files |
| 347 | + properties[3].ulVal = UInt32(ZLIB_LP); // for normal files |
| 348 | + properties[4].ulVal = UInt32(2); |
| 349 | + properties[5].ulVal = UInt32(128); |
| 350 | + |
| 351 | + properties[6].vt = VT_BSTR; |
| 352 | + properties[6].bstrVal = (BSTR)(const wchar_t *)L"BT4"; |
| 353 | + |
| 354 | + properties[7].vt = VT_BOOL; |
| 355 | + properties[7].boolVal = VARIANT_TRUE; |
| 356 | + |
| 357 | + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) |
| 358 | + return Z_MEM_ERROR; // should not happen |
| 359 | + |
| 360 | + HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0); |
| 361 | + if (result == E_OUTOFMEMORY) |
| 362 | + { |
| 363 | + return Z_MEM_ERROR; |
| 364 | + } |
| 365 | + else if (result != S_OK) |
| 366 | + { |
| 367 | + return Z_BUF_ERROR; // should not happen |
| 368 | + } |
| 369 | + |
| 370 | + UInt64 fileSize; |
| 371 | + outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize); |
| 372 | + *destLen = fileSize; |
| 373 | + |
| 374 | + return Z_OK; |
| 375 | +} |
| 376 | + |
| 377 | +ZEXTERN int ZEXPORT uncompress (Bytef *dest, uLongf *destLen, |
| 378 | + const Bytef *source, uLong sourceLen) |
| 379 | +{ |
| 380 | + CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen); |
| 381 | + CMyComPtr<ISequentialInStream> inStream = inStreamSpec; |
| 382 | + |
| 383 | + COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen); |
| 384 | + CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; |
| 385 | + |
| 386 | + NCompress::NLZMA::CDecoder *decoderSpec = |
| 387 | + new NCompress::NLZMA::CDecoder; |
| 388 | + CMyComPtr<ICompressCoder> decoder = decoderSpec; |
| 389 | + |
| 390 | + if (decoderSpec->SetDecoderPropertiesRaw(ZLIB_LC, |
| 391 | + ZLIB_LP, ZLIB_PB, (1 << 23)) != S_OK) return Z_DATA_ERROR; |
| 392 | + |
| 393 | + UInt64 fileSize = *destLen; |
| 394 | + |
| 395 | + if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK) |
| 396 | + { |
| 397 | + return Z_DATA_ERROR; |
| 398 | + } |
| 399 | + |
| 400 | + outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize); |
| 401 | + *destLen = fileSize; |
| 402 | + |
| 403 | + return Z_OK; |
| 404 | +} |
| 405 | |