Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Ppmd7Dec.c
Go to the documentation of this file.
1 /* Ppmd7Dec.c -- PPMdH Decoder
2 2017-04-03 : Igor Pavlov : Public domain
3 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
4 
5 #include "Precomp.h"
6 
7 #include "Ppmd7.h"
8 
9 #define kTopValue (1 << 24)
10 
12 {
13  unsigned i;
14  p->Code = 0;
15  p->Range = 0xFFFFFFFF;
16  if (IByteIn_Read(p->Stream) != 0)
17  return False;
18  for (i = 0; i < 4; i++)
19  p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
20  return (p->Code < 0xFFFFFFFF);
21 }
22 
23 #define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
24 
26 {
28  return p->Code / (p->Range /= total);
29 }
30 
32 {
33  if (p->Range < kTopValue)
34  {
35  p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
36  p->Range <<= 8;
37  if (p->Range < kTopValue)
38  {
39  p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
40  p->Range <<= 8;
41  }
42  }
43 }
44 
45 static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
46 {
48  p->Code -= start * p->Range;
49  p->Range *= size;
50  Range_Normalize(p);
51 }
52 
53 static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
54 {
56  UInt32 newBound = (p->Range >> 14) * size0;
57  UInt32 symbol;
58  if (p->Code < newBound)
59  {
60  symbol = 0;
61  p->Range = newBound;
62  }
63  else
64  {
65  symbol = 1;
66  p->Code -= newBound;
67  p->Range -= newBound;
68  }
69  Range_Normalize(p);
70  return symbol;
71 }
72 
74 {
76  p->vt.Decode = Range_Decode;
78 }
79 
80 
81 #define MASK(sym) ((signed char *)charMask)[sym]
82 
84 {
85  size_t charMask[256 / sizeof(size_t)];
86  if (p->MinContext->NumStats != 1)
87  {
89  unsigned i;
90  UInt32 count, hiCnt;
91  if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
92  {
93  Byte symbol;
94  rc->Decode(rc, 0, s->Freq);
95  p->FoundState = s;
96  symbol = s->Symbol;
97  Ppmd7_Update1_0(p);
98  return symbol;
99  }
100  p->PrevSuccess = 0;
101  i = p->MinContext->NumStats - 1;
102  do
103  {
104  if ((hiCnt += (++s)->Freq) > count)
105  {
106  Byte symbol;
107  rc->Decode(rc, hiCnt - s->Freq, s->Freq);
108  p->FoundState = s;
109  symbol = s->Symbol;
110  Ppmd7_Update1(p);
111  return symbol;
112  }
113  }
114  while (--i);
115  if (count >= p->MinContext->SummFreq)
116  return -2;
117  p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
118  rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
119  PPMD_SetAllBitsIn256Bytes(charMask);
120  MASK(s->Symbol) = 0;
121  i = p->MinContext->NumStats - 1;
122  do { MASK((--s)->Symbol) = 0; } while (--i);
123  }
124  else
125  {
126  UInt16 *prob = Ppmd7_GetBinSumm(p);
127  if (rc->DecodeBit(rc, *prob) == 0)
128  {
129  Byte symbol;
130  *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
131  symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
132  Ppmd7_UpdateBin(p);
133  return symbol;
134  }
135  *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
136  p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
137  PPMD_SetAllBitsIn256Bytes(charMask);
138  MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
139  p->PrevSuccess = 0;
140  }
141  for (;;)
142  {
143  CPpmd_State *ps[256], *s;
144  UInt32 freqSum, count, hiCnt;
145  CPpmd_See *see;
146  unsigned i, num, numMasked = p->MinContext->NumStats;
147  do
148  {
149  p->OrderFall++;
150  if (!p->MinContext->Suffix)
151  return -1;
153  }
154  while (p->MinContext->NumStats == numMasked);
155  hiCnt = 0;
156  s = Ppmd7_GetStats(p, p->MinContext);
157  i = 0;
158  num = p->MinContext->NumStats - numMasked;
159  do
160  {
161  int k = (int)(MASK(s->Symbol));
162  hiCnt += (s->Freq & k);
163  ps[i] = s++;
164  i -= k;
165  }
166  while (i != num);
167 
168  see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
169  freqSum += hiCnt;
170  count = rc->GetThreshold(rc, freqSum);
171 
172  if (count < hiCnt)
173  {
174  Byte symbol;
175  CPpmd_State **pps = ps;
176  for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
177  s = *pps;
178  rc->Decode(rc, hiCnt - s->Freq, s->Freq);
179  Ppmd_See_Update(see);
180  p->FoundState = s;
181  symbol = s->Symbol;
182  Ppmd7_Update2(p);
183  return symbol;
184  }
185  if (count >= freqSum)
186  return -2;
187  rc->Decode(rc, hiCnt, freqSum - hiCnt);
188  see->Summ = (UInt16)(see->Summ + freqSum);
189  do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
190  }
191 }