mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 17:15:00 -06:00
9.11
This commit is contained in:
committed by
Kornel Lesiński
parent
db5eb6d638
commit
993daef9cb
@@ -1,10 +1,10 @@
|
||||
// PpmdEncoder.cpp
|
||||
// 2009-05-30 : Igor Pavlov : Public domain
|
||||
// 2009-03-11 : Igor Pavlov : Public domain
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #include <fstream.h>
|
||||
// #include <iomanip.h>
|
||||
#include "../../../C/Alloc.h"
|
||||
#include "../../../C/CpuArch.h"
|
||||
|
||||
#include "../Common/StreamUtils.h"
|
||||
|
||||
@@ -13,55 +13,46 @@
|
||||
namespace NCompress {
|
||||
namespace NPpmd {
|
||||
|
||||
const UInt32 kMinMemSize = (1 << 11);
|
||||
const UInt32 kMinOrder = 2;
|
||||
static const UInt32 kBufSize = (1 << 20);
|
||||
|
||||
/*
|
||||
UInt32 g_NumInner = 0;
|
||||
UInt32 g_InnerCycles = 0;
|
||||
static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
|
||||
static void SzBigFree(void *, void *address) { BigFree(address); }
|
||||
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
|
||||
|
||||
UInt32 g_Encode2 = 0;
|
||||
UInt32 g_Encode2Cycles = 0;
|
||||
UInt32 g_Encode2Cycles2 = 0;
|
||||
|
||||
class CCounter
|
||||
CEncoder::CEncoder():
|
||||
_inBuf(NULL),
|
||||
_usedMemSize(1 << 24),
|
||||
_order(6)
|
||||
{
|
||||
public:
|
||||
CCounter() {}
|
||||
~CCounter()
|
||||
{
|
||||
ofstream ofs("Res.dat");
|
||||
ofs << "innerEncode1 = " << setw(10) << g_NumInner << endl;
|
||||
ofs << "g_InnerCycles = " << setw(10) << g_InnerCycles << endl;
|
||||
ofs << "g_Encode2 = " << setw(10) << g_Encode2 << endl;
|
||||
ofs << "g_Encode2Cycles = " << setw(10) << g_Encode2Cycles << endl;
|
||||
ofs << "g_Encode2Cycles2= " << setw(10) << g_Encode2Cycles2 << endl;
|
||||
|
||||
}
|
||||
};
|
||||
CCounter g_Counter;
|
||||
*/
|
||||
_rangeEnc.Stream = &_outStream.p;
|
||||
Ppmd7_Construct(&_ppmd);
|
||||
}
|
||||
|
||||
CEncoder::~CEncoder()
|
||||
{
|
||||
::MidFree(_inBuf);
|
||||
Ppmd7_Free(&_ppmd, &g_BigAlloc);
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
|
||||
{
|
||||
for (UInt32 i = 0; i < numProps; i++)
|
||||
{
|
||||
const PROPVARIANT &prop = props[i];
|
||||
if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
UInt32 v = (UInt32)prop.ulVal;
|
||||
switch(propIDs[i])
|
||||
{
|
||||
case NCoderPropID::kUsedMemorySize:
|
||||
if (prop.vt != VT_UI4)
|
||||
if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0)
|
||||
return E_INVALIDARG;
|
||||
if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize)
|
||||
return E_INVALIDARG;
|
||||
_usedMemorySize = (UInt32)prop.ulVal;
|
||||
_usedMemSize = v;
|
||||
break;
|
||||
case NCoderPropID::kOrder:
|
||||
if (prop.vt != VT_UI4)
|
||||
if (v < 2 || v > 32)
|
||||
return E_INVALIDARG;
|
||||
if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress)
|
||||
return E_INVALIDARG;
|
||||
_order = (Byte)prop.ulVal;
|
||||
_order = (Byte)v;
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
@@ -75,74 +66,54 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
|
||||
const UInt32 kPropSize = 5;
|
||||
Byte props[kPropSize];
|
||||
props[0] = _order;
|
||||
for (int i = 0; i < 4; i++)
|
||||
props[1 + i] = Byte(_usedMemorySize >> (8 * i));
|
||||
SetUi32(props + 1, _usedMemSize);
|
||||
return WriteStream(outStream, props, kPropSize);
|
||||
}
|
||||
|
||||
const UInt32 kUsedMemorySizeDefault = (1 << 24);
|
||||
const int kOrderDefault = 6;
|
||||
|
||||
CEncoder::CEncoder():
|
||||
_usedMemorySize(kUsedMemorySizeDefault),
|
||||
_order(kOrderDefault)
|
||||
HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
|
||||
{
|
||||
if (!_inStream.Create(1 << 20))
|
||||
if (!_inBuf)
|
||||
{
|
||||
_inBuf = (Byte *)::MidAlloc(kBufSize);
|
||||
if (!_inBuf)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (!_outStream.Alloc(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_rangeEncoder.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize))
|
||||
if (!Ppmd7_Alloc(&_ppmd, _usedMemSize, &g_BigAlloc))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
_inStream.SetStream(inStream);
|
||||
_inStream.Init();
|
||||
_outStream.Stream = outStream;
|
||||
_outStream.Init();
|
||||
|
||||
_rangeEncoder.SetStream(outStream);
|
||||
_rangeEncoder.Init();
|
||||
|
||||
CEncoderFlusher flusher(this);
|
||||
|
||||
_info.MaxOrder = 0;
|
||||
_info.StartModelRare(_order);
|
||||
Ppmd7z_RangeEnc_Init(&_rangeEnc);
|
||||
Ppmd7_Init(&_ppmd, _order);
|
||||
|
||||
UInt64 processed = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 size = (1 << 18);
|
||||
do
|
||||
UInt32 size;
|
||||
RINOK(inStream->Read(_inBuf, kBufSize, &size));
|
||||
if (size == 0)
|
||||
{
|
||||
Byte symbol;
|
||||
if (!_inStream.ReadByte(symbol))
|
||||
{
|
||||
// here we can write End Mark for stream version.
|
||||
// In current version this feature is not used.
|
||||
// _info.EncodeSymbol(-1, &_rangeEncoder);
|
||||
return S_OK;
|
||||
}
|
||||
_info.EncodeSymbol(symbol, &_rangeEncoder);
|
||||
// We don't write EndMark in PPMD-7z.
|
||||
// Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1);
|
||||
Ppmd7z_RangeEnc_FlushData(&_rangeEnc);
|
||||
return _outStream.Flush();
|
||||
}
|
||||
while (--size != 0);
|
||||
if (progress != NULL)
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
UInt64 inSize = _inStream.GetProcessedSize();
|
||||
UInt64 outSize = _rangeEncoder.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &outSize));
|
||||
Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]);
|
||||
RINOK(_outStream.Res);
|
||||
}
|
||||
processed += size;
|
||||
if (progress)
|
||||
{
|
||||
UInt64 outSize = _outStream.GetProcessed();
|
||||
RINOK(progress->SetRatioInfo(&processed, &outSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const COutBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return E_FAIL; }
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user