Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Bitwise Arithmetic Coder

By: cr88192 on Jun 17th, 2013  |  syntax: C  |  size: 12.31 KB  |  views: 38  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. /*
  2. Copyright (C) 2013 by Brendan G Bohannon
  3. Email: cr88192@gmail.com
  4. Copying: http://pastebin.com/iJxtZHm6
  5.  */
  6.  
  7. /*
  8.  
  9. typedef struct BGBBTJ_ArithContext_s BGBBTJ_ArithContext;
  10.  
  11. struct BGBBTJ_ArithContext_s
  12. {
  13. byte *cs;       //current pos in bitstream (input)
  14. byte *ct;       //current pos in bitstream (output)
  15. byte *cse;      //current end pos in bitstream (input)
  16. byte *cte;      //current end pos in bitstream (output)
  17.  
  18. u32 rmin;               //window lower range
  19. u32 rmax;               //window upper range
  20. u32 rval;               //window decode value
  21.  
  22. int wctx;
  23. byte *model;    //pairs of counts
  24. int ctxbits;    //context bits
  25. int ctxmask;    //context mask
  26. };
  27.  
  28. */
  29.  
  30. /*
  31. Bitwise Arithmetic Coder
  32.  */
  33.  
  34. #include <bgbbtj.h>
  35.  
  36. #define BGBBTJ_BITARITH_LOWER           0x00000000
  37. #define BGBBTJ_BITARITH_UPPER           0xFFFFFFFF
  38. #define BGBBTJ_BITARITH_NEUTRAL         0x8000
  39. #define BGBBTJ_BITARITH_WBITS           16
  40. #define BGBBTJ_BITARITH_WMASK           ((1<<BGBBTJ_BITARITH_WBITS)-1)
  41.  
  42. #define BGBBTJ_BITARITH_DATABITS        8       //W: arithmetic coder bits/symbol
  43. //#define BGBBTJ_BITARITH_CTXBITS               16
  44. //#define BGBBTJ_BITARITH_CTXBITS               14
  45. #define BGBBTJ_BITARITH_CTXBITS         13
  46. // #define BGBBTJ_BITARITH_CTXBITS              12
  47. // #define BGBBTJ_BITARITH_CTXBITS              10
  48. // #define BGBBTJ_BITARITH_CTXBITS              8
  49. #define BGBBTJ_BITARITH_CTXMASK         ((1<<BGBBTJ_BITARITH_CTXBITS)-1)
  50.  
  51. u16 bgbbtj_bitarith_divtab[65536];      //division table
  52. u32 bgbbtj_bitarith_divtab2[65536];     //division table (32 bit)
  53.  
  54. void BGBBTJ_BitArith_Init()
  55. {
  56.         static int init=0;
  57.         int i, j, k;
  58.  
  59.         if(init)return;
  60.         init=1;
  61.  
  62.         for(i=0; i<256; i++)
  63.                 for(j=0; j<256; j++)
  64.         {
  65.                 k=((i+1)<<16)/(i+j+2);
  66.                 bgbbtj_bitarith_divtab[i+(j<<8)]=k;
  67.                 bgbbtj_bitarith_divtab2[i+(j<<8)]=k<<16;
  68.         }
  69. }
  70.  
  71. byte *BGBBTJ_EmitVLI(byte *ct, int val)
  72. {
  73.         if(val<0)
  74.         {
  75.                 *ct++=0;
  76.                 return(ct);
  77.         }
  78.  
  79.         if(val<128)
  80.         {
  81.                 *ct++=val;
  82.                 return(ct);
  83.         }
  84.  
  85.         if(val<16384)
  86.         {
  87.                 *ct++=0x80|(val>>8);
  88.                 *ct++=val&0xFF;
  89.                 return(ct);
  90.         }
  91.  
  92.         if(val<2097152)
  93.         {
  94.                 *ct++=0xC0|(val>>16);
  95.                 *ct++=(val>>8)&0xFF;
  96.                 *ct++=val&0xFF;
  97.                 return(ct);
  98.         }
  99.  
  100.         if(val<268435456)
  101.         {
  102.                 *ct++=0xE0|(val>>24);
  103.                 *ct++=(val>>16)&0xFF;
  104.                 *ct++=(val>>8)&0xFF;
  105.                 *ct++=val&0xFF;
  106.                 return(ct);
  107.         }
  108.  
  109.         *ct++=0xF0;
  110.         *ct++=(val>>24)&0xFF;
  111.         *ct++=(val>>16)&0xFF;
  112.         *ct++=(val>>8)&0xFF;
  113.         *ct++=val&0xFF;
  114.         return(ct);
  115. }
  116.  
  117. byte *BGBBTJ_EmitSVLI(byte *ct, int val)
  118. {
  119.         return(BGBBTJ_EmitVLI(ct,
  120.                 (val>=0)?(val<<1):(((-val)<<1)-1)));
  121. }
  122.  
  123. byte *BGBBTJ_DecodeVLI(byte *cs, int *rval)
  124. {
  125.         int i;
  126.        
  127.         if(!cs)return(NULL);
  128.        
  129.         i=*cs++;
  130.         if(!(i&0x80))
  131.         {
  132.                 *rval=i; return(cs);
  133.         }else if((i&0xC0)==0x80)
  134.         {
  135.                 i=((i&0x3F)<<8)|(*cs++);
  136.                 *rval=i; return(cs);
  137.         }else if((i&0xE0)==0xC0)
  138.         {
  139.                 i=((i&0x1F)<<8)|(*cs++);
  140.                 i=(i<<8)|(*cs++);
  141.                 *rval=i; return(cs);
  142.         }else if((i&0xF0)==0xE0)
  143.         {
  144.                 i=((i&0x0F)<<8)|(*cs++);
  145.                 i=(i<<8)|(*cs++);
  146.                 i=(i<<8)|(*cs++);
  147.                 *rval=i; return(cs);
  148.         }else if((i&0xF8)==0xF0)
  149.         {
  150.                 i=((i&0x0F)<<8)|(*cs++);
  151.                 i=(i<<8)|(*cs++);
  152.                 i=(i<<8)|(*cs++);
  153.                 i=(i<<8)|(*cs++);
  154.                 *rval=i; return(cs);
  155.         }
  156.        
  157. //      *(int *)-1=-1;
  158.         *rval=0;
  159. //      return(cs);
  160.         return(NULL);
  161. }
  162.  
  163. byte *BGBBTJ_DecodeSVLI(byte *cs, int *rval)
  164. {
  165.         int i;
  166.        
  167.         cs=BGBBTJ_DecodeVLI(cs, &i);
  168.        
  169.         i=(i&1)?(-((i+1)>>1)):(i>>1);
  170.        
  171.         *rval=i;
  172.         return(cs);
  173. }
  174.  
  175. int BGBBTJ_BitArith_InputByte(BGBBTJ_ArithContext *ctx)
  176. {
  177.         if(ctx->cs>ctx->cse)
  178.                 return(0);
  179.  
  180.         return(*ctx->cs++);
  181. }
  182.  
  183. void BGBBTJ_BitArith_OutputByte(BGBBTJ_ArithContext *ctx, int i)
  184. {
  185.         if(ctx->ct>ctx->cte)
  186.                 return;
  187.  
  188.         *ctx->ct++=i;
  189. }
  190.  
  191. void BGBBTJ_BitArith_OutputBit(BGBBTJ_ArithContext *ctx,
  192.         int i, u32 w)
  193. {
  194.         u32 r, r2, v;
  195.         int j;
  196.  
  197.         r=ctx->rmax-ctx->rmin;
  198.         v=ctx->rmin+((((u64)r)*((u64)(w<<(32-BGBBTJ_BITARITH_WBITS))))>>32);
  199.  
  200.         if(i)ctx->rmin=v+1;
  201.         else ctx->rmax=v;
  202.  
  203.         //while bits
  204. //      while((ctx->rmin&0xFF000000)==(ctx->rmax&0xFF000000))
  205.         while(!((ctx->rmin^ctx->rmax)>>24))
  206.         {
  207.                 BGBBTJ_BitArith_OutputByte(ctx, ctx->rmin>>24);
  208.                 ctx->rmin<<=8;
  209.                 ctx->rmax<<=8;
  210.                 ctx->rmax|=255;
  211.         }
  212. }
  213.  
  214. int BGBBTJ_BitArith_InputBit(BGBBTJ_ArithContext *ctx, u32 w)
  215. {
  216.         u32 r, r2, v, i;
  217.  
  218.         r=ctx->rmax-ctx->rmin;
  219.         v=ctx->rmin+((((u64)r)*((u64)(w<<(32-BGBBTJ_BITARITH_WBITS))))>>32);
  220.  
  221.         i=(ctx->rval>v);
  222.         if(i)ctx->rmin=v+1;
  223.         else ctx->rmax=v;
  224.  
  225.         //while bits
  226. //      while((ctx->rmin&0xFF000000)==(ctx->rmax&0xFF000000))
  227.         while(!((ctx->rmin^ctx->rmax)>>24))
  228.         {
  229.                 ctx->rmin<<=8;
  230.                 ctx->rmax<<=8;
  231.                 ctx->rmax|=255;
  232.  
  233.                 ctx->rval<<=8;
  234.                 ctx->rval|=BGBBTJ_BitArith_InputByte(ctx);
  235.         }
  236.  
  237.         return(i);
  238. }
  239.  
  240. int BGBBTJ_BitArith_InputModelBit(BGBBTJ_ArithContext *ctx,
  241.         byte *model, int wctx)
  242. {
  243.         u32 r, v, i, w;
  244.         int wc;
  245.  
  246.         r=ctx->rmax-ctx->rmin;
  247.         w=bgbbtj_bitarith_divtab2[((u16 *)model)[wctx]];
  248.         v=ctx->rmin+(((u64)r*(u64)w)>>32);
  249.         wc=wctx<<1;
  250.  
  251.         i=(ctx->rval>v);
  252.         if(i)
  253.         {
  254.                 ctx->rmin=v+1;
  255.  
  256.                 if((++model[wc|1])&0x80)
  257.                 {
  258.                         model[wc|0]>>=1;
  259.                         model[wc|1]>>=1;
  260.                 }
  261.         }else
  262.         {
  263.                 ctx->rmax=v;
  264.  
  265.                 if((++model[wc])&0x80)
  266.                 {
  267.                         model[wc|0]>>=1;
  268.                         model[wc|1]>>=1;
  269.                 }
  270.         }
  271.  
  272.         //while bits
  273. //      while((ctx->rmin&0xFF000000)==(ctx->rmax&0xFF000000))
  274. //      while(!((ctx->rmin^ctx->rmax)&0xFF000000))
  275.         while(!((ctx->rmin^ctx->rmax)>>24))
  276.         {
  277.                 ctx->rmin<<=8;
  278.                 ctx->rmax<<=8;
  279.                 ctx->rmax|=255;
  280.  
  281.                 ctx->rval<<=8;
  282.                 ctx->rval|=BGBBTJ_BitArith_InputByte(ctx);
  283.         }
  284.  
  285.         return(i);
  286. }
  287.  
  288. void BGBBTJ_BitArith_FlushWBits(BGBBTJ_ArithContext *ctx)
  289. {
  290.         while((ctx->rmin!=BGBBTJ_BITARITH_LOWER) ||
  291.                 (ctx->rmax!=BGBBTJ_BITARITH_UPPER))
  292.         {
  293.                 BGBBTJ_BitArith_OutputByte(ctx, ctx->rmin>>24);
  294.  
  295.                 ctx->rmin<<=8;
  296.                 ctx->rmax<<=8;
  297.                 ctx->rmax|=255;
  298.         }
  299. }
  300.  
  301.  
  302. int BGBBTJ_BitArith_SetupEncode(BGBBTJ_ArithContext *ctx, byte *out, int sz)
  303. {
  304.         ctx->ct=out;
  305.         ctx->cte=out+sz;
  306.         ctx->rmin=BGBBTJ_BITARITH_LOWER;
  307.         ctx->rmax=BGBBTJ_BITARITH_UPPER;
  308. }
  309.  
  310. int BGBBTJ_BitArith_SetupDecode(BGBBTJ_ArithContext *ctx, byte *in, int sz)
  311. {
  312.         int i;
  313.  
  314.         ctx->cs=in;
  315.         ctx->cse=in+sz;
  316.         ctx->rmin=BGBBTJ_BITARITH_LOWER;
  317.         ctx->rmax=BGBBTJ_BITARITH_UPPER;
  318.  
  319.         ctx->rval=BGBBTJ_BITARITH_LOWER;
  320.         for(i=0; i<4; i++)
  321.                 ctx->rval=(ctx->rval<<8)|BGBBTJ_BitArith_InputByte(ctx);
  322. }
  323.  
  324. //arithmetic frontend/modeler
  325. #if 1
  326. int BGBBTJ_BitArith_Predict(
  327.         BGBBTJ_ArithContext *ctx, byte *model, int wctx)
  328. {
  329.         return(bgbbtj_bitarith_divtab[((u16 *)ctx->model)[wctx]]);
  330.  
  331. //      return(bgbbtj_bitarith_divtab[
  332. //              model[(ctx<<1)|0]|
  333. //              (model[(ctx<<1)|1]<<8)]);
  334. }
  335. #endif
  336.  
  337. #if 0
  338. int BGBBTJ_BitArith_Predict(BGBBTJ_ArithContext *ctx, byte *model, int wctx)
  339. {
  340.         u32 i, j, k;
  341.  
  342.         wctx<<=1;
  343.         i=model[wctx|0];
  344.         j=model[wctx|1];
  345.  
  346.         k=((i+1)<<BGBBTJ_BITARITH_WBITS)/(i+j+2);
  347.  
  348. //      k=(k<WARITH2_CLAMP)?WARITH2_CLAMP:
  349. //              ((k>(4096-WARITH2_CLAMP))?(4096-WARITH2_CLAMP):k);
  350. //      k=BGBBTJ_BITARITH_NEUTRAL;
  351.  
  352.         return(k);
  353. }
  354. #endif
  355.  
  356. int BGBBTJ_BitArith_Update(
  357.         BGBBTJ_ArithContext *ctx, byte *model, int wctx, int v)
  358. {
  359.         int i;
  360.  
  361.         i=(wctx<<1);
  362.         ctx->model[i|v]++;
  363.         if(ctx->model[i|v]&0x80)
  364.         {
  365.                 ctx->model[i|0]>>=1;
  366.                 ctx->model[i|1]>>=1;
  367.         }
  368. }
  369.  
  370. void BGBBTJ_BitArith_EncodeSymbol(BGBBTJ_ArithContext *ctx, int v)
  371. {
  372.         int i, j, k;
  373.  
  374.         i=BGBBTJ_BITARITH_DATABITS;
  375.         while(i--)
  376.         {
  377.                 j=(v>>i)&1;
  378.  
  379.                 k=BGBBTJ_BitArith_Predict(ctx, ctx->model, ctx->wctx);
  380.                 BGBBTJ_BitArith_Update(ctx, ctx->model, ctx->wctx, j);
  381. //              k=BGBBTJ_BITARITH_NEUTRAL;
  382.  
  383.                 BGBBTJ_BitArith_OutputBit(ctx, j, k);
  384. //              ctx->wctx=((ctx->wctx<<1)|j)&BGBBTJ_BITARITH_CTXMASK;
  385.                 ctx->wctx=((ctx->wctx<<1)|j)&ctx->ctxmask;
  386.         }
  387. }
  388.  
  389. int BGBBTJ_BitArith_DecodeSymbol(BGBBTJ_ArithContext *ctx)
  390. {
  391.         int i, j, k, v;
  392.  
  393. //      v=0;
  394.         i=BGBBTJ_BITARITH_DATABITS;
  395.         while(i--)
  396.         {
  397. //              k=BGBBTJ_BitArith_Predict(ctx->model, ctx->wctx);
  398. //              k=BGBBTJ_BITARITH_NEUTRAL;
  399. //              j=BGBBTJ_BitArith_InputBit(k);
  400. //              BGBBTJ_BitArith_Update(ctx->model, ctx->wctx, j);
  401.  
  402. //              ctx->wctx=v&((1<<WARITH2_CTXBITS)-1);
  403.                 j=BGBBTJ_BitArith_InputModelBit(ctx, ctx->model, ctx->wctx);
  404.  
  405. //              ctx->wctx=((ctx->wctx<<1)|j)&((1<<WARITH2_CTXBITS)-1);
  406. //              ctx->wctx=((ctx->wctx<<1)|j)&BGBBTJ_BITARITH_CTXMASK;
  407.                 ctx->wctx=((ctx->wctx<<1)|j)&ctx->ctxmask;
  408.         }
  409.  
  410. //      return(ctx->wctx&0xFF);
  411.         return(ctx->wctx&((1<<BGBBTJ_BITARITH_DATABITS)-1));
  412. //      return(v);
  413. }
  414.  
  415. void BGBBTJ_BitArith_SetupContextBits(
  416.         BGBBTJ_ArithContext *ctx, int bits)
  417. {
  418.         int i, j;
  419.  
  420.         if(ctx->model && (ctx->ctxbits==bits))
  421.         {
  422.                 j=1<<bits;
  423.                 for(i=0; i<j*2; i++)ctx->model[i]=0;
  424.                 ctx->wctx=0;
  425.                 return;
  426.         }
  427.  
  428.         if(ctx->model)
  429.                 { gcfree(ctx->model); }
  430.        
  431.         j=1<<bits;
  432.         ctx->model=gcalloc(j*2*sizeof(byte));
  433.         ctx->ctxbits=bits;
  434.         ctx->ctxmask=(1<<bits)-1;
  435.         ctx->wctx=0;
  436. }
  437.  
  438. BGBBTJ_API int BGBBTJ_BitArith_EncodeDataCtx(
  439.         BGBBTJ_ArithContext *ctx, byte *ibuf, int isz, byte *obuf, int osz)
  440. {
  441.         int i, j, k, l, ll;
  442.         byte *cs, *ct, *cse, *cte, *s2;
  443.  
  444.         if(isz<=0)return(0);
  445.  
  446.         BGBBTJ_BitArith_Init();
  447.  
  448. #if 0
  449. //      j=1<<WARITH2_CTXBITS;
  450.         j=1<<BGBBTJ_BITARITH_CTXBITS;
  451. //      ctx->model=malloc(j*2*sizeof(byte));
  452.         for(i=0; i<j*2; i++)ctx->model[i]=0;
  453.         ctx->wctx=0;
  454. #endif
  455.  
  456.         BGBBTJ_BitArith_SetupContextBits(ctx,
  457.                 BGBBTJ_BITARITH_CTXBITS);
  458.  
  459.         ct=obuf; cte=obuf+osz;
  460.  
  461.         //Emit Header
  462.         *ct++=0xBA;             //magic byte
  463.         *ct++=0x00|(BGBBTJ_BITARITH_CTXBITS-12)&7;
  464.  
  465.         ct=BGBBTJ_EmitVLI(ct, isz);
  466.  
  467.         BGBBTJ_BitArith_SetupEncode(ctx, ct, cte-ct);
  468. //      BGBBTJ_BitArith_SetupEncode(ctx, obuf, osz);
  469.  
  470.         cs=ibuf;
  471.         cse=ibuf+isz;
  472.         i=0;
  473.  
  474.         while(cs<cse)
  475.         {
  476.                 j=*cs++;
  477.  
  478. //              if(i<16)printf("%02X ", j);
  479.  
  480.                 BGBBTJ_BitArith_EncodeSymbol(ctx, j);
  481.                 i++;
  482.         }
  483. //      printf("\n");
  484. //      BGBBTJ_BitArith_EncodeSymbol(ctx, 258);
  485.         BGBBTJ_BitArith_FlushWBits(ctx);
  486.  
  487. #if 0
  488.         for(i=0; i<16; i++)
  489.                 printf("%02X ", out[i]);
  490.         printf("\n");
  491. #endif
  492.  
  493. #if 0
  494. //test decode
  495. //      for(i=0; i<1024; i++)ctx->model[i]=0;
  496. //      j=1<<WARITH2_CTXBITS;
  497.         j=1<<BGBBTJ_BITARITH_CTXBITS;
  498.         for(i=0; i<j*2; i++)ctx->model[i]=0;
  499.         ctx->wctx=0;
  500.  
  501.         BGBBTJ_BitArith_SetupDecode(ctx, obuf, osz);
  502.  
  503.         cs=ibuf;
  504.         ce=ibuf+isz;
  505.         i=0;
  506.  
  507.         while(cs<ce)
  508.         {
  509.                 j=*cs++;
  510.  
  511.                 k=BGBBTJ_BitArith_DecodeSymbol(ctx);
  512.  
  513.                 if(i<16)printf("%02X ", k);
  514.                 if(j!=k)
  515.                 {
  516.                         printf("break at %d\n", i);
  517.                         break;
  518.                 }
  519.                 i++;
  520.         }
  521.  
  522.         printf("\n");
  523. #endif
  524.  
  525.         i=ctx->ct-obuf;
  526.         return(i);
  527. }
  528.  
  529. BGBBTJ_API int BGBBTJ_BitArith_DecodeDataCtx(
  530.         BGBBTJ_ArithContext *ctx,
  531.         byte *ibuf, int isz, byte *obuf, int osz)
  532. {
  533.         int i, j, k, l, ll, osz1;
  534.         byte *cs, *ct, *cse, *cte, *s2;
  535.  
  536.         if(isz<=0)return(0);
  537.  
  538.         BGBBTJ_BitArith_Init();
  539.  
  540. //      j=1<<BGBBTJ_BITARITH_CTXBITS;
  541. //      for(i=0; i<j*2; i++)ctx->model[i]=0;
  542. //      ctx->wctx=0;
  543.  
  544.         cs=ibuf; cse=ibuf+isz;
  545. //      if((cs[0]!=0xBA)||(cs[1]!=0x00))
  546.         if((cs[0]!=0xBA)||(cs[1]&0xF8))
  547.                 return(-1);
  548.  
  549.         BGBBTJ_BitArith_SetupContextBits(ctx, 12+(cs[1]&7));
  550.  
  551.         cs+=2;
  552.  
  553.         cs=BGBBTJ_DecodeVLI(cs, &osz1);
  554.         if(osz1>osz)return(-1);
  555.  
  556.         BGBBTJ_BitArith_SetupDecode(ctx, cs, cse-cs);
  557. //      BGBBTJ_BitArith_SetupDecode(ctx, ibuf, isz);
  558.  
  559.         ct=obuf;
  560. //      cte=obuf+osz;
  561.         cte=obuf+osz1;
  562.         i=0;
  563.  
  564.         while(ct<cte)
  565.         {
  566.                 j=BGBBTJ_BitArith_DecodeSymbol(ctx);
  567.                 *ct++=j;
  568.         }
  569.  
  570. //      i=ctx->cs-ibuf;
  571.         i=ct-obuf;
  572.         return(i);
  573. }
  574.  
  575. BGBBTJ_API int BGBBTJ_BitArith_EncodeData(
  576.         byte *ibuf, int isz, byte *obuf, int osz)
  577. {
  578.         BGBBTJ_ArithContext *ctx;
  579.         int i, j;
  580.        
  581.         ctx=gcalloc(sizeof(BGBBTJ_ArithContext));
  582.         ctx->cs=NULL; ctx->ct=NULL;
  583. //      j=1<<BGBBTJ_BITARITH_CTXBITS;
  584. //      ctx->model=gcalloc(j*2*sizeof(byte));
  585.         i=BGBBTJ_BitArith_EncodeDataCtx(ctx, ibuf, isz, obuf, osz);
  586.  
  587.         if(ctx->model)gcfree(ctx->model);
  588.         gcfree(ctx);
  589.        
  590.         return(i);
  591. }
  592.  
  593. BGBBTJ_API int BGBBTJ_BitArith_DecodeData(
  594.         byte *ibuf, int isz, byte *obuf, int osz)
  595. {
  596.         BGBBTJ_ArithContext *ctx;
  597.         int i, j;
  598.        
  599.         ctx=gcalloc(sizeof(BGBBTJ_ArithContext));
  600.         ctx->cs=NULL; ctx->ct=NULL;
  601. //      j=1<<BGBBTJ_BITARITH_CTXBITS;
  602. //      ctx->model=gcalloc(j*2*sizeof(byte));
  603.         i=BGBBTJ_BitArith_DecodeDataCtx(ctx, ibuf, isz, obuf, osz);
  604.        
  605.         if(ctx->model)gcfree(ctx->model);
  606.         gcfree(ctx);
  607.        
  608.         return(i);
  609. }
  610.  
  611. BGBBTJ_API int BGBBTJ_BitArith_EncodeTestData(
  612.         byte *ibuf, int isz, byte *obuf, int osz)
  613. {
  614.         BGBBTJ_ArithContext *ctx;
  615.         byte *tbuf;
  616.         int i, j, k;
  617.        
  618.         ctx=gcalloc(sizeof(BGBBTJ_ArithContext));
  619.         ctx->cs=NULL; ctx->ct=NULL;
  620. //      j=1<<BGBBTJ_BITARITH_CTXBITS;
  621. //      ctx->model=gcalloc(j*2*sizeof(byte));
  622.         i=BGBBTJ_BitArith_EncodeDataCtx(ctx, ibuf, isz, obuf, osz);
  623.  
  624.         tbuf=malloc(2*isz);
  625.         j=BGBBTJ_BitArith_DecodeDataCtx(ctx, obuf, i, tbuf, 2*isz);
  626.        
  627.         if(j!=isz)
  628.         {
  629.                 printf("BGBBTJ_BitArith_EncodeTestData: Size Check %d->%d\n",
  630.                         isz, j);
  631.         }
  632.        
  633.         for(k=0; k<j; k++)
  634.         {
  635.                 if(ibuf[k]!=tbuf[k])
  636.                 {
  637.                         printf("BGBBTJ_BitArith_EncodeTestData: "
  638.                                 "Decode Fail At %d\n", k);
  639.                         break;
  640.                 }
  641.         }
  642.  
  643.         if(k>=j)
  644.         {
  645.                 printf("BGBBTJ_BitArith_EncodeTestData: OK\n");
  646.         }
  647.  
  648.         free(tbuf);
  649.  
  650.         if(ctx->model)gcfree(ctx->model);
  651.         gcfree(ctx);
  652.        
  653.         return(i);
  654. }