mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 06:07:07 -06:00
9.04 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
8874e4fbc9
commit
829409452d
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
#include "Bcj2Coder.h"
|
||||
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
#ifndef __COMPRESS_BCJ_CODER_H
|
||||
#define __COMPRESS_BCJ_CODER_H
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Bra.h"
|
||||
}
|
||||
|
||||
#include "BranchCoder.h"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Bra.h"
|
||||
}
|
||||
|
||||
#include "BranchMisc.h"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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[];
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -2,11 +2,8 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Alloc.h"
|
||||
#include "../../../C/HuffEnc.h"
|
||||
}
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
|
||||
@@ -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
112
CPP/7zip/Compress/DeltaFilter.cpp
Executable 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)
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -26,6 +26,7 @@ WIN_OBJS = \
|
||||
$O\System.obj
|
||||
|
||||
7ZIP_COMMON_OBJS = \
|
||||
$O\CWrappers.obj \
|
||||
$O\InBuffer.obj \
|
||||
$O\OutBuffer.obj \
|
||||
$O\StreamUtils.obj \
|
||||
|
||||
189
CPP/7zip/Compress/Lzma2Decoder.cpp
Executable file
189
CPP/7zip/Compress/Lzma2Decoder.cpp
Executable 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
|
||||
|
||||
}}
|
||||
73
CPP/7zip/Compress/Lzma2Decoder.h
Executable file
73
CPP/7zip/Compress/Lzma2Decoder.h
Executable 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
|
||||
94
CPP/7zip/Compress/Lzma2Encoder.cpp
Executable file
94
CPP/7zip/Compress/Lzma2Encoder.cpp
Executable 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);
|
||||
}
|
||||
|
||||
}}
|
||||
36
CPP/7zip/Compress/Lzma2Encoder.h
Executable file
36
CPP/7zip/Compress/Lzma2Encoder.h
Executable 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
|
||||
20
CPP/7zip/Compress/Lzma2Register.cpp
Executable file
20
CPP/7zip/Compress/Lzma2Register.cpp
Executable 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)
|
||||
@@ -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
|
||||
|
||||
}}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// PpmdDecoder.cpp
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// PpmdDecoder.h
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
|
||||
#ifndef __COMPRESS_PPMD_DECODER_H
|
||||
#define __COMPRESS_PPMD_DECODER_H
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// PpmdEncoder.cpp
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// PpmdEncoder.h
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
|
||||
#ifndef __COMPRESS_PPMD_ENCODER_H
|
||||
#define __COMPRESS_PPMD_ENCODER_H
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// PpmdRegister.cpp
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Compress/RangeCoder.h
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
|
||||
#ifndef __COMPRESS_RANGE_CODER_H
|
||||
#define __COMPRESS_RANGE_CODER_H
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,11 +12,8 @@ Note:
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/7zCrc.h"
|
||||
#include "../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
#include "Rar3Vm.h"
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
#include "../Common/InBuffer.h"
|
||||
#include "../Common/OutBuffer.h"
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Alloc.h"
|
||||
}
|
||||
|
||||
#include "../Common/InBuffer.h"
|
||||
#include "../Common/OutBuffer.h"
|
||||
|
||||
Reference in New Issue
Block a user