diff src/win32/7zip/7z/CPP/7zip/Compress/PpmdDecode.h @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/PpmdDecode.h	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,154 @@
     1.4 +// PpmdDecode.h
     1.5 +// This code is based on Dmitry Shkarin's PPMdH code
     1.6 +
     1.7 +#ifndef __COMPRESS_PPMD_DECODE_H
     1.8 +#define __COMPRESS_PPMD_DECODE_H
     1.9 +
    1.10 +#include "PpmdContext.h"
    1.11 +
    1.12 +namespace NCompress {
    1.13 +namespace NPpmd {
    1.14 +
    1.15 +class CRangeDecoderVirt
    1.16 +{
    1.17 +public:
    1.18 +  virtual UInt32 GetThreshold(UInt32 total) = 0;
    1.19 +  virtual void Decode(UInt32 start, UInt32 size) = 0;
    1.20 +  virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) = 0;
    1.21 +};
    1.22 +
    1.23 +typedef NRangeCoder::CDecoder CRangeDecoderMy;
    1.24 +
    1.25 +class CRangeDecoder:public CRangeDecoderVirt, public CRangeDecoderMy
    1.26 +{
    1.27 +  UInt32 GetThreshold(UInt32 total) { return CRangeDecoderMy::GetThreshold(total); }
    1.28 +  void Decode(UInt32 start, UInt32 size) { CRangeDecoderMy::Decode(start, size); }
    1.29 +  UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) { return CRangeDecoderMy::DecodeBit(size0, numTotalBits); }
    1.30 +};
    1.31 +
    1.32 +struct CDecodeInfo: public CInfo
    1.33 +{
    1.34 +  void DecodeBinSymbol(CRangeDecoderVirt *rangeDecoder)
    1.35 +  {
    1.36 +    PPM_CONTEXT::STATE& rs = MinContext->oneState();
    1.37 +    UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats);
    1.38 +    if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0)
    1.39 +    {
    1.40 +      FoundState = &rs;
    1.41 +      rs.Freq = (Byte)(rs.Freq + (rs.Freq < 128 ? 1: 0));
    1.42 +      bs = (UInt16)(bs + INTERVAL - GET_MEAN(bs, PERIOD_BITS, 2));
    1.43 +      PrevSuccess = 1;
    1.44 +      RunLength++;
    1.45 +    }
    1.46 +    else
    1.47 +    {
    1.48 +      bs = (UInt16)(bs - GET_MEAN(bs, PERIOD_BITS, 2));
    1.49 +      InitEsc = ExpEscape[bs >> 10];
    1.50 +      NumMasked = 1;
    1.51 +      CharMask[rs.Symbol] = EscCount;
    1.52 +      PrevSuccess = 0;
    1.53 +      FoundState = NULL;
    1.54 +    }
    1.55 +  }
    1.56 +
    1.57 +  void DecodeSymbol1(CRangeDecoderVirt *rangeDecoder)
    1.58 +  {
    1.59 +    PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats);
    1.60 +    int i, count, hiCnt;
    1.61 +    if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq))
    1.62 +    {
    1.63 +      PrevSuccess = (2 * hiCnt > MinContext->SummFreq);
    1.64 +      RunLength += PrevSuccess;
    1.65 +      rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq);
    1.66 +      (FoundState = p)->Freq = (Byte)(hiCnt += 4);
    1.67 +      MinContext->SummFreq += 4;
    1.68 +      if (hiCnt > MAX_FREQ)
    1.69 +        rescale();
    1.70 +      return;
    1.71 +    }
    1.72 +    PrevSuccess = 0;
    1.73 +    i = MinContext->NumStats - 1;
    1.74 +    while ((hiCnt += (++p)->Freq) <= count)
    1.75 +      if (--i == 0)
    1.76 +      {
    1.77 +        HiBitsFlag = HB2Flag[FoundState->Symbol];
    1.78 +        rangeDecoder->Decode(hiCnt, MinContext->SummFreq - hiCnt); // , MinContext->SummFreq);
    1.79 +        CharMask[p->Symbol] = EscCount;
    1.80 +        i = (NumMasked = MinContext->NumStats)-1;
    1.81 +        FoundState = NULL;
    1.82 +        do { CharMask[(--p)->Symbol] = EscCount; } while ( --i );
    1.83 +        return;
    1.84 +      }
    1.85 +    rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , MinContext->SummFreq);
    1.86 +    update1(p);
    1.87 +  }
    1.88 +
    1.89 +
    1.90 +  void DecodeSymbol2(CRangeDecoderVirt *rangeDecoder)
    1.91 +  {
    1.92 +    int count, hiCnt, i = MinContext->NumStats - NumMasked;
    1.93 +    UInt32 freqSum;
    1.94 +    SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum);
    1.95 +    PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1;
    1.96 +    hiCnt = 0;
    1.97 +    do
    1.98 +    {
    1.99 +      do { p++; } while (CharMask[p->Symbol] == EscCount);
   1.100 +      hiCnt += p->Freq;
   1.101 +      *pps++ = p;
   1.102 +    }
   1.103 +    while ( --i );
   1.104 +    
   1.105 +    freqSum += hiCnt;
   1.106 +    count = rangeDecoder->GetThreshold(freqSum);
   1.107 +    
   1.108 +    p = *(pps = ps);
   1.109 +    if (count < hiCnt)
   1.110 +    {
   1.111 +      hiCnt = 0;
   1.112 +      while ((hiCnt += p->Freq) <= count)
   1.113 +        p=*++pps;
   1.114 +      rangeDecoder->Decode(hiCnt - p->Freq, p->Freq); // , freqSum);
   1.115 +      
   1.116 +      psee2c->update();
   1.117 +      update2(p);
   1.118 +    }
   1.119 +    else
   1.120 +    {
   1.121 +      rangeDecoder->Decode(hiCnt, freqSum - hiCnt); // , freqSum);
   1.122 +      
   1.123 +      i = MinContext->NumStats - NumMasked;
   1.124 +      pps--;
   1.125 +      do { CharMask[(*++pps)->Symbol] = EscCount; } while ( --i );
   1.126 +      psee2c->Summ = (UInt16)(psee2c->Summ + freqSum);
   1.127 +      NumMasked = MinContext->NumStats;
   1.128 +    }
   1.129 +  }
   1.130 +
   1.131 +  int DecodeSymbol(CRangeDecoderVirt *rangeDecoder)
   1.132 +  {
   1.133 +    if (MinContext->NumStats != 1)
   1.134 +      DecodeSymbol1(rangeDecoder);
   1.135 +    else
   1.136 +      DecodeBinSymbol(rangeDecoder);
   1.137 +    while ( !FoundState )
   1.138 +    {
   1.139 +      do
   1.140 +      {
   1.141 +        OrderFall++;
   1.142 +        MinContext = GetContext(MinContext->Suffix);
   1.143 +        if (MinContext == 0)
   1.144 +          return -1;
   1.145 +      }
   1.146 +      while (MinContext->NumStats == NumMasked);
   1.147 +      DecodeSymbol2(rangeDecoder);
   1.148 +    }
   1.149 +    Byte symbol = FoundState->Symbol;
   1.150 +    NextContext();
   1.151 +    return symbol;
   1.152 +  }
   1.153 +};
   1.154 +
   1.155 +}}
   1.156 +
   1.157 +#endif