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

📄 ppmdcontext.h

📁 seven zip源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
  void UpdateModel()
  {
    PPM_CONTEXT::STATE fs = *FoundState, * p = NULL;
    PPM_CONTEXT* pc, * Successor;
    unsigned int ns1, ns, cf, sf, s0;
    if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0) 
    {
        pc = GetContextNoCheck(MinContext->Suffix);
      
        if (pc->NumStats != 1) 
        {
            if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol) 
            {
                do { p++; } while (p->Symbol != fs.Symbol);
                if (p[0].Freq >= p[-1].Freq) 
                {
                    _PPMD_SWAP(p[0],p[-1]); 
                    p--;
                }
            }
            if (p->Freq < MAX_FREQ-9) 
            {
                p->Freq += 2;               
                pc->SummFreq += 2;
            }
        } 
        else 
        {
            p = &(pc->oneState());            
            p->Freq = (Byte)(p->Freq + ((p->Freq < 32) ? 1 : 0));
        }
    }
    if ( !OrderFall ) 
    {
        MinContext = MaxContext = CreateSuccessors(true, p);
        FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext));
        if (MinContext == 0)                  
          goto RESTART_MODEL;
        return;
    }
    *SubAllocator.pText++ = fs.Symbol;                   
    Successor = (PPM_CONTEXT*) SubAllocator.pText;
    if (SubAllocator.pText >= SubAllocator.UnitsStart)                
      goto RESTART_MODEL;
    if (fs.GetSuccessor() != 0) 
    {
        if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText)
        {
          PPM_CONTEXT* cs = CreateSuccessors(false, p);
          fs.SetSuccessor(SubAllocator.GetOffset(cs));
          if (cs == NULL)
            goto RESTART_MODEL;
        }
        if ( !--OrderFall ) 
        {
            Successor = GetContext(fs.GetSuccessor());
            SubAllocator.pText -= (MaxContext != MinContext);
        }
    } 
    else 
    {
        FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor));    
        fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext));
    }
    s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1);
    for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix)) 
    {
        if ((ns1 = pc->NumStats) != 1) 
        {
            if ((ns1 & 1) == 0) 
            {
                void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1);
                pc->Stats = SubAllocator.GetOffset(ppp);
                if (!ppp)           
                  goto RESTART_MODEL;
            }
            pc->SummFreq = (UInt16)(pc->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) &
                    (pc->SummFreq <= 8 * ns1)));
        } 
        else 
        {
            p = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(1);
            if ( !p )                       
              goto RESTART_MODEL;
            *p = pc->oneState();              
            pc->Stats = SubAllocator.GetOffsetNoCheck(p);
            if (p->Freq < MAX_FREQ / 4 - 1)     
              p->Freq <<= 1;
            else                            
              p->Freq  = MAX_FREQ - 4;
            pc->SummFreq = (UInt16)(p->Freq + InitEsc + (ns > 3));
        }
        cf = 2 * fs.Freq * (pc->SummFreq+6);      
        sf = s0 + pc->SummFreq;
        if (cf < 6 * sf) 
        {
            cf = 1 + (cf > sf)+(cf >= 4 * sf);
            pc->SummFreq += 3;
        } 
        else 
        {
            cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
            pc->SummFreq = (UInt16)(pc->SummFreq + cf);
        }
        p = GetState(pc->Stats) + ns1;                    
        p->SetSuccessor(SubAllocator.GetOffset(Successor));
        p->Symbol = fs.Symbol;              
        p->Freq = (Byte)cf;
        pc->NumStats = (UInt16)++ns1;
    }
    MaxContext = MinContext = GetContext(fs.GetSuccessor());
    return;
RESTART_MODEL:
    RestartModelRare();
    EscCount = 0;               
    PrintCount = 0xFF;
  }

  void ClearMask()
  {
    EscCount = 1;                             
    memset(CharMask, 0, sizeof(CharMask));
    // if (++PrintCount == 0)                  
    //   PrintInfo(DecodedFile,EncodedFile);
  }

  void update1(PPM_CONTEXT::STATE* p)
  {
    (FoundState = p)->Freq += 4;              
    MinContext->SummFreq += 4;
    if (p[0].Freq > p[-1].Freq) 
    {
        _PPMD_SWAP(p[0],p[-1]);             
        FoundState = --p;
        if (p->Freq > MAX_FREQ)             
          rescale();
    }
  }


  void update2(PPM_CONTEXT::STATE* p)
  {
    (FoundState = p)->Freq += 4;
    MinContext->SummFreq += 4;
    if (p->Freq > MAX_FREQ)                 
      rescale();
    EscCount++;                             
    RunLength = InitRL;
  }
  
  SEE2_CONTEXT* makeEscFreq2(int Diff, UInt32 &scale)
  {
    SEE2_CONTEXT* psee2c;
    if (MinContext->NumStats != 256) 
    {
      psee2c = SEE2Cont[NS2Indx[Diff-1]] + 
        (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) +
        2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 
        4 * (NumMasked > Diff) + 
        HiBitsFlag;
      scale = psee2c->getMean();
    } 
    else 
    {
      psee2c = &DummySEE2Cont;              
      scale = 1;
    }
    return psee2c;
  }



  void rescale()
  {
    int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq;
    PPM_CONTEXT::STATE* p1, * p;
    PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats);
    for (p = FoundState; p != stats; p--)       
      _PPMD_SWAP(p[0], p[-1]);
    stats->Freq += 4;                       
    MinContext->SummFreq += 4;
    EscFreq = MinContext->SummFreq - p->Freq;               
    Adder = (OrderFall != 0);
    p->Freq = (Byte)((p->Freq + Adder) >> 1);
    MinContext->SummFreq = p->Freq;
    do 
    {
        EscFreq -= (++p)->Freq;
        p->Freq = (Byte)((p->Freq + Adder) >> 1);
        MinContext->SummFreq = (UInt16)(MinContext->SummFreq + p->Freq);
        if (p[0].Freq > p[-1].Freq) 
        {
            PPM_CONTEXT::STATE tmp = *(p1 = p);
            do 
            { 
              p1[0] = p1[-1]; 
            } 
            while (--p1 != stats && tmp.Freq > p1[-1].Freq);
            *p1 = tmp;
        }
    } 
    while ( --i );
    if (p->Freq == 0) 
    {
        do { i++; } while ((--p)->Freq == 0);
        EscFreq += i;
        MinContext->NumStats = (UInt16)(MinContext->NumStats - i);
        if (MinContext->NumStats == 1) 
        {
            PPM_CONTEXT::STATE tmp = *stats;
            do { tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); EscFreq >>= 1; } while (EscFreq > 1);
            SubAllocator.FreeUnits(stats, (OldNS+1) >> 1);
            *(FoundState = &MinContext->oneState()) = tmp;  return;
        }
    }
    EscFreq -= (EscFreq >> 1);
    MinContext->SummFreq = (UInt16)(MinContext->SummFreq + EscFreq);
    int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1;
    if (n0 != n1)
      MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1));
    FoundState = GetState(MinContext->Stats);
  }

  void NextContext()
  {
    PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor());
    if (!OrderFall && (Byte *)c > SubAllocator.pText)
      MinContext = MaxContext = c;
    else 
    {
      UpdateModel();
      if (EscCount == 0)              
        ClearMask();
    }
  }
};

// Tabulated escapes for exponential symbol distribution
const Byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))

}}

#endif

⌨️ 快捷键说明

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