📄 compress_lzma.cpp
字号:
/* compress_lzma.cpp -- This file is part of the UPX executable compressor. Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2007 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Markus F.X.J. Oberhumer Laszlo Molnar <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net> */#include "conf.h"#include "compress.h"#include "mem.h"void lzma_compress_config_t::reset(){ memset(this, 0, sizeof(*this)); pos_bits.reset(); lit_pos_bits.reset(); lit_context_bits.reset(); dict_size.reset(); fast_mode = 2; num_fast_bytes.reset(); match_finder_cycles = 0; max_num_probs = 0;}#if !defined(WITH_LZMA)extern int compress_lzma_dummy;int compress_lzma_dummy = 0;#else// INFO: the LZMA SDK is covered by a permissive license which allows// using unmodified LZMA source code in UPX and the UPX stubs.// See SPECIAL EXCEPTION below.//// Quoting from lzma-4.43/lzma.txt://// LICENSE// -------//// LZMA SDK is available under any of the following licenses://// 1) GNU Lesser General Public License (GNU LGPL)// 2) Common Public License (CPL)// 3) Simplified license for unmodified code (read SPECIAL EXCEPTION)// 4) Proprietary license//// It means that you can select one of these four options and follow rules// of that license.//// 1,2) GNU LGPL and CPL licenses are pretty similar and both these// licenses are classified as// - "Free software licenses" at http://www.gnu.org/// - "OSI-approved" at http://www.opensource.org///// 3) SPECIAL EXCEPTION//// Igor Pavlov, as the author of this code, expressly permits you// to statically or dynamically link your code (or bind by name)// to the files from LZMA SDK without subjecting your linked// code to the terms of the CPL or GNU LGPL.// Any modifications or additions to files from LZMA SDK, however,// are subject to the GNU LGPL or CPL terms.//// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,// while you keep LZMA SDK code unmodified./*************************************************************************// cruft because of pseudo-COM layer**************************************************************************/#undef USE_LZMA_PROPERTIES#undef MSDOS#undef OS2#undef _WIN32#undef _WIN32_WCE#undef COMPRESS_MF_MT#undef _NO_EXCEPTIONS#if (WITH_LZMA >= 0x449)# define INITGUID 1//# include "CPP/7zip/Compress/LZMA/LZMADecoder.h"# include "CPP/7zip/Compress/LZMA/LZMAEncoder.h"#else# include "C/Common/MyInitGuid.h"//# include "C/7zip/Compress/LZMA/LZMADecoder.h"# include "C/7zip/Compress/LZMA/LZMAEncoder.h"#endifnamespace MyLzma {struct InStream: public ISequentialInStream, public CMyUnknownImp{ MY_UNKNOWN_IMP const Byte *b_buf; size_t b_size; size_t b_pos; void Init(const Byte *data, size_t size) { b_buf = data; b_size = size; b_pos = 0; } STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);};STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize){ size_t remain = b_size - b_pos; if (size > remain) size = (UInt32) remain; memcpy(data, b_buf + b_pos, size); b_pos += size; if (processedSize != NULL) *processedSize = size; return S_OK;}struct OutStream : public ISequentialOutStream, public CMyUnknownImp{ MY_UNKNOWN_IMP Byte *b_buf; size_t b_size; size_t b_pos; bool overflow; void Init(Byte *data, size_t size) { b_buf = data; b_size = size; b_pos = 0; overflow = false; } HRESULT WriteByte(Byte c) { if (b_pos >= b_size) { overflow = true; return E_FAIL; } b_buf[b_pos++] = c; return S_OK; } STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);};STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize){ size_t remain = b_size - b_pos; if (size > remain) size = (UInt32) remain, overflow = true; memcpy(b_buf + b_pos, data, size); b_pos += size; if (processedSize != NULL) *processedSize = size; return overflow ? E_FAIL : S_OK;}struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp{ MY_UNKNOWN_IMP STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); upx_callback_p cb;};STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize){ if (cb && cb->nprogress) cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize); return S_OK;}} // namespace#if (ACC_CC_INTELC) && defined(__linux__)# pragma warning(disable: 424) // #424: extra ";" ignored#endif#if (WITH_LZMA >= 0x449)# include "C/Alloc.c"# include "C/7zCrc.c"# include "C/Compress/Lz/MatchFinder.c"//# include "CPP/7zip/Common/InBuffer.cpp"# include "CPP/7zip/Common/OutBuffer.cpp"# include "CPP/7zip/Common/StreamUtils.cpp"//# include "CPP/7zip/Compress/LZ/LZOutWindow.cpp"//# include "CPP/7zip/Compress/LZMA/LZMADecoder.cpp"# include "CPP/7zip/Compress/LZMA/LZMAEncoder.cpp"# include "CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp"#else# include "C/Common/Alloc.cpp"# include "C/Common/CRC.cpp"//# include "C/7zip/Common/InBuffer.cpp"# include "C/7zip/Common/OutBuffer.cpp"# include "C/7zip/Common/StreamUtils.cpp"# include "C/7zip/Compress/LZ/LZInWindow.cpp"//# include "C/7zip/Compress/LZ/LZOutWindow.cpp"//# include "C/7zip/Compress/LZMA/LZMADecoder.cpp"# include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"# include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"#endif#undef RC_NORMALIZEint upx_lzma_compress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult ){ assert(M_IS_LZMA(method)); assert(level > 0); assert(cresult != NULL); int r = UPX_E_ERROR; HRESULT rh; const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL; lzma_compress_result_t *res = &cresult->result_lzma; MyLzma::InStream is; is.AddRef(); MyLzma::OutStream os; os.AddRef(); is.Init(src, src_len); os.Init(dst, *dst_len); MyLzma::ProgressInfo progress; progress.AddRef(); progress.cb = cb; NCompress::NLZMA::CEncoder enc; const PROPID propIDs[8] = { NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2) NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0) NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3) NCoderPropID::kDictionarySize, // 3 ds NCoderPropID::kAlgorithm, // 4 fm _fastmode NCoderPropID::kNumFastBytes, // 5 fb NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue NCoderPropID::kMatchFinder // 7 mf }; PROPVARIANT pr[8]; pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4; pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4; unsigned nprops = 7; // setup defaults pr[0].uintVal = 2; // 0 .. 4 pr[1].uintVal = 0; // 0 .. 4 pr[2].uintVal = 3; // 0 .. 8 pr[3].uintVal = 4 * 1024 * 1024; // 1 .. 2**30 pr[4].uintVal = 2; pr[5].uintVal = 64; // 5 .. 273 pr[6].uintVal = 0;#ifdef COMPRESS_MF_BT4 static wchar_t matchfinder[] = L"BT4"; assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0); pr[nprops].vt = VT_BSTR; pr[nprops].bstrVal = matchfinder; nprops++;#endif#if 1 pr[0].uintVal = lzma_compress_config_t::pos_bits_t::default_value_c; pr[1].uintVal = lzma_compress_config_t::lit_pos_bits_t::default_value_c; pr[2].uintVal = lzma_compress_config_t::lit_context_bits_t::default_value_c; pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c; pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;#endif // method overrides if (method >= 0x100) { pr[0].uintVal = (method >> 16) & 15; pr[1].uintVal = (method >> 12) & 15; pr[2].uintVal = (method >> 8) & 15; }#if 0 // DEBUG - set sizes so that we use a maxmimum amount of stack. // These settings cause res->num_probs == 3147574, i.e. we will // need about 6 MB of stack during runtime decompression. pr[1].uintVal = 4; pr[2].uintVal = 8;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -