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

📄 ppmddecode.h

📁 7-Zip 是一款号称有着现今最高压缩比的压缩软件
💻 H
字号:
// PPMDDecode.h
// This code is based on Dmitry Shkarin's PPMdH code

#ifndef __COMPRESS_PPMD_DECODE_H
#define __COMPRESS_PPMD_DECODE_H

#include "PPMDContext.h"

namespace NCompress {
namespace NPPMD {

class CRangeDecoderVirt
{
public:
  virtual UInt32 GetThreshold(UInt32 total) = 0;
  virtual void Decode(UInt32 start, UInt32 size) = 0;
  virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0;
};

typedef NRangeCoder::CDecoder CRangeDecoderMy;

class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy
{
  UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); }
  void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); }
  UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); }
};

struct CDecodeInfo: public CInfo
{
  void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder)
  {
    PPM_CONTEXT::STATE& rs = MinContext->oneState();
    UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
    if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
    {
      FoundState = &rs;
      rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0));
      bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2));
      PrevSuccess = 1;
      RunLength++;
    }
    else
    {
      bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2));
      InitEsc = ExpEscape[bs >> 10];
      NumMasked = 1;
      CharMask[rs.Symbol] = EscCount;
      PrevSuccess = 0;
      FoundState = NULL;
    }
  }

  void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder)
  {
    PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
    int i, count, hiCnt;
    if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq))
    {
      PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
      RunLength += PrevSuccess;
      rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq);
      (FoundState = p)->Freq = (Byte)(hiCnt += 4);
      MinContext->SummFreq += 4;
      if (hiCnt > MAX_FREQ)
        rescale();
      return;
    }
    PrevSuccess = 0;
    i = MinContext->NumStats - 1;
    while ((hiCnt += (++p)->Freq) <= count)
      if (--i == 0)
      {
        HiBitsFlag = HB2Flag[FoundState->Symbol];
        rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq);
        CharMask[p->Symbol] = EscCount;
        i = (NumMasked = MinContext->NumStats)-1;
        FoundState = NULL;
        do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
        return;
      }
    rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq);
    update1(p);
  }


  void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder)
  {
    int count, hiCnt, i = MinContext->NumStats - NumMasked;
    UInt32 freqSum;
    SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
    PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1;
    hiCnt = 0;
    do
    {
      do { p++; } while (CharMask[p->Symbol] == EscCount);
      hiCnt += p->Freq;
      *pps++ = p;
    }
    while ( --i );
    
    freqSum += hiCnt;
    count = rangeDecoder->GetThreshold(freqSum);
    
    p = *(pps = ps);
    if (count < hiCnt)
    {
      hiCnt = 0;
      while ((hiCnt += p->Freq) <= count)
        p=*++pps;
      rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum);
      
      psee2c->update();
      update2(p);
    }
    else
    {
      rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
      
      i = MinContext->NumStats - NumMasked;
      pps--;
      do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i );
      psee2c->Summ = (UInt16)(psee2c->Summ + freqSum);
      NumMasked = MinContext->NumStats;
    }
  }

  int DecodeSymbol(CRangeDecoderVirt *rangeDecoder)
  {
    if (MinContext->NumStats != 1)
      DecodeSymbol1(rangeDecoder);
    else
      DecodeBinSymbol(rangeDecoder);
    while ( !FoundState )
    {
      do
      {
        OrderFall++;
        MinContext = GetContext(MinContext->Suffix);
        if (MinContext == 0)
          return -1;
      }
      while (MinContext->NumStats == NumMasked);
      DecodeSymbol2(rangeDecoder);
    }
    Byte symbol = FoundState->Symbol;
    NextContext();
    return symbol;
  }
};

}}

#endif

⌨️ 快捷键说明

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