9.04 beta

This commit is contained in:
Igor Pavlov
2009-06-02 00:00:00 +00:00
committed by Kornel Lesiński
parent 8874e4fbc9
commit 829409452d
440 changed files with 19803 additions and 9941 deletions

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../../Common/Defs.h"
@@ -420,15 +417,19 @@ static UInt32 NO_INLINE DecodeBlock2Rand(const UInt32 *tt, UInt32 blockSize, UIn
return crc.GetDigest();
}
#ifdef COMPRESS_BZIP2_MT
CDecoder::CDecoder():
m_States(0)
CDecoder::CDecoder()
{
#ifdef COMPRESS_BZIP2_MT
m_States = 0;
m_NumThreadsPrev = 0;
NumThreads = 1;
#endif;
_needInStreamInit = true;
}
#ifdef COMPRESS_BZIP2_MT
CDecoder::~CDecoder()
{
Free();
@@ -611,43 +612,61 @@ HRESULT CDecoder::DecodeFile(bool &isBZ, ICompressProgressInfo *progress)
}
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
bool &isBZ, ICompressProgressInfo *progress)
{
isBZ = false;
try
{
if (!m_InStream.Create(kBufferSize))
return E_OUTOFMEMORY;
if (!m_OutStream.Create(kBufferSize))
return E_OUTOFMEMORY;
m_InStream.SetStream(inStream);
m_InStream.Init();
if (inStream)
m_InStream.SetStream(inStream);
CDecoderFlusher flusher(this, inStream != NULL);
if (_needInStreamInit)
{
m_InStream.Init();
_needInStreamInit = false;
}
_inStart = m_InStream.GetProcessedSize();
m_InStream.AlignToByte();
m_OutStream.SetStream(outStream);
m_OutStream.Init();
CDecoderFlusher flusher(this);
bool isBZ;
RINOK(DecodeFile(isBZ, progress));
return isBZ ? S_OK: S_FALSE;
}
flusher.NeedFlush = false;
return Flush();
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
}
catch(const CInBufferException &e) { return e.ErrorCode; }
catch(const COutBufferException &e) { return e.ErrorCode; }
catch(...) { return E_FAIL; }
}
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
if (value == NULL)
return E_INVALIDARG;
*value = m_InStream.GetProcessedSize();
return S_OK;
_needInStreamInit = true;
bool isBZ;
RINOK(CodeReal(inStream, outStream, isBZ, progress));
return isBZ ? S_OK : S_FALSE;
}
HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, bool &isBZ, ICompressProgressInfo *progress)
{
return CodeReal(NULL, outStream, isBZ, progress);
}
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { m_InStream.SetStream(inStream); return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { m_InStream.ReleaseStream(); return S_OK; }
#ifdef COMPRESS_BZIP2_MT
static THREAD_FUNC_DECL MFThread(void *p) { ((CState *)p)->ThreadFunc(); return 0; }
@@ -694,7 +713,7 @@ void CState::ThreadFunc()
nextBlockIndex = 0;
Decoder->NextBlockIndex = nextBlockIndex;
UInt32 crc;
UInt64 packSize;
UInt64 packSize = 0;
UInt32 blockSize = 0, origPtr = 0;
bool randMode = false;
@@ -752,8 +771,9 @@ void CState::ThreadFunc()
{
if (Decoder->Progress)
{
UInt64 inSize = packSize - Decoder->_inStart;
UInt64 unpackSize = Decoder->m_OutStream.GetProcessedSize();
res = Decoder->Progress->SetRatioInfo(&packSize, &unpackSize);
res = Decoder->Progress->SetRatioInfo(&inSize, &unpackSize);
}
}
else

View File

@@ -62,7 +62,6 @@ class CDecoder :
#ifdef COMPRESS_BZIP2_MT
public ICompressSetCoderMt,
#endif
public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
public:
@@ -71,9 +70,11 @@ public:
NBitm::CDecoder<CInBuffer> m_InStream;
Byte m_Selectors[kNumSelectorsMax];
CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
UInt64 _inStart;
private:
UInt32 m_NumThreadsPrev;
bool _needInStreamInit;
UInt32 ReadBits(int numBits);
Byte ReadByte();
@@ -82,18 +83,22 @@ private:
HRESULT PrepareBlock(CState &state);
HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress);
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
bool &isBZ, ICompressProgressInfo *progress);
class CDecoderFlusher
{
CDecoder *_decoder;
public:
bool NeedFlush;
CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
bool ReleaseInStream;
CDecoderFlusher(CDecoder *decoder, bool releaseInStream):
_decoder(decoder),
ReleaseInStream(releaseInStream),
NeedFlush(true) {}
~CDecoderFlusher()
{
if (NeedFlush)
_decoder->Flush();
_decoder->ReleaseStreams();
_decoder->ReleaseStreams(ReleaseInStream);
}
};
@@ -103,6 +108,7 @@ public:
#ifdef COMPRESS_BZIP2_MT
ICompressProgressInfo *Progress;
CState *m_States;
UInt32 m_NumThreadsPrev;
NWindows::NSynchronization::CManualResetEvent CanProcessEvent;
NWindows::NSynchronization::CCriticalSection CS;
@@ -118,7 +124,6 @@ public:
HRESULT Result2;
UInt32 BlockSizeMax;
CDecoder();
~CDecoder();
HRESULT Create();
void Free();
@@ -127,28 +132,37 @@ public:
CState m_States[1];
#endif
CDecoder();
HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc);
HRESULT Flush() { return m_OutStream.Flush(); }
void ReleaseStreams()
void ReleaseStreams(bool releaseInStream)
{
m_InStream.ReleaseStream();
if (releaseInStream)
m_InStream.ReleaseStream();
m_OutStream.ReleaseStream();
}
MY_QUERYINTERFACE_BEGIN
#ifdef COMPRESS_BZIP2_MT
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize)
#else
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
HRESULT CodeResume(ISequentialOutStream *outStream, bool &isBZ, ICompressProgressInfo *progress);
UInt64 GetInputProcessedSize() const { return m_InStream.GetProcessedSize(); }
#ifdef COMPRESS_BZIP2_MT
STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
#endif

View File

@@ -2,12 +2,9 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
#include "../../../C/BwtSort.h"
#include "../../../C/HuffEnc.h"
}
#include "BZip2Crc.h"
#include "BZip2Encoder.h"
@@ -823,7 +820,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
WriteByte(kFinSig5);
WriteCrc(CombinedCrc.GetDigest());
return S_OK;
return Flush();
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,

View File

@@ -1,4 +1,4 @@
// Compress/BZip2Encoder.h
// BZip2Encoder.h
#ifndef __COMPRESS_BZIP2_ENCODER_H
#define __COMPRESS_BZIP2_ENCODER_H
@@ -215,12 +215,9 @@ public:
{
CEncoder *_coder;
public:
bool NeedFlush;
CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {}
CFlusher(CEncoder *coder): _coder(coder) {}
~CFlusher()
{
if (NeedFlush)
_coder->Flush();
_coder->ReleaseStreams();
}
};

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "Bcj2Coder.h"

View File

@@ -3,10 +3,7 @@
#ifndef __COMPRESS_BCJ_CODER_H
#define __COMPRESS_BCJ_CODER_H
extern "C"
{
#include "../../../C/Bra.h"
}
#include "BranchCoder.h"

View File

@@ -35,15 +35,11 @@ public:
m_Value = 0;
NumExtraBytes = 0;
}
UInt64 GetProcessedSize() const
{ return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
UInt64 GetProcessedBitsSize() const
{ return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
int GetBitPosition() const { return (m_BitPos & 7); }
UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() + NumExtraBytes - (kNumBigValueBits - m_BitPos) / 8; }
void Normalize()
{
for (;m_BitPos >= 8; m_BitPos -= 8)
for (; m_BitPos >= 8; m_BitPos -= 8)
{
Byte b = 0;
if (!m_Stream.ReadByte(b))
@@ -114,10 +110,31 @@ public:
UInt32 ReadBits(int numBits)
{
Normalize();
UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
UInt32 res = m_NormalValue & ((1 << numBits) - 1);
MovePos(numBits);
return res;
}
void AlignToByte() { MovePos((32 - this->m_BitPos) & 7); }
Byte ReadByte()
{
if (this->m_BitPos == kNumBigValueBits)
{
Byte b = 0;
if (!this->m_Stream.ReadByte(b))
{
b = 0xFF;
this->NumExtraBytes++;
}
return b;
}
{
Byte b = (Byte)(m_NormalValue & 0xFF);
MovePos(8);
return b;
}
}
};
}

View File

@@ -31,9 +31,7 @@ public:
Normalize();
}
UInt64 GetProcessedSize() const
{ return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
UInt32 GetBitPosition() const { return (m_BitPos & 7); }
UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
void Normalize()
{
@@ -59,6 +57,8 @@ public:
MovePos(numBits);
return res;
}
void AlignToByte() { MovePos((32 - m_BitPos) & 7); }
};
}

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Bra.h"
}
#include "BranchMisc.h"

View File

@@ -2,7 +2,31 @@
#include "StdAfx.h"
#include "ByteSwap.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/RegisterCodec.h"
class CByteSwap2:
public ICompressFilter,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
};
class CByteSwap4:
public ICompressFilter,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
};
STDMETHODIMP CByteSwap2::Init() { return S_OK; }
@@ -36,3 +60,14 @@ STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
}
return i;
}
static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); }
static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); }
static CCodecInfo g_CodecsInfo[] =
{
{ CreateCodec2, CreateCodec2, 0x020302, L"Swap2", 1, true },
{ CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true }
};
REGISTER_CODECS(ByteSwap)

View File

@@ -1,30 +0,0 @@
// ByteSwap.h
#ifndef __COMPRESS_BYTE_SWAP_H
#define __COMPRESS_BYTE_SWAP_H
#include "../../Common/MyCom.h"
#include "../ICoder.h"
class CByteSwap2:
public ICompressFilter,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
};
class CByteSwap4:
public ICompressFilter,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
};
#endif

View File

@@ -1,18 +0,0 @@
// ByteSwapRegister.cpp
#include "StdAfx.h"
#include "../Common/RegisterCodec.h"
#include "ByteSwap.h"
static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); }
static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); }
static CCodecInfo g_CodecsInfo[] =
{
{ CreateCodec2, CreateCodec4, 0x020302, L"Swap2", 1, true },
{ CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true }
};
REGISTER_CODECS(ByteSwap)

View File

@@ -3,10 +3,13 @@
#include "StdAfx.h"
#include "../../Common/ComTry.h"
#include "../../Windows/PropVariant.h"
#include "../Common/RegisterCodec.h"
#include "../ICoder.h"
#include "../Common/RegisterCodec.h"
extern unsigned int g_NumCodecs;
extern const CCodecInfo *g_Codecs[];

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../Common/StreamUtils.h"
@@ -35,16 +32,18 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
TotalSize = 0;
for (;;)
{
UInt32 realProcessedSize;
UInt32 size = kBufferSize;
if (outSize != 0)
if (size > *outSize - TotalSize)
size = (UInt32)(*outSize - TotalSize);
RINOK(inStream->Read(_buffer, size, &realProcessedSize));
if (realProcessedSize == 0)
RINOK(inStream->Read(_buffer, size, &size));
if (size == 0)
break;
RINOK(WriteStream(outStream, _buffer, realProcessedSize));
TotalSize += realProcessedSize;
if (outStream)
{
RINOK(WriteStream(outStream, _buffer, size));
}
TotalSize += size;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
@@ -59,4 +58,10 @@ STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
return S_OK;
}
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
}

View File

@@ -17,7 +17,7 @@ class CCopyCoder:
Byte *_buffer;
public:
UInt64 TotalSize;
CCopyCoder(): TotalSize(0) , _buffer(0) {};
CCopyCoder(): TotalSize(0), _buffer(0) {};
~CCopyCoder();
MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
@@ -27,6 +27,8 @@ public:
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};
HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
}
#endif

View File

@@ -15,6 +15,7 @@ CCoder::CCoder(bool deflate64Mode, bool deflateNSIS):
_deflate64Mode(deflate64Mode),
_deflateNSIS(deflateNSIS),
_keepHistory(false),
_needInitInStream(true),
ZlibMode(false) {}
UInt32 CCoder::ReadBits(int numBits)
@@ -70,9 +71,7 @@ bool CCoder::ReadTables(void)
if (blockType == NBlockType::kStored)
{
m_StoredMode = true;
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0);
ReadBits(numBitsForAlign);
m_InBitStream.AlignToByte();
m_StoredBlockSize = ReadBits(kStoredBlockLengthFieldSize);
if (_deflateNSIS)
return true;
@@ -130,10 +129,8 @@ HRESULT CCoder::CodeSpec(UInt32 curSize)
if (!_keepHistory)
if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32))
return E_OUTOFMEMORY;
if (!m_InBitStream.Create(1 << 17))
return E_OUTOFMEMORY;
RINOK(InitInStream(_needInitInStream));
m_OutWindowStream.Init(_keepHistory);
m_InBitStream.Init();
m_FinalBlock = false;
_remainLen = 0;
_needReadTable = true;
@@ -167,7 +164,7 @@ HRESULT CCoder::CodeSpec(UInt32 curSize)
if(m_StoredMode)
{
for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--)
m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
m_OutWindowStream.PutByte(m_InBitStream.ReadByte());
_needReadTable = (m_StoredBlockSize == 0);
continue;
}
@@ -231,14 +228,29 @@ HRESULT CCoder::CodeSpec(UInt32 curSize)
return S_OK;
}
HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *, const UInt64 *outSize, ICompressProgressInfo *progress)
#ifdef _NO_EXCEPTIONS
#define DEFLATE_TRY_BEGIN
#define DEFLATE_TRY_END
#else
#define DEFLATE_TRY_BEGIN try {
#define DEFLATE_TRY_END } \
catch(const CInBufferException &e) { return e.ErrorCode; } \
catch(const CLzOutWindowException &e) { return e.ErrorCode; } \
catch(...) { return S_FALSE; }
#endif
HRESULT CCoder::CodeReal(ISequentialOutStream *outStream,
const UInt64 *outSize, ICompressProgressInfo *progress)
{
SetInStream(inStream);
DEFLATE_TRY_BEGIN
m_OutWindowStream.SetStream(outStream);
SetOutStreamSize(outSize);
CCoderReleaser flusher(this);
const UInt64 inStart = m_InBitStream.GetProcessedSize();
const UInt64 start = m_OutWindowStream.GetProcessedSize();
for (;;)
{
@@ -256,45 +268,33 @@ HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *ou
break;
if (progress != NULL)
{
const UInt64 inSize = m_InBitStream.GetProcessedSize();
const UInt64 inSize = m_InBitStream.GetProcessedSize() - inStart;
const UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start;
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
}
}
if (_remainLen == kLenIdFinished && ZlibMode)
{
UInt32 currentBitPosition = m_InBitStream.GetBitPosition();
int numBitsForAlign = (int)(currentBitPosition > 0 ? (8 - currentBitPosition): 0);
ReadBits(numBitsForAlign);
m_InBitStream.AlignToByte();
for (int i = 0; i < 4; i++)
ZlibFooter[i] = (Byte)m_InBitStream.ReadBits(8);
ZlibFooter[i] = m_InBitStream.ReadByte();
}
flusher.NeedFlush = false;
return Flush();
HRESULT res = Flush();
if (res == S_OK && InputEofError())
return S_FALSE;
return res;
DEFLATE_TRY_END
}
#ifdef _NO_EXCEPTIONS
#define DEFLATE_TRY_BEGIN
#define DEFLATE_TRY_END
#else
#define DEFLATE_TRY_BEGIN try {
#define DEFLATE_TRY_END } \
catch(const CInBufferException &e) { return e.ErrorCode; } \
catch(const CLzOutWindowException &e) { return e.ErrorCode; } \
catch(...) { return S_FALSE; }
#endif
HRESULT CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
DEFLATE_TRY_BEGIN
return CodeReal(inStream, outStream, inSize, outSize, progress);
DEFLATE_TRY_END
SetInStream(inStream);
SetOutStreamSize(outSize);
HRESULT res = CodeReal(outStream, outSize, progress);
ReleaseInStream();
return res;
}
STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value)
@@ -320,6 +320,7 @@ STDMETHODIMP CCoder::ReleaseInStream()
STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 * /* outSize */)
{
_remainLen = kLenIdNeedInit;
_needInitInStream = true;
m_OutWindowStream.Init(_keepHistory);
return S_OK;
}
@@ -342,4 +343,11 @@ STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
#endif
STDMETHODIMP CCoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
{
_remainLen = kLenIdNeedInit;
m_OutWindowStream.Init(_keepHistory);
return CodeReal(outStream, outSize, progress);
}
}}}

View File

@@ -44,6 +44,7 @@ class CCoder:
bool _deflateNSIS;
bool _deflate64Mode;
bool _keepHistory;
bool _needInitInStream;
Int32 _remainLen;
UInt32 _rep0;
bool _needReadTable;
@@ -53,24 +54,18 @@ class CCoder:
bool DeCodeLevelTable(Byte *values, int numSymbols);
bool ReadTables();
void ReleaseStreams()
{
m_OutWindowStream.ReleaseStream();
ReleaseInStream();
}
HRESULT Flush() { return m_OutWindowStream.Flush(); }
class CCoderReleaser
{
CCoder *m_Coder;
CCoder *_coder;
public:
bool NeedFlush;
CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
CCoderReleaser(CCoder *coder): _coder(coder), NeedFlush(true) {}
~CCoderReleaser()
{
if (NeedFlush)
m_Coder->Flush();
m_Coder->ReleaseStreams();
_coder->Flush();
_coder->ReleaseOutStream();
}
};
friend class CCoderReleaser;
@@ -81,10 +76,17 @@ public:
Byte ZlibFooter[4];
CCoder(bool deflate64Mode, bool deflateNSIS = false);
virtual ~CCoder() {};
void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
void ReleaseOutStream()
{
m_OutWindowStream.ReleaseStream();
}
HRESULT CodeReal(ISequentialOutStream *outStream,
const UInt64 *outSize, ICompressProgressInfo *progress);
#ifndef NO_READ_FROM_CODER
MY_UNKNOWN_IMP4(
@@ -109,6 +111,25 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
STDMETHOD(CodeResume)(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
HRESULT InitInStream(bool needInit)
{
if (!m_InBitStream.Create(1 << 17))
return E_OUTOFMEMORY;
if (needInit)
{
m_InBitStream.Init();
_needInitInStream = false;
}
return S_OK;
}
void AlignToByte() { m_InBitStream.AlignToByte(); }
Byte ReadByte() { return (Byte)m_InBitStream.ReadBits(8); }
bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); }
UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); }
// IGetInStreamProcessedSize
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
};

View File

@@ -2,11 +2,8 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
#include "../../../C/HuffEnc.h"
}
#include "Common/ComTry.h"

View File

@@ -3,10 +3,7 @@
#ifndef __DEFLATE_ENCODER_H
#define __DEFLATE_ENCODER_H
extern "C"
{
#include "../../../C/LzFind.h"
}
#include "../../../C/LzFind.h"
#include "Common/MyCom.h"

112
CPP/7zip/Compress/DeltaFilter.cpp Executable file
View File

@@ -0,0 +1,112 @@
// DeltaFilter.cpp
#include "StdAfx.h"
#include "../../../C/Delta.h"
#include "../Common/RegisterCodec.h"
#include "BranchCoder.h"
struct CDelta
{
unsigned _delta;
Byte _state[DELTA_STATE_SIZE];
CDelta(): _delta(1) {}
void DeltaInit() { Delta_Init(_state); }
};
class CDeltaEncoder:
public ICompressFilter,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
CDelta,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
};
class CDeltaDecoder:
public ICompressFilter,
public ICompressSetDecoderProperties2,
CDelta,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
};
STDMETHODIMP CDeltaEncoder::Init()
{
DeltaInit();
return S_OK;
}
STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size)
{
Delta_Encode(_state, _delta, data, size);
return size;
}
STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{
UInt32 delta = _delta;
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = props[i];
if (propIDs[i] != NCoderPropID::kDefaultProp || prop.vt != VT_UI4 || prop.ulVal < 1 || prop.ulVal > 256)
return E_INVALIDARG;
delta = prop.ulVal;
}
_delta = delta;
return S_OK;
}
STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
Byte prop = (Byte)(_delta - 1);
return outStream->Write(&prop, 1, NULL);
}
STDMETHODIMP CDeltaDecoder::Init()
{
DeltaInit();
return S_OK;
}
STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size)
{
Delta_Decode(_state, _delta, data, size);
return size;
}
STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
{
if (size != 1)
return E_INVALIDARG;
_delta = (unsigned)props[0] + 1;
return S_OK;
}
#define CREATE_CODEC(x) \
static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## Decoder); } \
static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## Encoder); }
CREATE_CODEC(Delta)
#define METHOD_ITEM(x, id, name) { CreateCodec ## x, CreateCodec ## x ## Out, id, name, 1, true }
static CCodecInfo g_CodecsInfo[] =
{
METHOD_ITEM(Delta, 3, L"Delta")
};
REGISTER_CODECS(Delta)

View File

@@ -297,6 +297,14 @@ SOURCE=..\..\..\Common\Types.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Common\CWrappers.cpp
# End Source File
# Begin Source File
SOURCE=..\..\Common\CWrappers.h
# End Source File
# Begin Source File
SOURCE=..\..\Common\FileStreams.cpp
# End Source File
# Begin Source File

View File

@@ -31,13 +31,10 @@
#include "../../../Windows/System.h"
#endif
extern "C"
{
#include "../../../../C/7zVersion.h"
#include "../../../../C/Alloc.h"
#include "../../../../C/LzmaUtil/Lzma86Dec.h"
#include "../../../../C/LzmaUtil/Lzma86Enc.h"
}
#include "../../../../C/7zVersion.h"
#include "../../../../C/Alloc.h"
#include "../../../../C/LzmaUtil/Lzma86Dec.h"
#include "../../../../C/LzmaUtil/Lzma86Enc.h"
using namespace NCommandLineParser;

View File

@@ -28,11 +28,8 @@
#endif
#endif
extern "C"
{
#include "../../../../C/7zCrc.h"
#include "../../../../C/Alloc.h"
}
#include "../../../Common/MyCom.h"
@@ -575,22 +572,22 @@ HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandom
PROPID propIDs[] =
{
NCoderPropID::kDictionarySize,
NCoderPropID::kMultiThread
NCoderPropID::kNumThreads
};
const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
PROPVARIANT properties[kNumProps];
properties[0].vt = VT_UI4;
properties[0].ulVal = (UInt32)dictionarySize;
PROPVARIANT props[kNumProps];
props[0].vt = VT_UI4;
props[0].ulVal = dictionarySize;
properties[1].vt = VT_BOOL;
properties[1].boolVal = (numThreads > 1) ? VARIANT_TRUE : VARIANT_FALSE;
props[1].vt = VT_UI4;
props[1].ulVal = numThreads;
{
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
if (!setCoderProperties)
return E_FAIL;
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, kNumProps));
RINOK(setCoderProperties->SetCoderProperties(propIDs, props, kNumProps));
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);

View File

@@ -26,6 +26,7 @@ WIN_OBJS = \
$O\System.obj
7ZIP_COMMON_OBJS = \
$O\CWrappers.obj \
$O\InBuffer.obj \
$O\OutBuffer.obj \
$O\StreamUtils.obj \

View File

@@ -0,0 +1,189 @@
// Lzma2Decoder.cpp
#include "StdAfx.h"
#include "../../../C/Alloc.h"
#include "../Common/StreamUtils.h"
#include "Lzma2Decoder.h"
static HRESULT SResToHRESULT(SRes res)
{
switch(res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_PARAM: return E_INVALIDARG;
// case SZ_ERROR_PROGRESS: return E_ABORT;
case SZ_ERROR_DATA: return S_FALSE;
}
return E_FAIL;
}
namespace NCompress {
namespace NLzma2 {
static const UInt32 kInBufSize = 1 << 20;
CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false)
{
Lzma2Dec_Construct(&_state);
}
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
CDecoder::~CDecoder()
{
Lzma2Dec_Free(&_state, &g_Alloc);
MyFree(_inBuf);
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
if (size != 1) return SZ_ERROR_UNSUPPORTED;
RINOK(SResToHRESULT(Lzma2Dec_Allocate(&_state, prop[0], &g_Alloc)));
if (_inBuf == 0)
{
_inBuf = (Byte *)MyAlloc(kInBufSize);
if (_inBuf == 0)
return E_OUTOFMEMORY;
}
return S_OK;
}
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; }
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
_outSizeDefined = (outSize != NULL);
if (_outSizeDefined)
_outSize = *outSize;
Lzma2Dec_Init(&_state);
_inPos = _inSize = 0;
_inSizeProcessed = _outSizeProcessed = 0;
return S_OK;
}
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 * /* inSize */,
const UInt64 *outSize, ICompressProgressInfo *progress)
{
if (_inBuf == 0)
return S_FALSE;
SetOutStreamSize(outSize);
for (;;)
{
if (_inPos == _inSize)
{
_inPos = _inSize = 0;
RINOK(inStream->Read(_inBuf, kInBufSize, &_inSize));
}
SizeT dicPos = _state.decoder.dicPos;
SizeT curSize = _state.decoder.dicBufSize - dicPos;
const UInt32 kStepSize = ((UInt32)1 << 22);
if (curSize > kStepSize)
curSize = (SizeT)kStepSize;
ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
if (_outSizeDefined)
{
const UInt64 rem = _outSize - _outSizeProcessed;
if (rem < curSize)
{
curSize = (SizeT)rem;
/*
// finishMode = LZMA_FINISH_END;
we can't use LZMA_FINISH_END here to allow partial decoding
*/
}
}
SizeT inSizeProcessed = _inSize - _inPos;
ELzmaStatus status;
SRes res = Lzma2Dec_DecodeToDic(&_state, dicPos + curSize, _inBuf + _inPos, &inSizeProcessed, finishMode, &status);
_inPos += (UInt32)inSizeProcessed;
_inSizeProcessed += inSizeProcessed;
SizeT outSizeProcessed = _state.decoder.dicPos - dicPos;
_outSizeProcessed += outSizeProcessed;
bool finished = (inSizeProcessed == 0 && outSizeProcessed == 0);
bool stopDecoding = (_outSizeDefined && _outSizeProcessed >= _outSize);
if (res != 0 || _state.decoder.dicPos == _state.decoder.dicBufSize || finished || stopDecoding)
{
HRESULT res2 = WriteStream(outStream, _state.decoder.dic, _state.decoder.dicPos);
if (res != 0)
return S_FALSE;
RINOK(res2);
if (stopDecoding)
return S_OK;
if (finished)
return (status == LZMA_STATUS_FINISHED_WITH_MARK ? S_OK : S_FALSE);
}
if (_state.decoder.dicPos == _state.decoder.dicBufSize)
_state.decoder.dicPos = 0;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed));
}
}
}
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
do
{
if (_inPos == _inSize)
{
_inPos = _inSize = 0;
RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
}
{
SizeT inProcessed = _inSize - _inPos;
if (_outSizeDefined)
{
const UInt64 rem = _outSize - _outSizeProcessed;
if (rem < size)
size = (UInt32)rem;
}
SizeT outProcessed = size;
ELzmaStatus status;
SRes res = Lzma2Dec_DecodeToBuf(&_state, (Byte *)data, &outProcessed,
_inBuf + _inPos, &inProcessed, LZMA_FINISH_ANY, &status);
_inPos += (UInt32)inProcessed;
_inSizeProcessed += inProcessed;
_outSizeProcessed += outProcessed;
size -= (UInt32)outProcessed;
data = (Byte *)data + outProcessed;
if (processedSize)
*processedSize += (UInt32)outProcessed;
RINOK(SResToHRESULT(res));
if (inProcessed == 0 && outProcessed == 0)
return S_OK;
}
}
while (size != 0);
return S_OK;
}
#endif
}}

View File

@@ -0,0 +1,73 @@
// Lzma2Decoder.h
#ifndef __LZMA2_DECODER_H
#define __LZMA2_DECODER_H
#include "../../../C/Lzma2Dec.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
namespace NCompress {
namespace NLzma2 {
class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
public ICompressGetInStreamProcessedSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
public ISequentialInStream,
#endif
public CMyUnknownImp
{
CMyComPtr<ISequentialInStream> _inStream;
Byte *_inBuf;
UInt32 _inPos;
UInt32 _inSize;
CLzma2Dec _state;
bool _outSizeDefined;
UInt64 _outSize;
UInt64 _inSizeProcessed;
UInt64 _outSizeProcessed;
public:
#ifndef NO_READ_FROM_CODER
MY_UNKNOWN_IMP5(
ICompressSetDecoderProperties2,
ICompressGetInStreamProcessedSize,
ICompressSetInStream,
ICompressSetOutStreamSize,
ISequentialInStream)
#else
MY_UNKNOWN_IMP2(
ICompressSetDecoderProperties2,
ICompressGetInStreamProcessedSize)
#endif
STDMETHOD(Code)(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *_inSize, const UInt64 *outSize,
ICompressProgressInfo *progress);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
#ifndef NO_READ_FROM_CODER
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
CDecoder();
virtual ~CDecoder();
};
}}
#endif

View File

@@ -0,0 +1,94 @@
// Lzma2Encoder.cpp
#include "StdAfx.h"
#include "../../../C/Alloc.h"
#include "../Common/CWrappers.h"
#include "../Common/StreamUtils.h"
#include "Lzma2Encoder.h"
namespace NCompress {
namespace NLzma {
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep);
}
namespace NLzma2 {
static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
static void SzBigFree(void *, void *address) { BigFree(address); }
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
static void *SzAlloc(void *, size_t size) { return MyAlloc(size); }
static void SzFree(void *, void *address) { MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
CEncoder::CEncoder()
{
_encoder = 0;
_encoder = Lzma2Enc_Create(&g_Alloc, &g_BigAlloc);
if (_encoder == 0)
throw 1;
}
CEncoder::~CEncoder()
{
if (_encoder != 0)
Lzma2Enc_Destroy(_encoder);
}
HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props)
{
switch (propID)
{
case NCoderPropID::kBlockSize:
if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.blockSize = prop.ulVal; break;
case NCoderPropID::kNumThreads:
if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;
default:
RINOK(NLzma::SetLzmaProp(propID, prop, lzma2Props.lzmaProps));
}
return S_OK;
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
CLzma2EncProps lzma2Props;
Lzma2EncProps_Init(&lzma2Props);
for (UInt32 i = 0; i < numProps; i++)
{
RINOK(SetLzma2Prop(propIDs[i], coderProps[i], lzma2Props));
}
return SResToHRESULT(Lzma2Enc_SetProps(_encoder, &lzma2Props));
}
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
Byte prop = Lzma2Enc_WriteProperties(_encoder);
return WriteStream(outStream, &prop, 1);
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
CSeqInStreamWrap inWrap(inStream);
CSeqOutStreamWrap outWrap(outStream);
CCompressProgressWrap progressWrap(progress);
SRes res = Lzma2Enc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL);
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
return outWrap.Res;
if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)
return progressWrap.Res;
return SResToHRESULT(res);
}
}}

View File

@@ -0,0 +1,36 @@
// Lzma2Encoder.h
#ifndef __LZMA2_ENCODER_H
#define __LZMA2_ENCODER_H
#include "../../../C/Lzma2Enc.h"
#include "../../Common/MyCom.h"
#include "../ICoder.h"
namespace NCompress {
namespace NLzma2 {
class CEncoder:
public ICompressCoder,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public CMyUnknownImp
{
CLzma2EncHandle _encoder;
public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
CEncoder();
virtual ~CEncoder();
};
}}
#endif

View File

@@ -0,0 +1,20 @@
// Lzma2Register.cpp
#include "StdAfx.h"
#include "../Common/RegisterCodec.h"
#include "Lzma2Decoder.h"
static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CDecoder); }
#ifndef EXTRACT_ONLY
#include "Lzma2Encoder.h"
static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CEncoder); }
#else
#define CreateCodecOut 0
#endif
static CCodecInfo g_CodecInfo =
{ CreateCodec, CreateCodecOut, 0x21, L"LZMA2", 1, false };
REGISTER_CODEC(LZMA2)

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../Common/StreamUtils.h"
@@ -19,7 +16,6 @@ static HRESULT SResToHRESULT(SRes res)
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_PARAM: return E_INVALIDARG;
case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
// case SZ_ERROR_PROGRESS: return E_ABORT;
case SZ_ERROR_DATA: return S_FALSE;
}
return E_FAIL;
@@ -30,8 +26,10 @@ namespace NLzma {
static const UInt32 kInBufSize = 1 << 20;
CDecoder::CDecoder(): _inBuf(0), _outSizeDefined(false), FinishStream(false)
CDecoder::CDecoder(): _inBuf(0), _propsWereSet(false), _outSizeDefined(false), FinishStream(false)
{
_inSizeProcessed = 0;
_inPos = _inSize = 0;
LzmaDec_Construct(&_state);
}
@@ -45,43 +43,47 @@ CDecoder::~CDecoder()
MyFree(_inBuf);
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
HRESULT CDecoder::CreateInputBuffer()
{
RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc)));
if (_inBuf == 0)
{
_inBuf = (Byte *)MyAlloc(kInBufSize);
if (_inBuf == 0)
return E_OUTOFMEMORY;
}
return S_OK;
}
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; }
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *prop, UInt32 size)
{
RINOK(SResToHRESULT(LzmaDec_Allocate(&_state, prop, size, &g_Alloc)));
_propsWereSet = true;
return CreateInputBuffer();
}
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
void CDecoder::SetOutStreamSizeResume(const UInt64 *outSize)
{
_outSizeDefined = (outSize != NULL);
if (_outSizeDefined)
_outSize = *outSize;
_outSizeProcessed = 0;
LzmaDec_Init(&_state);
}
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
_inSizeProcessed = 0;
_inPos = _inSize = 0;
_inSizeProcessed = _outSizeProcessed = 0;
SetOutStreamSizeResume(outSize);
return S_OK;
}
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
HRESULT CDecoder::CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
{
if (_inBuf == 0)
if (_inBuf == 0 || !_propsWereSet)
return S_FALSE;
SetOutStreamSize(outSize);
UInt64 startInProgress = _inSizeProcessed;
for (;;)
{
@@ -135,15 +137,26 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
if (_state.dicPos == _state.dicBufSize)
_state.dicPos = 0;
if (progress != NULL)
if (progress)
{
RINOK(progress->SetRatioInfo(&_inSizeProcessed, &_outSizeProcessed));
UInt64 inSize = _inSizeProcessed - startInProgress;
RINOK(progress->SetRatioInfo(&inSize, &_outSizeProcessed));
}
}
}
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
SetOutStreamSize(outSize);
return CodeSpec(inStream, outStream, progress);
}
#ifndef NO_READ_FROM_CODER
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
@@ -185,6 +198,42 @@ STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
return S_OK;
}
HRESULT CDecoder::CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress)
{
SetOutStreamSizeResume(outSize);
return CodeSpec(_inStream, outStream, progress);
}
HRESULT CDecoder::ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize)
{
RINOK(CreateInputBuffer());
if (processedSize)
*processedSize = 0;
while (size > 0)
{
if (_inPos == _inSize)
{
_inPos = _inSize = 0;
RINOK(_inStream->Read(_inBuf, kInBufSize, &_inSize));
if (_inSize == 0)
break;
}
{
UInt32 curSize = _inSize - _inPos;
if (curSize > size)
curSize = size;
memcpy(data, _inBuf + _inPos, curSize);
_inPos += curSize;
_inSizeProcessed += curSize;
size -= curSize;
data = (Byte *)data + curSize;
if (processedSize)
*processedSize += curSize;
}
}
return S_OK;
}
#endif
}}

View File

@@ -3,10 +3,7 @@
#ifndef __LZMA_DECODER_H
#define __LZMA_DECODER_H
extern "C"
{
#include "../../../C/LzmaDec.h"
}
#include "../../Common/MyCom.h"
#include "../ICoder.h"
@@ -17,7 +14,6 @@ namespace NLzma {
class CDecoder:
public ICompressCoder,
public ICompressSetDecoderProperties2,
public ICompressGetInStreamProcessedSize,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
@@ -30,35 +26,42 @@ class CDecoder:
UInt32 _inPos;
UInt32 _inSize;
CLzmaDec _state;
bool _propsWereSet;
bool _outSizeDefined;
UInt64 _outSize;
UInt64 _inSizeProcessed;
UInt64 _outSizeProcessed;
public:
HRESULT CreateInputBuffer();
HRESULT CodeSpec(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress);
void SetOutStreamSizeResume(const UInt64 *outSize);
public:
MY_QUERYINTERFACE_BEGIN
MY_QUERYINTERFACE_ENTRY(ICompressSetDecoderProperties2)
#ifndef NO_READ_FROM_CODER
MY_UNKNOWN_IMP5(
ICompressSetDecoderProperties2,
ICompressGetInStreamProcessedSize,
ICompressSetInStream,
ICompressSetOutStreamSize,
ISequentialInStream)
#else
MY_UNKNOWN_IMP2(
ICompressSetDecoderProperties2,
ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
#ifndef NO_READ_FROM_CODER
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
HRESULT ReadFromInputStream(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetInputProcessedSize() const { return _inSizeProcessed; }
#endif
bool FinishStream;

View File

@@ -2,49 +2,16 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../Common/CWrappers.h"
#include "../Common/StreamUtils.h"
#include "LzmaEncoder.h"
static HRESULT SResToHRESULT(SRes res)
{
switch(res)
{
case SZ_OK: return S_OK;
case SZ_ERROR_MEM: return E_OUTOFMEMORY;
case SZ_ERROR_PARAM: return E_INVALIDARG;
// case SZ_ERROR_THREAD: return E_FAIL;
}
return E_FAIL;
}
namespace NCompress {
namespace NLzma {
static const UInt32 kStreamStepSize = (UInt32)1 << 31;
static SRes MyRead(void *object, void *data, size_t *size)
{
UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
HRESULT res = ((CSeqInStream *)object)->RealStream->Read(data, curSize, &curSize);
*size = curSize;
return (SRes)res;
}
static size_t MyWrite(void *object, const void *data, size_t size)
{
CSeqOutStream *p = (CSeqOutStream *)object;
p->Res = WriteStream(p->RealStream, data, size);
if (p->Res != 0)
return 0;
return size;
}
static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
static void SzBigFree(void *, void *address) { BigFree(address); }
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
@@ -55,8 +22,6 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree };
CEncoder::CEncoder()
{
_seqInStream.SeqInStream.Read = MyRead;
_seqOutStream.SeqOutStream.Write = MyWrite;
_encoder = 0;
_encoder = LzmaEnc_Create(&g_Alloc);
if (_encoder == 0)
@@ -108,6 +73,31 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
return 1;
}
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
{
if (propID == NCoderPropID::kMatchFinder)
{
if (prop.vt != VT_BSTR)
return E_INVALIDARG;
return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
}
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
switch (propID)
{
case NCoderPropID::kNumFastBytes: ep.fb = v; break;
case NCoderPropID::kMatchFinderCycles: ep.mc = v; break;
case NCoderPropID::kAlgorithm: ep.algo = v; break;
case NCoderPropID::kDictionarySize: ep.dictSize = v; break;
case NCoderPropID::kPosStateBits: ep.pb = v; break;
case NCoderPropID::kLitPosBits: ep.lp = v; break;
case NCoderPropID::kLitContextBits: ep.lc = v; break;
default: return E_INVALIDARG;
}
return S_OK;
}
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
const PROPVARIANT *coderProps, UInt32 numProps)
{
@@ -117,34 +107,15 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = coderProps[i];
switch (propIDs[i])
PROPID propID = propIDs[i];
switch (propID)
{
case NCoderPropID::kNumFastBytes:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.fb = prop.ulVal; break;
case NCoderPropID::kMatchFinderCycles:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.mc = prop.ulVal; break;
case NCoderPropID::kAlgorithm:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.algo = prop.ulVal; break;
case NCoderPropID::kDictionarySize:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.dictSize = prop.ulVal; break;
case NCoderPropID::kPosStateBits:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.pb = prop.ulVal; break;
case NCoderPropID::kLitPosBits:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.lp = prop.ulVal; break;
case NCoderPropID::kLitContextBits:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.lc = prop.ulVal; break;
case NCoderPropID::kNumThreads:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break;
case NCoderPropID::kMultiThread:
if (prop.vt != VT_BOOL) return E_INVALIDARG; props.numThreads = ((prop.boolVal == VARIANT_TRUE) ? 2 : 1); break;
case NCoderPropID::kEndMarker:
if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break;
case NCoderPropID::kMatchFinder:
if (prop.vt != VT_BSTR) return E_INVALIDARG;
if (!ParseMatchFinder(prop.bstrVal, &props.btMode, &props.numHashBytes /* , &_matchFinderBase.skipModeBits */))
return E_INVALIDARG; break;
case NCoderPropID::kNumThreads:
if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break;
default:
return E_INVALIDARG;
RINOK(SetLzmaProp(propID, prop, props));
}
}
return SResToHRESULT(LzmaEnc_SetProps(_encoder, &props));
@@ -158,53 +129,20 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
return WriteStream(outStream, props, size);
}
STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
{
_seqOutStream.RealStream = outStream;
_seqOutStream.Res = S_OK;
return S_OK;
}
STDMETHODIMP CEncoder::ReleaseOutStream()
{
_seqOutStream.RealStream.Release();
return S_OK;
}
typedef struct _CCompressProgressImp
{
ICompressProgress p;
ICompressProgressInfo *Progress;
HRESULT Res;
} CCompressProgressImp;
#define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1)
#define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize)
{
CCompressProgressImp *p = (CCompressProgressImp *)pp;
p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
return (SRes)p->Res;
}
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
CCompressProgressImp progressImp;
progressImp.p.Progress = CompressProgress;
progressImp.Progress = progress;
progressImp.Res = SZ_OK;
CSeqInStreamWrap inWrap(inStream);
CSeqOutStreamWrap outWrap(outStream);
CCompressProgressWrap progressWrap(progress);
_seqInStream.RealStream = inStream;
SetOutStream(outStream);
SRes res = LzmaEnc_Encode(_encoder, &_seqOutStream.SeqOutStream, &_seqInStream.SeqInStream, progress ? &progressImp.p : NULL, &g_Alloc, &g_BigAlloc);
ReleaseOutStream();
if (res == SZ_ERROR_WRITE && _seqOutStream.Res != S_OK)
return _seqOutStream.Res;
if (res == SZ_ERROR_PROGRESS && progressImp.Res != S_OK)
return progressImp.Res;
SRes res = LzmaEnc_Encode(_encoder, &outWrap.p, &inWrap.p, progress ? &progressWrap.p : NULL, &g_Alloc, &g_BigAlloc);
if (res == SZ_ERROR_READ && inWrap.Res != S_OK)
return inWrap.Res;
if (res == SZ_ERROR_WRITE && outWrap.Res != S_OK)
return outWrap.Res;
if (res == SZ_ERROR_PROGRESS && progressWrap.Res != S_OK)
return progressWrap.Res;
return SResToHRESULT(res);
}

View File

@@ -3,10 +3,7 @@
#ifndef __LZMA_ENCODER_H
#define __LZMA_ENCODER_H
extern "C"
{
#include "../../../C/LzmaEnc.h"
}
#include "../../Common/MyCom.h"
@@ -15,47 +12,22 @@ extern "C"
namespace NCompress {
namespace NLzma {
struct CSeqInStream
{
ISeqInStream SeqInStream;
ISequentialInStream *RealStream;
};
struct CSeqOutStream
{
ISeqOutStream SeqOutStream;
CMyComPtr<ISequentialOutStream> RealStream;
HRESULT Res;
};
class CEncoder :
class CEncoder:
public ICompressCoder,
public ICompressSetOutStream,
public ICompressSetCoderProperties,
public ICompressWriteCoderProperties,
public CMyUnknownImp
{
CLzmaEncHandle _encoder;
CSeqInStream _seqInStream;
CSeqOutStream _seqOutStream;
public:
CEncoder();
MY_UNKNOWN_IMP3(
ICompressSetOutStream,
ICompressSetCoderProperties,
ICompressWriteCoderProperties
)
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
STDMETHOD(ReleaseOutStream)();
CEncoder();
virtual ~CEncoder();
};

View File

@@ -1,5 +1,6 @@
// PpmdContext.h
// This code is based on Dmitry Shkarin's PPMdH code
// 2009-05-30 : Igor Pavlov : Public domain
// This code is based on Dmitry Shkarin's PPMdH code (public domain)
#ifndef __COMPRESS_PPMD_CONTEXT_H
#define __COMPRESS_PPMD_CONTEXT_H

View File

@@ -1,5 +1,6 @@
// PpmdDecode.h
// This code is based on Dmitry Shkarin's PPMdH code
// 2009-05-30 : Igor Pavlov : Public domain
// This code is based on Dmitry Shkarin's PPMdH code (public domain)
#ifndef __COMPRESS_PPMD_DECODE_H
#define __COMPRESS_PPMD_DECODE_H

View File

@@ -1,4 +1,5 @@
// PpmdDecoder.cpp
// 2009-05-30 : Igor Pavlov : Public domain
#include "StdAfx.h"

View File

@@ -1,4 +1,5 @@
// PpmdDecoder.h
// 2009-05-30 : Igor Pavlov : Public domain
#ifndef __COMPRESS_PPMD_DECODER_H
#define __COMPRESS_PPMD_DECODER_H

View File

@@ -1,5 +1,6 @@
// PpmdEncode.h
// This code is based on Dmitry Shkarin's PPMdH code
// 2009-05-30 : Igor Pavlov : Public domain
// This code is based on Dmitry Shkarin's PPMdH code (public domain)
#ifndef __COMPRESS_PPMD_ENCODE_H
#define __COMPRESS_PPMD_ENCODE_H

View File

@@ -1,4 +1,5 @@
// PpmdEncoder.cpp
// 2009-05-30 : Igor Pavlov : Public domain
#include "StdAfx.h"

View File

@@ -1,4 +1,5 @@
// PpmdEncoder.h
// 2009-05-30 : Igor Pavlov : Public domain
#ifndef __COMPRESS_PPMD_ENCODER_H
#define __COMPRESS_PPMD_ENCODER_H

View File

@@ -1,4 +1,5 @@
// PpmdRegister.cpp
// 2009-05-30 : Igor Pavlov : Public domain
#include "StdAfx.h"

View File

@@ -1,13 +1,11 @@
// PpmdSubAlloc.h
// This code is based on Dmitry Shkarin's PPMdH code
// 2009-05-30 : Igor Pavlov : Public domain
// This code is based on Dmitry Shkarin's PPMdH code (public domain)
#ifndef __COMPRESS_PPMD_SUB_ALLOC_H
#define __COMPRESS_PPMD_SUB_ALLOC_H
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "PpmdType.h"

View File

@@ -1,12 +1,6 @@
/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2001 *
* Contents: compilation parameters and miscelaneous definitions *
* Comments: system & compiler dependent file
* modified by Igor Pavlov (2004-08-29).
****************************************************************************/
// PpmdType.h
// 2009-05-30 : Igor Pavlov : Public domain
// This code is based on Dmitry Shkarin's PPMdH code (public domain)
#ifndef __COMPRESS_PPMD_TYPE_H
#define __COMPRESS_PPMD_TYPE_H

View File

@@ -1,4 +1,5 @@
// Compress/RangeCoder.h
// 2009-05-30 : Igor Pavlov : Public domain
#ifndef __COMPRESS_RANGE_CODER_H
#define __COMPRESS_RANGE_CODER_H

View File

@@ -1,4 +1,5 @@
// Compress/RangeCoderBit.h
// 2009-05-30 : Igor Pavlov : Public domain
#ifndef __COMPRESS_RANGE_CODER_BIT_H
#define __COMPRESS_RANGE_CODER_BIT_H

View File

@@ -12,11 +12,8 @@ Note:
#include "StdAfx.h"
extern "C"
{
#include "../../../C/7zCrc.h"
#include "../../../C/Alloc.h"
}
#include "Rar3Vm.h"

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../Common/InBuffer.h"
#include "../Common/OutBuffer.h"

View File

@@ -2,10 +2,7 @@
#include "StdAfx.h"
extern "C"
{
#include "../../../C/Alloc.h"
}
#include "../Common/InBuffer.h"
#include "../Common/OutBuffer.h"