More lzma stuff.

This commit is contained in:
Markus F.X.J. Oberhumer
2006-06-09 18:36:53 +02:00
parent 54340ab4bf
commit f1ba0c0aa7
8 changed files with 198 additions and 71 deletions
+101 -38
View File
@@ -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