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

📄 ppmdcontext.h

📁 seven zip源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
// Compress/PPMD/Context.h
// This code is based on Dmitry Shkarin's PPMdH code

#ifndef __COMPRESS_PPMD_CONTEXT_H
#define __COMPRESS_PPMD_CONTEXT_H

#include "../../../Common/Types.h"

#include "../RangeCoder/RangeCoder.h"
#include "PPMDSubAlloc.h"

namespace NCompress {
namespace NPPMD {

const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
        INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;

struct SEE2_CONTEXT 
{   
  // SEE-contexts for PPM-contexts with masked symbols
  UInt16 Summ;
  Byte Shift, Count;
  void init(int InitVal) { Summ = (UInt16)(InitVal << (Shift=PERIOD_BITS-4)); Count=4; }
  unsigned int getMean() 
  {
    unsigned int RetVal=(Summ >> Shift);        
    Summ = (UInt16)(Summ - RetVal);
    return RetVal+(RetVal == 0);
  }
  void update() 
  {
    if (Shift < PERIOD_BITS && --Count == 0) 
    {
      Summ <<= 1;                   
      Count = (Byte)(3 << Shift++);
    }
  }
};

struct PPM_CONTEXT 
{
  UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte) 
  UInt16 SummFreq;
  
  struct STATE 
  { 
    Byte Symbol, Freq; 
    UInt16 SuccessorLow;
    UInt16 SuccessorHigh;

    UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); }
    void SetSuccessor(UInt32 v) 
    { 
      SuccessorLow = (UInt16)(v & 0xFFFF);
      SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF);
    }
  };
  
  UInt32 Stats;
  UInt32 Suffix;
  
  PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState)
  {
    PPM_CONTEXT* pc = (PPM_CONTEXT*) subAllocator.AllocContext();
    if (pc) 
    {
      pc->NumStats = 1;                     
      pc->oneState() = FirstState;
      pc->Suffix = subAllocator.GetOffset(this);                    
      pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc));
    }
    return pc;
  }

  STATE& oneState() const { return (STATE&) SummFreq; }
};

/////////////////////////////////

const UInt16 InitBinEsc[] =
  {0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};

struct CInfo
{
  CSubAllocator SubAllocator;
  SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
  PPM_CONTEXT * MinContext, * MaxContext;

  PPM_CONTEXT::STATE* FoundState;      // found next state transition
  int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder;
  Byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
  Byte EscCount, PrintCount, PrevSuccess, HiBitsFlag;
  UInt16 BinSumm[128][64];               // binary SEE-contexts

  UInt16 &GetBinSumm(const PPM_CONTEXT::STATE &rs, int numStates)
  {
    HiBitsFlag = HB2Flag[FoundState->Symbol];
    return BinSumm[rs.Freq - 1][
         PrevSuccess + NS2BSIndx[numStates - 1] +
         HiBitsFlag + 2 * HB2Flag[rs.Symbol] + 
         ((RunLength >> 26) & 0x20)];
  }

  PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); }
  PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); }
  PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); }
  PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); }

  void RestartModelRare()
  {
    int i, k, m;
    memset(CharMask,0,sizeof(CharMask));
    SubAllocator.InitSubAllocator();                     
    InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1;
    MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext();
    MinContext->Suffix = 0;                
    OrderFall = MaxOrder;
    MinContext->SummFreq = (UInt16)((MinContext->NumStats = 256) + 1);
    FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2);
    MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState);
    PrevSuccess = 0;
    for (RunLength = InitRL, i = 0; i < 256; i++) 
    {
      PPM_CONTEXT::STATE &state = FoundState[i];
      state.Symbol = (Byte)i;      
      state.Freq = 1;
      state.SetSuccessor(0);
    }
    for (i = 0; i < 128; i++)
        for (k = 0; k < 8; k++)
            for ( m=0; m < 64; m += 8)
                BinSumm[i][k + m] = (UInt16)(BIN_SCALE - InitBinEsc[k] / (i + 2));
    for (i = 0; i < 25; i++)
        for (k = 0; k < 16; k++)            
            SEE2Cont[i][k].init(5*i+10);
  }

  void StartModelRare(int maxOrder)
  {
    int i, k, m ,Step;
    EscCount=PrintCount=1;
    if (maxOrder < 2) 
    {
        memset(CharMask,0,sizeof(CharMask));
        OrderFall = MaxOrder;               
        MinContext = MaxContext;
        while (MinContext->Suffix != 0) 
        {
          MinContext = GetContextNoCheck(MinContext->Suffix);  
          OrderFall--;
        }
        FoundState = GetState(MinContext->Stats);
        MinContext = MaxContext;
    } 
    else 
    {
        MaxOrder = maxOrder;                
        RestartModelRare();
        NS2BSIndx[0] = 2 * 0;                   
        NS2BSIndx[1] = 2 * 1;
        memset(NS2BSIndx + 2, 2 * 2, 9);          
        memset(NS2BSIndx + 11, 2 * 3, 256 - 11);
        for (i = 0; i < 3; i++)                 
          NS2Indx[i] = (Byte)i;
        for (m = i, k = Step = 1; i < 256; i++) 
        {
            NS2Indx[i] = (Byte)m;
            if ( !--k ) 
            { 
              k = ++Step;       
              m++; 
            }
        }
        memset(HB2Flag, 0, 0x40);             
        memset(HB2Flag + 0x40, 0x08, 0x100 - 0x40);
        DummySEE2Cont.Shift = PERIOD_BITS;
    }
  }

  PPM_CONTEXT* CreateSuccessors(bool skip, PPM_CONTEXT::STATE* p1)
  {
    // static UpState declaration bypasses IntelC bug
    // static PPM_CONTEXT::STATE UpState;
    PPM_CONTEXT::STATE UpState;

    PPM_CONTEXT *pc = MinContext;
    PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor());
    PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps;
    if ( !skip ) 
    {
        *pps++ = FoundState;
        if ( !pc->Suffix )                  
          goto NO_LOOP;
    }
    if ( p1 ) 
    {
        p = p1;                               
        pc = GetContext(pc->Suffix);
        goto LOOP_ENTRY;
    }
    do 
    {
        pc = GetContext(pc->Suffix);
        if (pc->NumStats != 1) 
        {
            if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol)
                do { p++; } while (p->Symbol != FoundState->Symbol);
        } 
        else                              
          p = &(pc->oneState());
LOOP_ENTRY:
        if (GetContext(p->GetSuccessor()) != UpBranch) 
        {
            pc = GetContext(p->GetSuccessor());                
            break;
        }
        *pps++ = p;
    } 
    while ( pc->Suffix );
NO_LOOP:
    if (pps == ps)                          
      return pc;
    UpState.Symbol = *(Byte*) UpBranch;
    UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1);
    if (pc->NumStats != 1) 
    {
        if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol)
                do { p++; } while (p->Symbol != UpState.Symbol);
        unsigned int cf = p->Freq-1;
        unsigned int s0 = pc->SummFreq - pc->NumStats - cf;
        UpState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : 
            ((2 * cf + 3 * s0 - 1) / (2 * s0))));
    } 
    else                                  
      UpState.Freq = pc->oneState().Freq;
    do 
    {
        pc = pc->createChild(SubAllocator, *--pps, UpState);
        if ( !pc )                          
          return NULL;
    } 
    while (pps != ps);
    return pc;
  }

⌨️ 快捷键说明

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