"Fossies" - the Fresh Open Source Software Archive

Member "grzip-0.3.0/WFC_Ari.c" (4 Jan 2007, 23844 Bytes) of package /linux/privat/old/grzip-0.3.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "WFC_Ari.c" see the Fossies "Dox" file reference documentation.

    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 
  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 
  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 /*-------------------------------------------------*/