cr88192

STF+AdRice post compressor for RP2.

Feb 5th, 2026
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.80 KB | Source Code | 0 0
  1. /*
  2.  * STF+AdRice post-compressor for RP2.
  3.  *
  4.  * Escape Magic: 10-00
  5.  *
  6.  * Uses 3 contexts: Tag, Length/Distance, and Literal.
  7.  *
  8.  * Mostly separates bytes by category and then uses the appropriate context.
  9.  *
  10.  * Uses an AdRice implementation that steps by a fraction of a bit.
  11.  * The slower stepping was better for compression in this case.
  12.  * Where, Rice involves splitting the value into a unary coded prefix (Q)
  13.  * and a K bit suffix. In AdRice, the K value is adjusted based on Q.
  14.  * Rather than directly incrementing/decrementing K, was more effective to
  15.  * step with a partial bit here to slow the adaptation.
  16.  *
  17.  * STF: Swap Towards Front
  18.  * As each symbol is encoded, it is swapped towards the front of the list.
  19.  * This will typically swap symbols towards an approximation of an optimal order.
  20.  */
  21.  
  22. #define BTM_STFRK_ADBSHL    5
  23. #define BTM_STFRK_ADBINIT   6
  24.  
  25. typedef struct BTM_StfRkCtx_s BTM_StfRkCtx;
  26. struct BTM_StfRkCtx_s {
  27. byte *cst;
  28. u32 win;
  29. byte pos;
  30. };
  31.  
  32. int BTM_StfRk_PeekBits(BTM_StfRkCtx *ctx, int bits)
  33. {
  34.     u32 v;
  35.     v=*(u32 *)(ctx->cst);
  36.     return((v>>ctx->pos)&((1<<bits)-1));
  37. }
  38.  
  39. void BTM_StfRk_SkipBits(BTM_StfRkCtx *ctx, int bits)
  40. {
  41.     int p;
  42.  
  43.     p=ctx->pos+bits;
  44.     ctx->cst+=p>>3;
  45.     ctx->pos=p&7;
  46. }
  47.  
  48. void BTM_StfRk_SetupReadBits(BTM_StfRkCtx *ctx, byte *buf)
  49. {
  50.     ctx->cst=buf;
  51.     ctx->pos=0;
  52. }
  53.  
  54. #if 1
  55. static const byte tkupi_riceqtab[256]={
  56. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  57. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
  58. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  59. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6,
  60. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  61. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
  62. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  63. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7,
  64. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  65. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
  66. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  67. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6,
  68. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  69. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
  70. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
  71. 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 8
  72. };
  73.  
  74. int BTM_StfRk_ReadAdRiceB(BTM_StfRkCtx *ctx, byte *rkf)
  75. {
  76.     int b, q, r, v, kf, kfb, skb;
  77.     int p;
  78.  
  79.     kfb=*rkf;
  80.     kf=kfb>>BTM_STFRK_ADBSHL;
  81.     b=BTM_StfRk_PeekBits(ctx, 16);
  82.     q=tkupi_riceqtab[b&0xFF];
  83.     if(q==8)
  84.     {
  85.         kfb++;
  86.         skb=16;
  87.         v=(b>>8)&0xFF;
  88.     }else
  89.     {
  90.         r=(b>>(q+1))&((1<<kf)-1);
  91.         skb=q+kf+1;
  92.         v=(q<<kf)|r;
  93.         if(!q && kfb)
  94.             { kfb--; }
  95.         else if(q>1)
  96.             { kfb++; }
  97.     }
  98.  
  99.     BTM_StfRk_SkipBits(ctx, skb);
  100.     *rkf=kfb;
  101.     return(v);
  102. }
  103. #endif
  104.  
  105. int BTM_StfRk_ReadAdRiceSTF(BTM_StfRkCtx *ctx, byte *rkf, byte *stftab)
  106. {
  107.     int i0, i1, v0, v1;
  108.    
  109.     i0=BTM_StfRk_ReadAdRiceB(ctx, rkf);
  110.     i1=(i0*15)>>4;
  111.     v0=stftab[i0];  v1=stftab[i1];
  112.     stftab[i0]=v1;  stftab[i1]=v0;
  113.     return(v0);
  114. }
  115.  
  116.  
  117.  
  118. void BTM_StfRk_WriteBits(BTM_StfRkCtx *ctx, int val, int bits)
  119. {
  120.     ctx->win|=(val&((1U<<bits)-1))<<ctx->pos;
  121.     ctx->pos+=bits;
  122.     while(ctx->pos>=8)
  123.     {
  124.         *ctx->cst++=ctx->win;
  125.         ctx->win>>=8;
  126.         ctx->pos-=8;
  127.     }
  128. }
  129.  
  130. void BTM_StfRk_FlushBits(BTM_StfRkCtx *ctx)
  131. {
  132.     int p;
  133.     p=ctx->pos;
  134.     while(p>0)
  135.     {
  136.         *ctx->cst++=ctx->win;
  137.         ctx->win>>=8;
  138.         p-=8;
  139.     }
  140.     ctx->pos=0;
  141. }
  142.  
  143. void BTM_StfRk_WriteAdRiceB(BTM_StfRkCtx *ctx, int val, byte *rkf)
  144. {
  145.     int q, kf, kfb;
  146.    
  147.     kfb=*rkf;
  148.     kf=kfb>>BTM_STFRK_ADBSHL;
  149.  
  150.     q=val>>kf;
  151.  
  152.     if(q>=8)
  153.     {
  154.         kfb++; *rkf=kfb;
  155.         BTM_StfRk_WriteBits(ctx, 0xFF, 8);
  156.         BTM_StfRk_WriteBits(ctx, val, 8);
  157.         return;
  158.     }
  159.  
  160.     BTM_StfRk_WriteBits(ctx, (1<<q)-1, q+1);
  161.     BTM_StfRk_WriteBits(ctx, val&((1<<kf)-1), kf);
  162.     if(!q && kfb)
  163.         { kfb--; *rkf=kfb; }
  164.     else if(q>1)
  165.         { kfb++; *rkf=kfb; }
  166. }
  167.  
  168. void BTM_StfRk_WriteAdRiceSTF(BTM_StfRkCtx *ctx, int val,
  169.     byte *rkf, byte *stfvtab, byte *stfitab)
  170. {
  171.     int i0, i1, v0, v1;
  172.    
  173.     i0=stfitab[val];
  174.     i1=(i0*15)>>4;
  175.     v0=stfvtab[i0]; v1=stfvtab[i1];
  176.     stfvtab[i0]=v1; stfvtab[i1]=v0;
  177.     stfitab[v1]=i0; stfitab[v0]=i1;
  178.    
  179.     BTM_StfRk_WriteAdRiceB(ctx, i0, rkf);
  180. }
  181.  
  182. void BTM_StfRk_EncodeInit(BTM_StfRkCtx *ctx, byte *buf)
  183. {
  184.     ctx->cst=buf;
  185.     ctx->win=0;
  186.     ctx->pos=0;
  187. }
  188.  
  189. void BTM_StfRk_DecodeInit(BTM_StfRkCtx *ctx, byte *buf)
  190. {
  191.     ctx->cst=buf;
  192.     ctx->win=*(u32 *)buf;
  193.     ctx->pos=0;
  194. }
  195.  
  196. int BTM_StfRk_CheckPostRp2Blob(byte *ibuf)
  197. {
  198.     if((ibuf[0]==0x10) && (ibuf[1]==0x00))
  199.         return(1);
  200.     return(0);
  201. }
  202.  
  203. int BTM_StfRk_EncodeBufferPostRp2(byte *obuf, byte *ibuf, int ibsz)
  204. {
  205.     byte prbtab_t[256], prbidx_t[256];
  206.     byte prbtab_d[256], prbidx_d[256];
  207.     byte prbtab_l[256], prbidx_l[256];
  208.     BTM_StfRkCtx t_ctx;
  209.     BTM_StfRkCtx *ctx;
  210.     byte *cs, *cse, *cs1, *csr, *ct;
  211.     byte rk_t, rk_d, rk_l;
  212.     u32 tag;
  213.     int tsz, nr;
  214.     int i, j, k;
  215.  
  216.     ctx=&t_ctx;
  217.  
  218.     ct=obuf;
  219.     *ct++=0x10;
  220.     *ct++=0x00;
  221.    
  222.     BTM_StfRk_EncodeInit(ctx, ct);
  223.  
  224.     for(i=0; i<256; i++)
  225.     {
  226.         prbtab_t[i]=i;  prbidx_t[i]=i;
  227.         prbtab_d[i]=i;  prbidx_d[i]=i;
  228.         prbtab_l[i]=i;  prbidx_l[i]=i;
  229.     }
  230.  
  231.     rk_t=BTM_STFRK_ADBINIT<<BTM_STFRK_ADBSHL;
  232.     rk_d=BTM_STFRK_ADBINIT<<BTM_STFRK_ADBSHL;
  233.     rk_l=BTM_STFRK_ADBINIT<<BTM_STFRK_ADBSHL;
  234.  
  235.     cs=ibuf;
  236.     cse=ibuf+ibsz;
  237.     while(cs<cse)
  238.     {
  239.         tag=*(u32 *)cs;
  240.         if(!(tag&0x01))         { tsz=2; nr=(tag>>1)&7; }
  241.         else if(!(tag&0x02))    { tsz=3; nr=(tag>>2)&7; }
  242.         else if(!(tag&0x04))    { tsz=4; nr=(tag>>3)&7; }
  243.         else if(!(tag&0x08))    { tsz=1; nr=(((tag>>4)&15)+1)*8; }
  244.         else if(!(tag&0x10))    { tsz=-1; nr=(tag>>5)&7; }
  245.         else if(!(tag&0x20))    { tsz=1; nr=(tag>>6)&3; }
  246.         else if(!(tag&0x40))    { tsz=2; nr=(((tag>>7)&511)+1)*8; }
  247.         else if(!(tag&0x80))
  248.         {
  249.             if(tag&0x100)
  250.                 { tsz=6; nr=(tag>>9)&7; }
  251.             else
  252.                 { tsz=2; nr=0; }
  253.         }
  254.         else { tsz=-1; }
  255.        
  256.         if(tsz<1)
  257.             return(-1);
  258.        
  259.         BTM_StfRk_WriteAdRiceSTF(ctx, *cs++, &rk_t, prbtab_t, prbidx_t);
  260.         for(i=1; i<tsz; i++)
  261.             { BTM_StfRk_WriteAdRiceSTF(ctx, *cs++, &rk_d, prbtab_d, prbidx_d); }
  262.         for(i=0; i<nr; i++)
  263.             { BTM_StfRk_WriteAdRiceSTF(ctx, *cs++, &rk_l, prbtab_l, prbidx_l); }
  264.     }
  265.     BTM_StfRk_FlushBits(ctx);
  266.    
  267. //  printf("  rk_t=%d rk_d=%d rk_l=%d\n", rk_t>>5, rk_d>>5, rk_l>>5);
  268.    
  269.     return(ctx->cst-obuf);
  270. }
  271.  
  272. int BTM_StfRk_DecodeBufferPostRp2(byte *obuf, byte *ibuf, int ibsz)
  273. {
  274.     byte prbtab_t[256];
  275.     byte prbtab_d[256];
  276.     byte prbtab_l[256];
  277.     BTM_StfRkCtx t_ctx;
  278.     BTM_StfRkCtx *ctx;
  279.     byte *cs, *cse, *cs1, *csr, *ct;
  280.     byte rk_t, rk_d, rk_l;
  281.     u32 tag;
  282.     int lc, tsz, tsi, nr, tg;
  283.     int i, j, k;
  284.  
  285.     if((ibuf[0]!=0x10) || (ibuf[1]!=0x00))
  286.         return(-1);
  287.  
  288.     ctx=&t_ctx;
  289.     BTM_StfRk_DecodeInit(ctx, ibuf+2);
  290.    
  291.     ct=obuf;
  292.  
  293.     for(i=0; i<256; i++)
  294.     {
  295.         prbtab_t[i]=i;
  296.         prbtab_d[i]=i;
  297.         prbtab_l[i]=i;
  298.     }
  299.    
  300.     rk_t=BTM_STFRK_ADBINIT<<BTM_STFRK_ADBSHL;
  301.     rk_d=BTM_STFRK_ADBINIT<<BTM_STFRK_ADBSHL;
  302.     rk_l=BTM_STFRK_ADBINIT<<BTM_STFRK_ADBSHL;
  303.  
  304.     while(1)
  305.     {
  306.         tg=BTM_StfRk_ReadAdRiceSTF(ctx, &rk_t, prbtab_t);
  307.         if(!(tg&0x01))          { tsz=2; }
  308.         else if(!(tg&0x02)) { tsz=3; }
  309.         else if(!(tg&0x04)) { tsz=4; }
  310.         else if(!(tg&0x08)) { tsz=1; }
  311.         else if(!(tg&0x10)) { tsz=1; }
  312.         else if(!(tg&0x20)) { tsz=1; }
  313.         else if(!(tg&0x40)) { tsz=2; }
  314.         else if(!(tg&0x80)) { tsz=2; }
  315.         tsi=1;
  316.        
  317.         *ct++=tg;
  318.         if(tg==0x1F)
  319.             break;
  320.        
  321.         if(tg==0x7F)
  322.         {
  323.             j=BTM_StfRk_ReadAdRiceSTF(ctx, &rk_d, prbtab_d);
  324.             *ct++=j;
  325.             tag|=j<<8;
  326.             tsi=2;
  327.             if(tag&0x0100)
  328.                 tsz=6;
  329.         }
  330.        
  331.         tag=tg;
  332.         for(i=tsi; i<tsz; i++)
  333.         {
  334.             j=BTM_StfRk_ReadAdRiceSTF(ctx, &rk_d, prbtab_d);
  335.             *ct++=j;
  336.             tag|=j<<(i*8);
  337.         }
  338.        
  339.         if(!tag)
  340.             break;
  341.        
  342.         if(!(tag&0x01))         { tsz=2; nr=(tag>>1)&7; }
  343.         else if(!(tag&0x02))    { tsz=3; nr=(tag>>2)&7; }
  344.         else if(!(tag&0x04))    { tsz=4; nr=(tag>>3)&7; }
  345.         else if(!(tag&0x08))    { tsz=1; nr=(((tag>>4)&15)+1)*8; }
  346.         else if(!(tag&0x10))    { tsz=1; nr=(tag>>5)&7; }
  347.         else if(!(tag&0x20))    { tsz=1; nr=(tag>>6)&3; }
  348.         else if(!(tag&0x40))    { tsz=2; nr=(((tag>>7)&511)+1)*8; }
  349.         else if(!(tag&0x80))    { nr=(tag&0x0100)?((tag>>9)&7):0; }
  350.         for(i=0; i<nr; i++)
  351.             { *ct++=BTM_StfRk_ReadAdRiceSTF(ctx, &rk_l, prbtab_l); }
  352.     }
  353.     return(ct-obuf);
  354. }
  355.  
Advertisement
Add Comment
Please, Sign In to add comment