| --- a/C/7zip/Compress/LZMA/LZMADecoder.cpp |
| +++ b/C/7zip/Compress/LZMA/LZMADecoder.cpp |
| @@ -274,12 +274,17 @@ STDMETHODIMP CDecoder::SetDecoderPropert |
| Byte remainder = (Byte)(properties[0] / 9); |
| int lp = remainder % 5; |
| int pb = remainder / 5; |
| - if (pb > NLength::kNumPosStatesBitsMax) |
| - return E_INVALIDARG; |
| - _posStateMask = (1 << pb) - 1; |
| UInt32 dictionarySize = 0; |
| for (int i = 0; i < 4; i++) |
| dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); |
| + return SetDecoderPropertiesRaw(lc, lp, pb, dictionarySize); |
| +} |
| + |
| +STDMETHODIMP CDecoder::SetDecoderPropertiesRaw(int lc, int lp, int pb, UInt32 dictionarySize) |
| +{ |
| + if (pb > NLength::kNumPosStatesBitsMax) |
| + return E_INVALIDARG; |
| + _posStateMask = (1 << pb) - 1; |
| if (!_outWindowStream.Create(dictionarySize)) |
| return E_OUTOFMEMORY; |
| if (!_literalDecoder.Create(lp, lc)) |
| --- a/C/7zip/Compress/LZMA/LZMADecoder.h |
| +++ b/C/7zip/Compress/LZMA/LZMADecoder.h |
| @@ -228,6 +228,7 @@ public: |
| ICompressProgressInfo *progress); |
| |
| STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); |
| + STDMETHOD(SetDecoderPropertiesRaw)(int lc, int lp, int pb, UInt32 dictionarySize); |
| |
| STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); |
| |
| --- /dev/null |
| +++ b/C/7zip/Compress/LZMA_Lib/makefile |
| @@ -0,0 +1,92 @@ |
| +PROG = liblzma.a |
| +CXX = g++ -O3 -Wall |
| +AR = ar |
| +RM = rm -f |
| +CFLAGS = -c -I ../../../ |
| + |
| +OBJS = \ |
| + ZLib.o \ |
| + LZMADecoder.o \ |
| + LZMAEncoder.o \ |
| + LZInWindow.o \ |
| + LZOutWindow.o \ |
| + RangeCoderBit.o \ |
| + InBuffer.o \ |
| + OutBuffer.o \ |
| + FileStreams.o \ |
| + Alloc.o \ |
| + C_FileIO.o \ |
| + CommandLineParser.o \ |
| + CRC.o \ |
| + StreamUtils.o \ |
| + String.o \ |
| + StringConvert.o \ |
| + StringToInt.o \ |
| + Vector.o \ |
| + |
| + |
| +all: $(PROG) |
| + |
| +$(PROG): $(OBJS) |
| + $(AR) r $(PROG) $(OBJS) |
| + |
| +ZLib.o: ZLib.cpp |
| + $(CXX) $(CFLAGS) ZLib.cpp |
| + |
| +LZMADecoder.o: ../LZMA/LZMADecoder.cpp |
| + $(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp |
| + |
| +LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp |
| + $(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp |
| + |
| +LZInWindow.o: ../LZ/LZInWindow.cpp |
| + $(CXX) $(CFLAGS) ../LZ/LZInWindow.cpp |
| + |
| +LZOutWindow.o: ../LZ/LZOutWindow.cpp |
| + $(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp |
| + |
| +RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp |
| + $(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp |
| + |
| +InBuffer.o: ../../Common/InBuffer.cpp |
| + $(CXX) $(CFLAGS) ../../Common/InBuffer.cpp |
| + |
| +OutBuffer.o: ../../Common/OutBuffer.cpp |
| + $(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp |
| + |
| +StreamUtils.o: ../../Common/StreamUtils.cpp |
| + $(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp |
| + |
| +FileStreams.o: ../../Common/FileStreams.cpp |
| + $(CXX) $(CFLAGS) ../../Common/FileStreams.cpp |
| + |
| +Alloc.o: ../../../Common/Alloc.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/Alloc.cpp |
| + |
| +C_FileIO.o: ../../../Common/C_FileIO.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/C_FileIO.cpp |
| + |
| +CommandLineParser.o: ../../../Common/CommandLineParser.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp |
| + |
| +CRC.o: ../../../Common/CRC.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/CRC.cpp |
| + |
| +MyWindows.o: ../../../Common/MyWindows.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp |
| + |
| +String.o: ../../../Common/String.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/String.cpp |
| + |
| +StringConvert.o: ../../../Common/StringConvert.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp |
| + |
| +StringToInt.o: ../../../Common/StringToInt.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp |
| + |
| +Vector.o: ../../../Common/Vector.cpp |
| + $(CXX) $(CFLAGS) ../../../Common/Vector.cpp |
| + |
| +clean: |
| + -$(RM) $(PROG) $(OBJS) |
| + |
| --- /dev/null |
| +++ b/C/7zip/Compress/LZMA_Lib/ZLib.cpp |
| @@ -0,0 +1,273 @@ |
| +/* |
| + * lzma zlib simplified wrapper |
| + * |
| + * Copyright (c) 2005-2006 Oleg I. Vdovikin <oleg@cs.msu.su> |
| + * |
| + * This library is free software; you can redistribute |
| + * it and/or modify it under the terms of the GNU Lesser |
| + * General Public License as published by the Free Software |
| + * Foundation; either version 2.1 of the License, or |
| + * (at your option) any later version. |
| + * |
| + * This library is distributed in the hope that it will be |
| + * useful, but WITHOUT ANY WARRANTY; without even the implied |
| + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| + * PURPOSE. See the GNU Lesser General Public License |
| + * for more details. |
| + * |
| + * You should have received a copy of the GNU Lesser General |
| + * Public License along with this library; if not, write to |
| + * the Free Software Foundation, Inc., 59 Temple Place, |
| + * Suite 330, Boston, MA 02111-1307 USA |
| + */ |
| + |
| +/* |
| + * default values for encoder/decoder used by wrapper |
| + */ |
| + |
| +#include <zlib.h> |
| + |
| +#define ZLIB_LC 3 |
| +#define ZLIB_LP 0 |
| +#define ZLIB_PB 2 |
| + |
| +#ifdef WIN32 |
| +#include <initguid.h> |
| +#else |
| +#define INITGUID |
| +#endif |
| + |
| +#include "../../../Common/MyWindows.h" |
| +#include "../LZMA/LZMADecoder.h" |
| +#include "../LZMA/LZMAEncoder.h" |
| + |
| +#define STG_E_SEEKERROR ((HRESULT)0x80030019L) |
| +#define STG_E_MEDIUMFULL ((HRESULT)0x80030070L) |
| + |
| +class CInMemoryStream: |
| + public IInStream, |
| + public IStreamGetSize, |
| + public CMyUnknownImp |
| +{ |
| +public: |
| + CInMemoryStream(const Bytef *data, UInt64 size) : |
| + m_data(data), m_size(size), m_offset(0) {} |
| + |
| + virtual ~CInMemoryStream() {} |
| + |
| + MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) |
| + |
| + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) |
| + { |
| + if (size > m_size - m_offset) |
| + size = m_size - m_offset; |
| + |
| + if (size) { |
| + memcpy(data, m_data + m_offset, size); |
| + } |
| + |
| + m_offset += size; |
| + |
| + if (processedSize) |
| + *processedSize = size; |
| + |
| + return S_OK; |
| + } |
| + |
| + STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) |
| + { |
| + return Read(data, size, processedSize); |
| + } |
| + |
| + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) |
| + { |
| + UInt64 _offset; |
| + |
| + if (seekOrigin == STREAM_SEEK_SET) _offset = offset; |
| + else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset; |
| + else if (seekOrigin == STREAM_SEEK_END) _offset = m_size; |
| + else return STG_E_INVALIDFUNCTION; |
| + |
| + if (_offset < 0 || _offset > m_size) |
| + return STG_E_SEEKERROR; |
| + |
| + m_offset = _offset; |
| + |
| + if (newPosition) |
| + *newPosition = m_offset; |
| + |
| + return S_OK; |
| + } |
| + |
| + STDMETHOD(GetSize)(UInt64 *size) |
| + { |
| + *size = m_size; |
| + return S_OK; |
| + } |
| +protected: |
| + const Bytef *m_data; |
| + UInt64 m_size; |
| + UInt64 m_offset; |
| +}; |
| + |
| +class COutMemoryStream: |
| + public IOutStream, |
| + public CMyUnknownImp |
| +{ |
| +public: |
| + COutMemoryStream(Bytef *data, UInt64 maxsize) : |
| + m_data(data), m_size(0), m_maxsize(maxsize), m_offset(0) {} |
| + virtual ~COutMemoryStream() {} |
| + |
| + MY_UNKNOWN_IMP1(IOutStream) |
| + |
| + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) |
| + { |
| + if (size > m_maxsize - m_offset) |
| + size = m_maxsize - m_offset; |
| + |
| + if (size) { |
| + memcpy(m_data + m_offset, data, size); |
| + } |
| + |
| + m_offset += size; |
| + |
| + if (m_offset > m_size) |
| + m_size = m_offset; |
| + |
| + if (processedSize) |
| + *processedSize = size; |
| + |
| + return S_OK; |
| + } |
| + |
| + STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) |
| + { |
| + return Write(data, size, processedSize); |
| + } |
| + |
| + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) |
| + { |
| + UInt64 _offset; |
| + |
| + if (seekOrigin == STREAM_SEEK_SET) _offset = offset; |
| + else if (seekOrigin == STREAM_SEEK_CUR) _offset = m_offset + offset; |
| + else if (seekOrigin == STREAM_SEEK_END) _offset = m_size; |
| + else return STG_E_INVALIDFUNCTION; |
| + |
| + if (_offset < 0 || _offset > m_maxsize) |
| + return STG_E_SEEKERROR; |
| + |
| + m_offset = _offset; |
| + |
| + if (newPosition) |
| + *newPosition = m_offset; |
| + |
| + return S_OK; |
| + } |
| + |
| + STDMETHOD(SetSize)(Int64 newSize) |
| + { |
| + if ((UInt64)newSize > m_maxsize) |
| + return STG_E_MEDIUMFULL; |
| + |
| + return S_OK; |
| + } |
| +protected: |
| + Bytef *m_data; |
| + UInt64 m_size; |
| + UInt64 m_maxsize; |
| + UInt64 m_offset; |
| +}; |
| + |
| +ZEXTERN int ZEXPORT compress2 (Bytef *dest, uLongf *destLen, |
| + const Bytef *source, uLong sourceLen, |
| + int level) |
| +{ |
| + CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen); |
| + CMyComPtr<ISequentialInStream> inStream = inStreamSpec; |
| + |
| + COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen); |
| + CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; |
| + |
| + NCompress::NLZMA::CEncoder *encoderSpec = |
| + new NCompress::NLZMA::CEncoder; |
| + CMyComPtr<ICompressCoder> encoder = encoderSpec; |
| + |
| + PROPID propIDs[] = |
| + { |
| + NCoderPropID::kDictionarySize, |
| + NCoderPropID::kPosStateBits, |
| + NCoderPropID::kLitContextBits, |
| + NCoderPropID::kLitPosBits, |
| + NCoderPropID::kAlgorithm, |
| + NCoderPropID::kNumFastBytes, |
| + NCoderPropID::kMatchFinder, |
| + NCoderPropID::kEndMarker |
| + }; |
| + const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]); |
| + |
| + PROPVARIANT properties[kNumProps]; |
| + for (int p = 0; p < 6; p++) |
| + properties[p].vt = VT_UI4; |
| + properties[0].ulVal = UInt32(1 << (level + 14)); |
| + properties[1].ulVal = UInt32(ZLIB_PB); |
| + properties[2].ulVal = UInt32(ZLIB_LC); // for normal files |
| + properties[3].ulVal = UInt32(ZLIB_LP); // for normal files |
| + properties[4].ulVal = UInt32(2); |
| + properties[5].ulVal = UInt32(128); |
| + |
| + properties[6].vt = VT_BSTR; |
| + properties[6].bstrVal = (BSTR)(const wchar_t *)L"BT4"; |
| + |
| + properties[7].vt = VT_BOOL; |
| + properties[7].boolVal = VARIANT_TRUE; |
| + |
| + if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK) |
| + return Z_MEM_ERROR; // should not happen |
| + |
| + HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0); |
| + if (result == E_OUTOFMEMORY) |
| + { |
| + return Z_MEM_ERROR; |
| + } |
| + else if (result != S_OK) |
| + { |
| + return Z_BUF_ERROR; // should not happen |
| + } |
| + |
| + UInt64 fileSize; |
| + outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize); |
| + *destLen = fileSize; |
| + |
| + return Z_OK; |
| +} |
| + |
| +ZEXTERN int ZEXPORT uncompress (Bytef *dest, uLongf *destLen, |
| + const Bytef *source, uLong sourceLen) |
| +{ |
| + CInMemoryStream *inStreamSpec = new CInMemoryStream(source, sourceLen); |
| + CMyComPtr<ISequentialInStream> inStream = inStreamSpec; |
| + |
| + COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen); |
| + CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; |
| + |
| + NCompress::NLZMA::CDecoder *decoderSpec = |
| + new NCompress::NLZMA::CDecoder; |
| + CMyComPtr<ICompressCoder> decoder = decoderSpec; |
| + |
| + if (decoderSpec->SetDecoderPropertiesRaw(ZLIB_LC, |
| + ZLIB_LP, ZLIB_PB, (1 << 23)) != S_OK) return Z_DATA_ERROR; |
| + |
| + UInt64 fileSize = *destLen; |
| + |
| + if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK) |
| + { |
| + return Z_DATA_ERROR; |
| + } |
| + |
| + outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize); |
| + *destLen = fileSize; |
| + |
| + return Z_OK; |
| +} |