Пример #1
0
HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
    const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
  if (!_inBuf)
  {
    _inBuf = (Byte *)::MidAlloc(kBufSize);
    if (!_inBuf)
      return E_OUTOFMEMORY;
  }
  if (!_outStream.Alloc(1 << 20))
    return E_OUTOFMEMORY;
  if (!Ppmd7_Alloc(&_ppmd, _props.MemSize, &g_BigAlloc))
    return E_OUTOFMEMORY;

  _outStream.Stream = outStream;
  _outStream.Init();

  Ppmd7z_RangeEnc_Init(&_rangeEnc);
  Ppmd7_Init(&_ppmd, _props.Order);

  UInt64 processed = 0;
  for (;;)
  {
    UInt32 size;
    RINOK(inStream->Read(_inBuf, kBufSize, &size));
    if (size == 0)
    {
      // We don't write EndMark in PPMD-7z.
      // Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, -1);
      Ppmd7z_RangeEnc_FlushData(&_rangeEnc);
      return _outStream.Flush();
    }
    for (UInt32 i = 0; i < size; i++)
    {
      Ppmd7_EncodeSymbol(&_ppmd, &_rangeEnc, _inBuf[i]);
      RINOK(_outStream.Res);
    }
    processed += size;
    if (progress)
    {
      UInt64 outSize = _outStream.GetProcessed();
      RINOK(progress->SetRatioInfo(&processed, &outSize));
    }
  }
}
HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size)
{
  switch(_status)
  {
    case kStatus_Finished: return S_OK;
    case kStatus_Error: return S_FALSE;
    case kStatus_NeedInit:
      _inStream.Init();
      if (!Ppmd7z_RangeDec_Init(&_rangeDec))
      {
        _status = kStatus_Error;
        return S_FALSE;
      }
      _status = kStatus_Normal;
      Ppmd7_Init(&_ppmd, _order);
      break;
  }
  if (_outSizeDefined)
  {
    const UInt64 rem = _outSize - _processedSize;
    if (size > rem)
      size = (UInt32)rem;
  }

  UInt32 i;
  int sym = 0;
  for (i = 0; i != size; i++)
  {
    sym = Ppmd7_DecodeSymbol(&_ppmd, &_rangeDec.p);
    if (_inStream.Extra || sym < 0)
      break;
    memStream[i] = (Byte)sym;
  }

  _processedSize += i;
  if (_inStream.Extra)
  {
    _status = kStatus_Error;
    return _inStream.Res;
  }
  if (sym < 0)
    _status = (sym < -1) ? kStatus_Error : kStatus_Finished;
  return S_OK;
}