More lzma stuff.
This commit is contained in:
+101
-38
@@ -42,14 +42,14 @@ int compress_lzma_dummy = 0;
|
||||
#undef OS2
|
||||
#undef _WIN32
|
||||
#undef _WIN32_WCE
|
||||
#include "lzma/MyInitGuid.h"
|
||||
//#include "lzma/LZMADecoder.h"
|
||||
#include "lzma/LZMAEncoder.h"
|
||||
#undef RC_NORMALIZE
|
||||
#undef COMPRESS_MF_MT
|
||||
#include "C/Common/MyInitGuid.h"
|
||||
#include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||
#include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||
|
||||
namespace MyLzma {
|
||||
|
||||
struct CInStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
const Byte *Data; size_t Size; size_t Pos;
|
||||
@@ -59,7 +59,7 @@ struct CInStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 remain = Size - Pos;
|
||||
if (size > remain) size = remain;
|
||||
@@ -69,7 +69,7 @@ STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct COutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
||||
@@ -84,7 +84,7 @@ struct COutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < size && Pos < Size; i++)
|
||||
@@ -94,6 +94,21 @@ STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *process
|
||||
return 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, (upx_uint) *inSize, (upx_uint) *outSize, 3);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -101,7 +116,7 @@ int upx_lzma_compress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const struct upx_compress_config_t *conf,
|
||||
const struct upx_compress_config_t *conf_parm,
|
||||
upx_uintp result )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
@@ -111,41 +126,59 @@ int upx_lzma_compress ( const upx_bytep src, upx_uint src_len,
|
||||
int r = UPX_E_ERROR;
|
||||
HRESULT rh;
|
||||
|
||||
MyLzma::CInStreamRam* isp = new MyLzma::CInStreamRam;
|
||||
MyLzma::CInStreamRam& is = *isp;
|
||||
MyLzma::COutStreamRam* osp = new MyLzma::COutStreamRam;
|
||||
MyLzma::COutStreamRam& os = *osp;
|
||||
MyLzma::InStreamRam is; is.AddRef();
|
||||
MyLzma::OutStreamRam os; os.AddRef();
|
||||
is.Init(src, src_len);
|
||||
// os.Init(dst, *dst_len);
|
||||
os.Init(dst, src_len);
|
||||
|
||||
MyLzma::ProgressInfo progress; progress.AddRef();
|
||||
progress.cb = cb;
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
|
||||
NCompress::NLZMA::CEncoder enc;
|
||||
PROPID propIDs[3] = {
|
||||
NCoderPropID::kAlgorithm,
|
||||
NCoderPropID::kDictionarySize,
|
||||
NCoderPropID::kNumFastBytes
|
||||
const PROPID propIDs[7] = {
|
||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||
NCoderPropID::kDictionarySize, // 3
|
||||
NCoderPropID::kAlgorithm, // 4 _fastmode
|
||||
NCoderPropID::kNumFastBytes, // 5
|
||||
NCoderPropID::kMatchFinderCycles // 6
|
||||
};
|
||||
PROPVARIANT properties[3];
|
||||
properties[0].vt = VT_UI4;
|
||||
properties[1].vt = VT_UI4;
|
||||
properties[2].vt = VT_UI4;
|
||||
properties[0].ulVal = (UInt32) 2;
|
||||
// properties[1].ulVal = (UInt32) dictionarySize;
|
||||
properties[1].ulVal = (UInt32) 1024 * 1024; // FIXME
|
||||
properties[2].ulVal = (UInt32) 64;
|
||||
PROPVARIANT pr[7];
|
||||
pr[0].vt = pr[1].vt = pr[2].vt = VT_UI4;
|
||||
pr[3].vt = pr[4].vt = pr[5].vt = VT_UI4;
|
||||
pr[6].vt = VT_UI4;
|
||||
|
||||
if (enc.SetCoderProperties(propIDs, properties, 3) != S_OK)
|
||||
// setup defaults
|
||||
pr[0].uintVal = 2;
|
||||
pr[1].uintVal = 0;
|
||||
pr[2].uintVal = 3;
|
||||
pr[3].uintVal = src_len;
|
||||
pr[4].uintVal = 2;
|
||||
pr[5].uintVal = 64;
|
||||
pr[6].uintVal = 0;
|
||||
|
||||
// FIXME: tune these according to level
|
||||
if (pr[3].uintVal > src_len)
|
||||
pr[3].uintVal = src_len;
|
||||
|
||||
if (enc.SetCoderProperties(propIDs, pr, 3) != S_OK)
|
||||
goto error;
|
||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||
goto error;
|
||||
if (os.Pos != 5)
|
||||
if (os.Overflow || os.Pos != 5)
|
||||
goto error;
|
||||
#if 0 // defined(_LZMA_OUT_READ)
|
||||
#else
|
||||
os.Pos -= 4; // do not encode dict_size
|
||||
#endif
|
||||
|
||||
rh = enc.Code(&is, &os, 0, 0, 0);
|
||||
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||
if (rh == E_OUTOFMEMORY)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
#if 0
|
||||
@@ -156,7 +189,8 @@ int upx_lzma_compress ( const upx_bytep src, upx_uint src_len,
|
||||
r = UPX_E_OK;
|
||||
|
||||
//result[8] = LzmaGetNumProbs(&s.Properties));
|
||||
result[8] = 0; // FIXME
|
||||
//result[8] = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||
result[8] = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||
|
||||
error:
|
||||
*dst_len = os.Pos;
|
||||
@@ -168,14 +202,17 @@ error:
|
||||
}
|
||||
|
||||
|
||||
#include "lzma/Alloc.cpp"
|
||||
#include "lzma/CRC.cpp"
|
||||
//#include "lzma/LZMADecoder.cpp"
|
||||
#include "lzma/LZMAEncoder.cpp"
|
||||
#include "lzma/LZInWindow.cpp"
|
||||
#include "lzma/OutBuffer.cpp"
|
||||
#include "lzma/RangeCoderBit.cpp"
|
||||
#include "lzma/StreamUtils.cpp"
|
||||
#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"
|
||||
#undef RC_NORMALIZE
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -186,7 +223,7 @@ error:
|
||||
#undef _LZMA_OUT_READ
|
||||
#undef _LZMA_PROB32
|
||||
#undef _LZMA_LOC_OPT
|
||||
#include "lzma/LzmaDecode.cpp"
|
||||
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||
|
||||
int upx_lzma_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
@@ -205,7 +242,11 @@ int upx_lzma_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
r = LzmaDecodeProperties(&s.Properties, src, src_len);
|
||||
if (r != 0)
|
||||
goto error;
|
||||
#if 0 // defined(_LZMA_OUT_READ)
|
||||
src += LZMA_PROPERTIES_SIZE; src_len -= LZMA_PROPERTIES_SIZE;
|
||||
#else
|
||||
src += 1; src_len -= 1;
|
||||
#endif
|
||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||
if (!s.Probs)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
@@ -218,6 +259,28 @@ error:
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_lzma_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
|
||||
/* FIXME */
|
||||
UNUSED(buf);
|
||||
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead);
|
||||
if ((int)overlap_overhead >= 256)
|
||||
return UPX_E_OK;
|
||||
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_LZMA */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
|
||||
Reference in New Issue
Block a user