⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppmdencoder.cpp

📁 压缩软件源码
💻 CPP
字号:
// Compress/Associative/Encoder.h

#include "StdAfx.h"

#include "Windows/Defs.h"

// #include <fstream.h>
// #include <iomanip.h>

#include "Common/Defs.h"

#include "PPMDEncoder.h"

namespace NCompress {
namespace NPPMD {

const UInt32 kMinMemSize = (1 << 11); 
const UInt32 kMinOrder = 2;

/*
UInt32 g_NumInner = 0;
UInt32 g_InnerCycles = 0;

UInt32 g_Encode2 = 0;
UInt32 g_Encode2Cycles = 0;
UInt32 g_Encode2Cycles2 = 0;

class CCounter
{
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;


/*
// ISetRangeEncoder
STDMETHODIMP CEncoder::SetRangeEncoder(CRangeEncoder *aRangeEncoder)
{
  _rangeEncoder = aRangeEncoder;
  RINOK(_rangeEncoder.QueryInterface(&m_InitOutCoder));

  return S_OK;
}
*/

STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, 
    const PROPVARIANT *properties, UInt32 numProperties)
{
  for (UInt32 i = 0; i < numProperties; i++)
  {
    const PROPVARIANT &aProperty = properties[i];
    switch(propIDs[i])
    {
      case NCoderPropID::kUsedMemorySize:
        if (aProperty.vt != VT_UI4)
          return E_INVALIDARG;
        if (aProperty.ulVal < kMinMemSize)
          return E_INVALIDARG;
        _usedMemorySize = aProperty.ulVal;
        break;
      case NCoderPropID::kOrder:
        if (aProperty.vt != VT_UI4)
          return E_INVALIDARG;
        if (aProperty.ulVal < kMinOrder || aProperty.ulVal > kMaxOrderCompress)
          return E_INVALIDARG;
        _order = Byte(aProperty.ulVal);
        break;
      default:
        return E_INVALIDARG;
    }
  }
  return S_OK;
}

STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{ 
  const UInt32 kPropSize = 5;
  Byte properties[kPropSize];
  properties[0] = _order;
  for (int i = 0; i < 4; i++)
    properties[1 + i] = Byte(_usedMemorySize >> (8 * i));
  return outStream->Write(properties, kPropSize, NULL);
}

const UInt32 kUsedMemorySizeDefault = (1 << 24);
const int kOrderDefault = 6;

CEncoder::CEncoder():
  _usedMemorySize(kUsedMemorySizeDefault),
  _order(kOrderDefault)
{
  // SubAllocator.StartSubAllocator(kSubAllocator);
}


HRESULT CEncoder::Flush()
{
  _rangeEncoder.FlushData();
  return _rangeEncoder.FlushStream();
}

class CEncoderFlusher
{
  CEncoder *_encoder;
public:
  CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {}
  ~CEncoderFlusher()
  {
    _encoder->Flush();
    _encoder->ReleaseStreams();
  }
};



HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
      ISequentialOutStream *outStream, 
      const UInt64 *inSize, const UInt64 *outSize,
      ICompressProgressInfo *progress)
{
  if (!_inStream.Create(1 << 20))
    return E_OUTOFMEMORY;
  if (!_rangeEncoder.Create(1 << 20))
    return E_OUTOFMEMORY;

  _inStream.SetStream(inStream);
  _inStream.Init();
  _rangeEncoder.SetStream(outStream);
  _rangeEncoder.Init();

  CEncoderFlusher flusher(this);

  UInt64 pos = 0;
  UInt64 prevProgressPos = 0;

  try
  {
    if ( !_info.SubAllocator.StartSubAllocator(_usedMemorySize) ) 
      return E_OUTOFMEMORY;
  }
  catch(...)
  {
    return E_OUTOFMEMORY;
  }


  _info.MaxOrder = 0;
  _info.StartModelRare(_order);


  while (true)
  {
    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);   
    pos++;
    if (pos - prevProgressPos >= (1 << 18) && progress != NULL)
    {
      UInt64 outSize = _rangeEncoder.GetProcessedSize();
      RINOK(progress->SetRatioInfo(&pos, &outSize));
      prevProgressPos = pos;
    }
  }
}

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; }
}

}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -