1 /*-------------------------------------------------*/
2 /* GRZipII/libGRZip compressor           WFC_Ari.c */
3 /* RLE + WFC + Entropy Coder Functions             */
4 /*-------------------------------------------------*/
5 
6 /*--
7   This file is a part of GRZipII and/or libGRZip, a program
8   and library for lossless, block-sorting data compression.
9 
10   Copyright (C) 2002-2003 Grebnov Ilya. All rights reserved.
11 
12   This library is free software; you can redistribute it and/or
13   modify it under the terms of the GNU Lesser General Public
14   License as published by the Free Software Foundation; either
15   version 2.1 of the License, or (at your option) any later version.
16 
17   This library is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20   Lesser General Public License for more details.
21 
22   Grebnov Ilya, Ivanovo, Russian Federation.
23   Ilya.Grebnov@magicssoft.ru, http://magicssoft.ru/
24 
25   This program is based on (at least) the work of:
26   Juergen Abel, Jon L. Bentley, Edgar Binder,
27   Charles Bloom, Mike Burrows, Andrey Cadach,
28   Damien Debin, Sebastian Deorowicz, Peter Fenwick,
29   Michael Schindler, Robert Sedgewick, Julian Seward,
30   David Wheeler, Vadim Yoockin.
31 
32   For more information on these sources, see the manual.
33 --*/
34 
35 #include <stdlib.h>
36 #include "libGRZip.h"
37 #include "WFC_MTF.h"
38 
39 #define ARI_MaxByte            256
40 #define WFC_MaxByte            256
41 
42 #define WFC_Val0               131072
43 #define WFC_Val1               114688
44 #define WFC_Val2               7272
45 #define WFC_Val3               4240
46 #define WFC_Val4               2364
47 #define WFC_Val5               1263
48 #define WFC_Val6               649
49 #define WFC_Val7               320
50 #define WFC_Val8               153
51 #define WFC_Val9               70
52 #define WFC_Val10              31
53 #define WFC_Val11              14
54 #define WFC_Val12              8
55 
56 #define WFC_Pos1               1
57 #define WFC_Pos2               2
58 #define WFC_Pos3               4
59 #define WFC_Pos4               8
60 #define WFC_Pos5               16
61 #define WFC_Pos6               32
62 #define WFC_Pos7               64
63 #define WFC_Pos8               128
64 #define WFC_Pos9               256
65 #define WFC_Pos10              512
66 #define WFC_Pos11              1024
67 #define WFC_Pos12              2048
68 
69 #define WFC_Init()                                    \
70   uint8 * WFCBuf=(uint8 *)malloc(Size);               \
71   if (WFCBuf==NULL) return (GRZ_NOT_ENOUGH_MEMORY);   \
72                                                       \
73   sint32  WFC_List[WFC_MaxByte+1];                    \
74   sint32  Char2Index[WFC_MaxByte+1];                  \
75   sint32  CharWeight[WFC_MaxByte+1];                  \
76                                                       \
77   sint32  WFCBufPos=0;                                \
78                                                       \
79   for (i=0;i<=WFC_MaxByte;i++)                        \
80   {                                                   \
81     WFC_List[i]=Char2Index[i]=i;                      \
82     CharWeight[i]=0;                                  \
83   }                                                   \
84   CharWeight[WFC_MaxByte]=-1;                         \
85 
86 #define WFC_Finish()  free(WFCBuf);                   \
87 
88 #define Update_Weight0(c)                             \
89 {                                                     \
90   CharWeight[c]+=WFC_Val0;                            \
91   sint32 j=Char2Index[c];                             \
92   if (j>0) do {                                       \
93     Char2Index[WFC_List[j]=WFC_List[j-1]]=j;          \
94   } while (--j);                                      \
95   WFC_List[0]=c;                                      \
96   Char2Index[c]=0;                                    \
97 }
98 
99 #define Update_Weight(c,Weight)                       \
100 {                                                     \
101   sint32 W=(CharWeight[c]-=Weight);                   \
102   if (c!=Char)                                        \
103   {                                                   \
104     sint32  j=Char2Index[c];                          \
105     sint32* List=&WFC_List[j+1];                      \
106     while (CharWeight[*List]>W)                       \
107      {                                                \
108        Char2Index[List[-1]=*List]=j++;                \
109        List++;                                        \
110      }                                                \
111     WFC_List[j]=c;                                    \
112     Char2Index[c]=j;                                  \
113   }                                                   \
114 }
115 
116 #define Update_Weight_Full(Weight,Pos)                \
117   if (WFCBufPos>=Pos)                                 \
118   {                                                   \
119     uint8 c=WFCBuf[WFCBufPos-Pos];                    \
120     Update_Weight(c,Weight);                          \
121   }                                                   \
122 
123 #define ARI_RangeTOP           (1<<24)
124 
125 #define ARI_OutTgtByte(B)      (*Output++=B)
126 
127 #define Model_NumBits          11
128 #define Model_MaxFreq          (1<<Model_NumBits)
129 
130 #define M_Log2RLE_Shift_0      6
131 #define M_Log2RLE_Shift_1      3
132 #define M_Log2RLE_Shift_2      6
133 
134 #define M_L1_Shift_0           4
135 #define M_L1_Shift_1           6
136 
137 #define M_L2_Shift             7
138 
139 #define ModelL0_0MaxFreq       58
140 #define ModelL0_1MaxFreq       62
141 #define ModelL0_2MaxFreq       204
142 
143 #define ARI_ShiftLow()                              \
144 {                                                   \
145   if ((Low^0xFF000000)>0xFFFFFF)                    \
146   {                                                 \
147     ARI_OutTgtByte((uint8)(Cache+(Low>>32)));       \
148     sint32 c = (sint32)(0xFF+(Low>>32));            \
149     while (FFNum) ARI_OutTgtByte(c), FFNum--;       \
150     Cache = (uint32)(Low)>>24;                      \
151   } else FFNum++;                                   \
152   Low = (uint32)(Low)<<8;                           \
153 }
154 
155 #define UpdateVCtx_1(P,NumShiftBits)                \
156 {                                                   \
157   VCtx[P]-=(VCtx[P]>>NumShiftBits);                 \
158 }
159 
160 #define UpdateVCtx_0(P,NumShiftBits)                \
161 {                                                   \
162   VCtx[P]+=((Model_MaxFreq-VCtx[P])>>NumShiftBits); \
163 }
164 
165 #define UpdateUCtx_1(P,NumShiftBits)                \
166 {                                                   \
167   UCtx[P]-=(UCtx[P]>>NumShiftBits);                 \
168 }
169 
170 #define UpdateUCtx_0(P,NumShiftBits)                \
171 {                                                   \
172   UCtx[P]+=((Model_MaxFreq-UCtx[P])>>NumShiftBits); \
173 }
174 
175 #define Update_Model_L0()                           \
176 {                                                   \
177   if (Model_L0_0[4]>ModelL0_0MaxFreq)               \
178   {                                                 \
179     sint32 Sum=(Model_L0_0[0]=(Model_L0_0[0]+1)>>1);\
180     Sum+=(Model_L0_0[1]=(Model_L0_0[1]+1)>>1);      \
181     Sum+=(Model_L0_0[2]=(Model_L0_0[2]+1)>>1);      \
182     Sum+=(Model_L0_0[3]=(Model_L0_0[3]+1)>>1);      \
183     Model_L0_0[4]=Sum;                              \
184   }                                                 \
185   if (VCtx[4]>ModelL0_1MaxFreq)                     \
186   {                                                 \
187     sint32 Sum=(VCtx[0]>>=1);                       \
188     Sum+=(VCtx[1]>>=1);Sum+=(VCtx[2]>>=1);          \
189     Sum+=(VCtx[3]>>=1);VCtx[4]=Sum;                 \
190   }                                                 \
191   if (UCtx[4]>ModelL0_2MaxFreq)                     \
192   {                                                 \
193     sint32 Sum=(UCtx[0]>>=1);                       \
194     Sum+=(UCtx[1]>>=1);Sum+=(UCtx[2]>>=1);          \
195     Sum+=(UCtx[3]>>=1);UCtx[4]=Sum;                 \
196   }                                                 \
197 }                                                   \
198 
199 #define Init_Models()                               \
200                                                     \
201   uint32  Model_L0_0[5];                            \
202   uint32  Model_L0_1[ARI_MaxByte][5];               \
203   uint32  Model_L0_2[4*ARI_MaxByte][5];             \
204                                                     \
205   uint32  Model_L1_0[8];                            \
206   uint32  Model_L1_1[8][8];                         \
207                                                     \
208   uint32  Model_L2_0[8][128];                       \
209                                                     \
210   uint32  Model_Log2RLE_0[64][GRZ_Log2MaxBlockSize+1];\
211   uint32  Model_Log2RLE_2[GRZ_Log2MaxBlockSize+1][GRZ_Log2MaxBlockSize+1];\
212                                                     \
213   uint32* Model_Log2RLE_1;                          \
214                                                     \
215   sint32 i,j,CtxRLE=0,CtxL0=0,CtxL1=0,CtxL2;        \
216                                                     \
217   WFC_Init()                                        \
218                                                     \
219   Model_Log2RLE_1=(uint32*)malloc(ARI_MaxByte*(GRZ_Log2MaxBlockSize+1)*sizeof(uint32));\
220   if (Model_Log2RLE_1==NULL) {WFC_Finish();return (GRZ_NOT_ENOUGH_MEMORY);}\
221                                                     \
222   Model_L0_0[0]=Model_L0_0[1]=1;                    \
223   Model_L0_0[2]=Model_L0_0[3]=1;                    \
224   Model_L0_0[4]=4;                                  \
225                                                     \
226   Model_L1_0[0]=Model_L1_0[1]=Model_MaxFreq>>1;     \
227   Model_L1_0[2]=Model_L1_0[3]=Model_MaxFreq>>1;     \
228   Model_L1_0[4]=Model_L1_0[5]=Model_MaxFreq>>1;     \
229   Model_L1_0[6]=Model_L1_0[7]=Model_MaxFreq>>1;     \
230                                                     \
231   memset(Model_L0_1,0,5*ARI_MaxByte*sizeof(uint32));\
232   memset(Model_L0_2,0,4*5*ARI_MaxByte*sizeof(uint32));\
233                                                     \
234   for (i=0;i<8;i++)                                 \
235     for (j=0;j<128;j++)                             \
236       Model_L2_0[i][j]=Model_MaxFreq>>1;            \
237                                                     \
238   for (i=0;i<7;i++)                                 \
239   {                                                 \
240     Model_L1_1[i][0]=Model_L1_1[i][1]=Model_MaxFreq>>1;\
241     Model_L1_1[i][2]=Model_L1_1[i][3]=Model_MaxFreq>>1;\
242     Model_L1_1[i][4]=Model_L1_1[i][5]=Model_MaxFreq>>1;\
243     Model_L1_1[i][6]=Model_L1_1[i][7]=Model_MaxFreq>>1;\
244   }                                                 \
245                                                     \
246   for (j=0;j<64;j++)                                \
247     for (i=0;i<=GRZ_Log2MaxBlockSize;i++)           \
248       Model_Log2RLE_0[j][i]=Model_MaxFreq>>1;       \
249                                                     \
250   for (j=0;j<=GRZ_Log2MaxBlockSize;j++)             \
251     for (i=0;i<=GRZ_Log2MaxBlockSize;i++)           \
252       Model_Log2RLE_2[j][i]=Model_MaxFreq>>1;       \
253                                                     \
254   uint32* VCtx;                                     \
255   uint32* UCtx;                                     \
256                                                     \
257   for (UCtx=Model_Log2RLE_1,i=0;i<ARI_MaxByte;i++)  \
258     for (j=0;j<=GRZ_Log2MaxBlockSize;j++)           \
259       *UCtx++=Model_MaxFreq>>1;                     \
260 
GRZip_WFC_Ari_Encode(uint8 * Input,sint32 Size,uint8 * Output)261 sint32 GRZip_WFC_Ari_Encode(uint8* Input,sint32 Size,uint8* Output)
262 {
263   uint8 * InputEnd=Input+Size;
264   uint8 * OutputEnd=Output+Size-24;
265 
266   sint64 Low=0;
267   uint32 FFNum=0;
268   uint32 Cache=0;
269   uint32 Range=(uint32)(-1);
270 
271 #define ARI_Encode(TFreq,TCumFreq,TTotFreq)                \
272 {                                                          \
273   Low+=((sint32)TCumFreq)*(Range/=((sint32)TTotFreq));     \
274   Range*=(sint32)TFreq;                                    \
275   while(Range<ARI_RangeTOP) {ARI_ShiftLow();Range<<=8;}    \
276 }                                                          \
277 
278 #define ARI_Encode_0(FFreq0)                               \
279 {                                                          \
280   ARI_Encode(((sint32)FFreq0),0,Model_MaxFreq)             \
281 }                                                          \
282 
283 #define ARI_Encode_1(FFreq0)                               \
284 {                                                          \
285   sint32 FTFreq0=FFreq0;                                   \
286   ARI_Encode(Model_MaxFreq-FTFreq0,FTFreq0,Model_MaxFreq)  \
287 }                                                          \
288 
289   Init_Models();
290 
291   uint32 Mask=0,Log2RunSize,RunSize,WFCMTF_Rank,PredChar,Char=0;
292 
293   while (Input<InputEnd)
294   {
295 
296     if (Output>=OutputEnd)
297     {
298       WFC_Finish();
299       free(Model_Log2RLE_1);
300       return (GRZ_NOT_COMPRESSIBLE);
301     }
302 
303     PredChar=Char; Char=*Input++;
304 
305     RunSize=1;
306     while ((Input<InputEnd)&&(*Input==Char)) RunSize++,Input++;
307 
308     WFCBuf[WFCBufPos]=Char; WFCMTF_Rank=Char2Index[Char];
309     Update_Weight0(Char);
310     Update_Weight_Full(WFC_Val1,WFC_Pos1);
311     Update_Weight_Full(WFC_Val2,WFC_Pos2);
312     Update_Weight_Full(WFC_Val3,WFC_Pos3);
313     Update_Weight_Full(WFC_Val4,WFC_Pos4);
314     Update_Weight_Full(WFC_Val5,WFC_Pos5);
315     Update_Weight_Full(WFC_Val6,WFC_Pos6);
316     Update_Weight_Full(WFC_Val7,WFC_Pos7);
317     Update_Weight_Full(WFC_Val8,WFC_Pos8);
318     Update_Weight_Full(WFC_Val9,WFC_Pos9);
319     Update_Weight_Full(WFC_Val10,WFC_Pos10);
320     Update_Weight_Full(WFC_Val11,WFC_Pos11);
321     Update_Weight_Full(WFC_Val12,WFC_Pos12);
322 
323     WFCBufPos++;
324 
325     WFCMTF_Rank=(WFCMTF_Rank-1)&0xFF;
326 
327     VCtx=&Model_L0_1[PredChar][0]; UCtx=&Model_L0_2[4*CtxL0+(CtxRLE&3)][0];
328 
329     if (WFCMTF_Rank<3)
330      {
331        uint32 Tmp,Cum=0;
332        for (Tmp=0;Tmp<WFCMTF_Rank;Tmp++) Cum+=UCtx[Tmp]+VCtx[Tmp]+Model_L0_0[Tmp];
333        ARI_Encode(Model_L0_0[WFCMTF_Rank]+UCtx[WFCMTF_Rank]+VCtx[WFCMTF_Rank],Cum,
334                   Model_L0_0[4]+UCtx[4]+VCtx[4]);
335 
336        Model_L0_0[WFCMTF_Rank]+=2;UCtx[WFCMTF_Rank]+=2;VCtx[WFCMTF_Rank]+=2;
337        Model_L0_0[4]+=2;UCtx[4]+=2;VCtx[4]+=2;
338        Update_Model_L0();
339      }
340     else
341      {
342        uint32 Cum=Model_L0_0[4]+UCtx[4]+VCtx[4]-Model_L0_0[3]-UCtx[3]-VCtx[3];
343        ARI_Encode(Model_L0_0[3]+UCtx[3]+VCtx[3],Cum,
344                   Model_L0_0[4]+UCtx[4]+VCtx[4]);
345 
346        Model_L0_0[3]+=2;UCtx[3]+=2;VCtx[3]+=2;
347        Model_L0_0[4]+=2;UCtx[4]+=2;VCtx[4]+=2;
348        Update_Model_L0();
349 
350        sint32 Mask,GrNum,GrPos;
351 
352        GrNum=WFCMTF_Rank2GrNum[WFCMTF_Rank];
353        GrPos=WFCMTF_Rank2GrPos[WFCMTF_Rank]; Mask=WFCMTF_Rank2Mask[WFCMTF_Rank];
354 
355        VCtx=Model_L1_0; UCtx=&Model_L1_1[CtxL1][0]; CtxL1=GrNum;
356 
357        for (i=0;i<GrNum;i++)
358        {
359          ARI_Encode_1((VCtx[0]+UCtx[0])>>1);
360          UpdateVCtx_1(0,M_L1_Shift_0); UpdateUCtx_1(0,M_L1_Shift_1);
361          VCtx++;UCtx++;
362        }
363 
364        if (GrNum!=6)
365        {
366          ARI_Encode_0((VCtx[0]+UCtx[0])>>1);
367          UpdateVCtx_0(0,M_L1_Shift_0); UpdateUCtx_0(0,M_L1_Shift_1);
368        }
369 
370        VCtx=&Model_L2_0[GrNum][0];
371 
372        for (CtxL2=1,i=0;i<=GrNum;i++,Mask>>=1)
373          if (GrPos&Mask)
374           {
375             ARI_Encode_1(VCtx[CtxL2]);
376             UpdateVCtx_1(CtxL2,M_L2_Shift);
377             CtxL2=(CtxL2<<1)|1;
378           }
379          else
380           {
381             ARI_Encode_0(VCtx[CtxL2]);
382             UpdateVCtx_0(CtxL2,M_L2_Shift);
383             CtxL2<<=1;
384           }
385      }
386 
387     if (WFCMTF_Rank>3) WFCMTF_Rank=3;
388     CtxL0=((CtxL0<<2)|WFCMTF_Rank)&0xFF;
389 
390     sint32 Tmp=RunSize;
391 
392     if (Tmp==1) Log2RunSize=0;
393     else
394      {
395        Log2RunSize=1;Mask=1;
396        while (1)
397        {
398          if ((Tmp>>=1)==1) break;
399          Log2RunSize++;Mask<<=1;
400        }
401      }
402 
403     VCtx=&Model_Log2RLE_0[CtxRLE+16*WFCMTF_Rank][0];
404     UCtx=Model_Log2RLE_1+Char*(GRZ_Log2MaxBlockSize+1);
405 
406     for (i=0;i<Log2RunSize;i++)
407     {
408       ARI_Encode_1((VCtx[0]+UCtx[0])>>1);
409       UpdateVCtx_1(0,M_Log2RLE_Shift_0); UpdateUCtx_1(0,M_Log2RLE_Shift_1);
410       VCtx++;UCtx++;
411     }
412 
413     ARI_Encode_0((VCtx[0]+UCtx[0])>>1);
414     UpdateVCtx_0(0,M_Log2RLE_Shift_0); UpdateUCtx_0(0,M_Log2RLE_Shift_1);
415 
416     if (Log2RunSize<2)
417       CtxRLE=(CtxRLE<<1)&0xF;
418     else
419       CtxRLE=((CtxRLE<<1)|1)&0xF;
420 
421     VCtx=&Model_Log2RLE_2[Log2RunSize][0];
422 
423     for (i=0;i<Log2RunSize;i++,Mask>>=1,VCtx++)
424       if (RunSize&Mask)
425       {
426         ARI_Encode_1(VCtx[0]);
427         UpdateVCtx_1(0,M_Log2RLE_Shift_2);
428       }
429       else
430       {
431         ARI_Encode_0(VCtx[0]);
432         UpdateVCtx_0(0,M_Log2RLE_Shift_2);
433       }
434   }
435 
436   VCtx=&Model_L0_1[Char][0]; UCtx=&Model_L0_2[4*CtxL0+(CtxRLE&3)][0];
437   uint32 Cum=Model_L0_0[4]+UCtx[4]+VCtx[4]-Model_L0_0[3]-UCtx[3]-VCtx[3];
438   ARI_Encode(Model_L0_0[3]+UCtx[3]+VCtx[3],Cum,
439              Model_L0_0[4]+UCtx[4]+VCtx[4]);
440 
441   Model_L0_0[3]+=2;UCtx[3]+=2;VCtx[3]+=2;
442   Model_L0_0[4]+=2;UCtx[4]+=2;VCtx[4]+=2;
443   Update_Model_L0();
444 
445   VCtx=Model_L1_0; UCtx=&Model_L1_1[CtxL1][0];
446 
447   for (i=0;i<6;i++)
448   {
449     ARI_Encode_1((VCtx[0]+UCtx[0])>>1);
450     UpdateVCtx_1(0,M_L1_Shift_0); UpdateUCtx_1(0,M_L1_Shift_1);
451     VCtx++;UCtx++;
452   }
453 
454   VCtx=&Model_L2_0[6][0];
455 
456   for (Mask=64,CtxL2=1,i=0;i<=6;i++,Mask>>=1)
457   {
458     ARI_Encode_1(VCtx[CtxL2]);
459     UpdateVCtx_1(CtxL2,M_L2_Shift);
460     CtxL2=(CtxL2<<1)|1;
461   }
462   WFC_Finish();
463   free(Model_Log2RLE_1);
464   Low+=(Range>>=1); ARI_ShiftLow(); ARI_ShiftLow();
465   ARI_ShiftLow(); ARI_ShiftLow(); ARI_ShiftLow();
466   return (Output+Size-OutputEnd-24);
467 }
468 
469 #undef ARI_OutTgtByte
470 #undef ARI_ShiftLow
471 #undef ARI_Encode
472 #undef ARI_Encode_0
473 #undef ARI_Encode_1
474 
475 
476 #define ARI_InTgtByte()      (*Input++)
477 #define ARI_GetFreq(TotFreq) (ARICode/(Range/=(TotFreq)))
478 
GRZip_WFC_Ari_Decode(uint8 * Input,uint32 Size,uint8 * Output)479 sint32 GRZip_WFC_Ari_Decode(uint8* Input,uint32 Size,uint8* Output)
480 {
481   uint8* SOutput=Output;
482   uint32 ARICode=0;
483   uint32 Range=(uint32)(-1);
484 
485 #define ARI_Decode(TFreq,TCumFreq,TTotFreq)                \
486 {                                                          \
487   ARICode-=((uint32)TCumFreq)*Range;                       \
488   Range*=((uint32)TFreq);                                  \
489   while(Range<ARI_RangeTOP)                                \
490     {ARICode=(ARICode<<8)|ARI_InTgtByte();Range<<=8;}      \
491 }                                                          \
492 
493 #define ARI_Decode_0(FFreq0)                               \
494 {                                                          \
495   uint32 FAFreq=FFreq0;                                    \
496   ARI_Decode(FAFreq,0,Model_MaxFreq);                      \
497 }                                                          \
498 
499 #define ARI_Decode_1(FFreq0)                               \
500 {                                                          \
501   uint32 FAFreq=FFreq0;                                    \
502   ARI_Decode(Model_MaxFreq-FAFreq,FAFreq,Model_MaxFreq);   \
503 }                                                          \
504 
505   ARICode|=ARI_InTgtByte();ARICode<<=8;
506   ARICode|=ARI_InTgtByte();ARICode<<=8;
507   ARICode|=ARI_InTgtByte();ARICode<<=8;
508   ARICode|=ARI_InTgtByte();ARICode<<=8;
509   ARICode|=ARI_InTgtByte();
510 
511   Init_Models();
512 
513   uint32 Log2RunSize,RunSize,WFCMTF_Rank,PredChar,Char=0;
514 
515   while (1)
516   {
517     PredChar=Char;
518 
519     VCtx=&Model_L0_1[PredChar][0]; UCtx=&Model_L0_2[4*CtxL0+(CtxRLE&3)][0];
520     uint32 Cum=0,Frq=ARI_GetFreq(Model_L0_0[4]+UCtx[4]+VCtx[4]);
521 
522     WFCMTF_Rank=0;while (Frq>=Cum) {Cum+=(Model_L0_0[WFCMTF_Rank]+UCtx[WFCMTF_Rank]+VCtx[WFCMTF_Rank]);WFCMTF_Rank++;}
523     WFCMTF_Rank--; Cum-=(Model_L0_0[WFCMTF_Rank]+UCtx[WFCMTF_Rank]+VCtx[WFCMTF_Rank]);
524 
525     ARI_Decode(Model_L0_0[WFCMTF_Rank]+UCtx[WFCMTF_Rank]+VCtx[WFCMTF_Rank],Cum,
526                Model_L0_0[4]+UCtx[4]+VCtx[4]);
527 
528     Model_L0_0[WFCMTF_Rank]+=2;UCtx[WFCMTF_Rank]+=2;VCtx[WFCMTF_Rank]+=2;
529     Model_L0_0[4]+=2;UCtx[4]+=2;VCtx[4]+=2;
530     Update_Model_L0();
531 
532     if (WFCMTF_Rank==3)
533     {
534 
535       VCtx=Model_L1_0; UCtx=&Model_L1_1[CtxL1][0];
536 
537       sint32 GrNum,GrPos=0;
538 
539       GrNum=0;
540 
541       while (GrNum!=6)
542       {
543         if (ARI_GetFreq(Model_MaxFreq)<((VCtx[0]+UCtx[0])>>1))
544          {
545            ARI_Decode_0((VCtx[0]+UCtx[0])>>1);
546            UpdateVCtx_0(0,M_L1_Shift_0); UpdateUCtx_0(0,M_L1_Shift_1);
547            break;
548          }
549         ARI_Decode_1((VCtx[0]+UCtx[0])>>1);
550         UpdateVCtx_1(0,M_L1_Shift_0); UpdateUCtx_1(0,M_L1_Shift_1);
551         VCtx++;UCtx++;
552         GrNum++;
553       }
554 
555       CtxL1=GrNum;
556 
557       VCtx=&Model_L2_0[GrNum][0];
558 
559       for (CtxL2=1,i=0;i<=GrNum;i++)
560         if (ARI_GetFreq(Model_MaxFreq)<VCtx[CtxL2])
561          {
562            ARI_Decode_0(VCtx[CtxL2]);
563            UpdateVCtx_0(CtxL2,M_L2_Shift);
564            CtxL2<<=1;GrPos<<=1;
565          }
566         else
567          {
568            ARI_Decode_1(VCtx[CtxL2]);
569            UpdateVCtx_1(CtxL2,M_L2_Shift);
570            CtxL2=(CtxL2<<1)|1;GrPos=(GrPos<<1)|1;
571          }
572       if ((GrNum==6)&&(GrPos==127)) break;
573 
574       WFCMTF_Rank=WFCMTF_GrNum2GrBegin[GrNum]+GrPos;
575 
576     }
577 
578     WFCMTF_Rank=(WFCMTF_Rank+1)&0xFF;
579 
580     Char=WFC_List[WFCMTF_Rank];WFCBuf[WFCBufPos]=Char;
581 
582     Update_Weight0(Char);
583     Update_Weight_Full(WFC_Val1,WFC_Pos1);
584     Update_Weight_Full(WFC_Val2,WFC_Pos2);
585     Update_Weight_Full(WFC_Val3,WFC_Pos3);
586     Update_Weight_Full(WFC_Val4,WFC_Pos4);
587     Update_Weight_Full(WFC_Val5,WFC_Pos5);
588     Update_Weight_Full(WFC_Val6,WFC_Pos6);
589     Update_Weight_Full(WFC_Val7,WFC_Pos7);
590     Update_Weight_Full(WFC_Val8,WFC_Pos8);
591     Update_Weight_Full(WFC_Val9,WFC_Pos9);
592     Update_Weight_Full(WFC_Val10,WFC_Pos10);
593     Update_Weight_Full(WFC_Val11,WFC_Pos11);
594     Update_Weight_Full(WFC_Val12,WFC_Pos12);
595 
596     WFCBufPos++;
597 
598     WFCMTF_Rank=(WFCMTF_Rank-1)&0xFF;
599 
600     if (WFCMTF_Rank>3) WFCMTF_Rank=3;
601     CtxL0=((CtxL0<<2)|WFCMTF_Rank)&0xFF;
602 
603     VCtx=&Model_Log2RLE_0[CtxRLE+16*WFCMTF_Rank][0];
604     UCtx=Model_Log2RLE_1+Char*(GRZ_Log2MaxBlockSize+1);
605 
606     Log2RunSize=0;
607 
608     while (1)
609     {
610       if (ARI_GetFreq(Model_MaxFreq)<((VCtx[0]+UCtx[0])>>1))
611        {
612          ARI_Decode_0((VCtx[0]+UCtx[0])>>1);
613          UpdateVCtx_0(0,M_Log2RLE_Shift_0); UpdateUCtx_0(0,M_Log2RLE_Shift_1);
614          break;
615        }
616       ARI_Decode_1((VCtx[0]+UCtx[0])>>1);
617       UpdateVCtx_1(0,M_Log2RLE_Shift_0); UpdateUCtx_1(0,M_Log2RLE_Shift_1);
618       VCtx++;UCtx++;
619       Log2RunSize++;
620     }
621 
622     if (Log2RunSize<2)
623       CtxRLE=(CtxRLE<<1)&0xF;
624     else
625       CtxRLE=((CtxRLE<<1)|1)&0xF;
626 
627     VCtx=&Model_Log2RLE_2[Log2RunSize][0];
628 
629     RunSize=0;
630 
631     for (i=0;i<Log2RunSize;i++,VCtx++)
632       if (ARI_GetFreq(Model_MaxFreq)<VCtx[0])
633        {
634          ARI_Decode_0(VCtx[0]);
635          UpdateVCtx_0(0,M_Log2RLE_Shift_2);
636          RunSize<<=1;
637        }
638       else
639        {
640          ARI_Decode_1(VCtx[0]);
641          UpdateVCtx_1(0,M_Log2RLE_Shift_2);
642          RunSize=(RunSize<<1)|1;
643        }
644     RunSize+=WFCMTF_Log2RLESize[Log2RunSize];
645 
646     while (RunSize--) *Output++=Char;
647 
648   }
649   WFC_Finish();
650   free(Model_Log2RLE_1);
651   return (Output-SOutput);
652 }
653 
654 #undef ARI_InTgtByte
655 #undef ARI_GetFreq
656 #undef ARI_Decode
657 #undef ARI_Decode_0
658 #undef ARI_Decode_1
659 
660 #undef WFC_Val0
661 #undef WFC_Val1
662 #undef WFC_Val2
663 #undef WFC_Val3
664 #undef WFC_Val4
665 #undef WFC_Val5
666 #undef WFC_Val6
667 #undef WFC_Val7
668 #undef WFC_Val8
669 #undef WFC_Val9
670 #undef WFC_Val10
671 #undef WFC_Val11
672 #undef WFC_Val12
673 #undef WFC_Pos1
674 #undef WFC_Pos2
675 #undef WFC_Pos3
676 #undef WFC_Pos4
677 #undef WFC_Pos5
678 #undef WFC_Pos6
679 #undef WFC_Pos7
680 #undef WFC_Pos8
681 #undef WFC_Pos9
682 #undef WFC_Pos10
683 #undef WFC_Pos11
684 #undef WFC_Pos12
685 #undef WFC_Init
686 #undef WFC_Finish
687 #undef Update_Weight
688 #undef Update_Weight0
689 #undef Update_Weight_Full
690 
691 #undef ARI_MaxByte
692 #undef WFC_MaxByte
693 #undef ARI_RangeTOP
694 #undef Model_NumBits
695 #undef Model_MaxFreq
696 #undef M_Log2RLE_Shift_0
697 #undef M_Log2RLE_Shift_1
698 #undef M_Log2RLE_Shift_2
699 #undef M_L1_Shift_0
700 #undef M_L1_Shift_1
701 #undef M_L2_Shift
702 #undef ModelL0_0MaxFreq
703 #undef ModelL0_1MaxFreq
704 #undef ModelL0_2MaxFreq
705 #undef UpdateVCtx_0
706 #undef UpdateVCtx_1
707 #undef UpdateUCtx_0
708 #undef UpdateUCtx_1
709 #undef Update_Model_L0
710 #undef Init_Models
711 
712 /*-------------------------------------------------*/
713 /* End                                   WFC_Ari.c */
714 /*-------------------------------------------------*/
715