Advertisement
cr88192

Simple LZ, TK uLZ 0, Early Decoder

Feb 11th, 2019
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.93 KB | None | 0 0
  1. #define TKULZ_STATUS_NONE   0
  2. #define TKULZ_STATUS_END    1
  3. #define TKULZ_STATUS_BADTAG 2
  4. #define TKULZ_STATUS_BADESC 3
  5. #define TKULZ_STATUS_BADHT  4
  6.  
  7. #ifndef TKULZ_BYTE
  8. #define TKULZ_BYTE
  9. typedef unsigned char       byte;
  10. typedef unsigned short  u16;
  11. typedef unsigned int        u32;
  12.  
  13. typedef signed char     sbyte;
  14. typedef signed short        s16;
  15. typedef signed int      s32;
  16. #endif
  17.  
  18. typedef struct TKuLZ_DecState_s TKuLZ_DecState;
  19.  
  20. struct TKuLZ_DecState_s {
  21.     byte *cs;
  22.     u32 win;
  23.     byte pos;
  24.     byte status;
  25.  
  26.     byte *ct;
  27.  
  28.     u16 htab_t[4096];
  29.     u16 htab_l[4096];
  30.     u16 htab_d[4096];
  31. };
  32.  
  33. int TKuLZ_PeekBits(TKuLZ_DecState *ctx, int bits)
  34.     { return((ctx->win>>ctx->pos)&((1<<bits)-1)); }
  35.  
  36. void TKuLZ_SkipBits(TKuLZ_DecState *ctx, int bits)
  37. {
  38.     ctx->pos+=bits;
  39.     while(ctx->pos>=8)
  40.         { ctx->win=(ctx->win>>8)|((*ctx->cs++)<<24); ctx->pos-=8; }
  41. }
  42.  
  43. int TKuLZ_ReadBits(TKuLZ_DecState *ctx, int bits)
  44. {
  45.     int b;
  46.     b=TKuLZ_PeekBits(ctx, bits);
  47.     TKuLZ_SkipBits(ctx, bits);
  48.     return(b);
  49. }
  50.  
  51. int TKuLZ_ReadPackedLengths(TKuLZ_DecState *ctx, byte *cls)
  52. {
  53.     byte *t, *te;
  54.     int i, j, c, nz, zc, lc;
  55.    
  56.     t=cls; te=cls+256; lc=0;
  57.     while(t<te)
  58.     {
  59.         c=TKuLZ_ReadBits(ctx, 4); zc=0; nz=0;
  60.         if(c<14)
  61.             { *t++=c; lc=c; }
  62.         else if(c==14)
  63.             { nz=TKuLZ_ReadBits(ctx, 4)+3; }
  64.         else if(c==15)
  65.         {
  66.             j=TKuLZ_ReadBits(ctx, 2);
  67.             if(j==0)
  68.                 { nz=TKuLZ_ReadBits(ctx, 6)+19; }
  69.             else if(j==1)
  70.             {
  71.                 nz=TKuLZ_ReadBits(ctx, 6)+3; zc=lc;
  72.                 if(nz==3)
  73.                     { nz=te-t; zc=0; }
  74.             }
  75.             else
  76.                 { ctx->status=TKULZ_STATUS_BADHT; }
  77.         }
  78.         while(nz>0)
  79.             { *t++=zc; nz--; }
  80.     }
  81.    
  82.     if(t>te)
  83.         { ctx->status=TKULZ_STATUS_BADHT; }
  84. }
  85.  
  86. byte TKuLZ_TransposeByte(byte v)
  87. {
  88.     static const byte trans4[16]={
  89.         0x0,0x8,0x4,0xC, 0x2,0xA,0x6,0xE,
  90.         0x1,0x9,0x5,0xD, 0x3,0xB,0x7,0xF};
  91.     return((trans4[v&15]<<4)|trans4[v>>4]);
  92. }
  93.  
  94. u16 TKuLZ_TransposeWord(u16 v)
  95.     { return((TKuLZ_TransposeByte(v&255)<<8)|TKuLZ_TransposeByte(v>>8)); }
  96.  
  97. void TKuLZ_SetupTableLengths(TKuLZ_DecState *ctx, u16 *htab, byte *cls)
  98. {
  99.     int c, l, tc, ntc;
  100.     int i, j, k;
  101.  
  102.     for(i=0; i<4096; i++)
  103.         htab[i]=0;
  104.    
  105.     c=0;
  106.     for(l=1; l<13; l++)
  107.     {
  108.         for(i=0; i<256; i++)
  109.             if(cls[i]==l)
  110.         {
  111.             ntc=1<<(12-l);
  112.             tc=c<<(12-l);
  113.             for(j=0; j<ntc; j++)
  114.             {
  115.                 k=TKuLZ_TransposeWord(tc+j)>>4;
  116.                 htab[k]=(l<<8)|i;
  117.             }
  118.             c++;
  119.         }
  120.         c=c<<1;
  121.     }
  122. }
  123.  
  124. int TKuLZ_DecodeHuffSym(TKuLZ_DecState *ctx, u16 *htab)
  125. {
  126.     int b, c;
  127.     b=(ctx->win>>ctx->pos)&4095;
  128.     c=htab[b];
  129.     if(!((c>>8)&15))
  130.         { __debugbreak(); }
  131.     TKuLZ_SkipBits(ctx, (c>>8)&15);
  132.     return(c&255);
  133. }
  134.  
  135. int TKuLZ_DecodeTagSym(TKuLZ_DecState *ctx)
  136.     { return(TKuLZ_DecodeHuffSym(ctx, ctx->htab_t)); }
  137. int TKuLZ_DecodeLitSym(TKuLZ_DecState *ctx)
  138.     { return(TKuLZ_DecodeHuffSym(ctx, ctx->htab_l)); }
  139. int TKuLZ_DecodeDistSym(TKuLZ_DecState *ctx)
  140.     { return(TKuLZ_DecodeHuffSym(ctx, ctx->htab_d)); }
  141.  
  142. int TKuLZ_DecodeDistance(TKuLZ_DecState *ctx)
  143. {
  144.     int pfx, eb, d;
  145.     pfx=TKuLZ_DecodeDistSym(ctx);
  146.     eb=pfx>>3; d=pfx&7;
  147.     if(eb) { eb--; d=((8+d)<<eb)|TKuLZ_ReadBits(ctx, eb); }
  148.     return(d);
  149. }
  150.  
  151. void TKuLZ_CopyMatch(TKuLZ_DecState *ctx, int len, int dist)
  152. {
  153.     byte *cs, *ct, *cte;
  154.     int i;
  155.    
  156.     ct=ctx->ct; cs=ct-dist; cte=ct+len;
  157.     if(dist>=16)
  158.     {
  159.         while(ct<cte)
  160.             { memcpy(ct, cs, 16); ct+=16; cs+=16; }
  161.     }else
  162. //      if(len>16)
  163.         if(0)
  164.     {
  165.         for(i=0; i<16; i++)
  166.             ct[i]=cs[i];
  167.         while(ct<cte)
  168.             { memcpy(ct, cs, 16); ct+=16; cs+=16; }
  169.     }else
  170.     {
  171.         while(ct<cte)
  172.             { *ct++=*cs++; }
  173.     }
  174.    
  175.     ctx->ct=cte;
  176. }
  177.  
  178. void TKuLZ_DecodeLiterals(TKuLZ_DecState *ctx, int len)
  179. {
  180.     int i;
  181.     i=len;
  182.     while(i--)
  183.         { *ctx->ct++=TKuLZ_DecodeLitSym(ctx); }
  184. }
  185.  
  186. void TKuLZ_DecodeRuns(TKuLZ_DecState *ctx)
  187. {
  188.     int tg, ltg, lll;
  189.     int ll, ml, md, lml, lmd;
  190.     int i, j, k;
  191.  
  192.     lml=0; lmd=0;
  193.     while(1)
  194.     {
  195.         tg=TKuLZ_DecodeTagSym(ctx);
  196.         ll=tg>>4; ml=(tg&15)+3;
  197.         if(ll==15)
  198.             { ll=TKuLZ_DecodeDistance(ctx)+15; }
  199.         if(ml==18)
  200.             { ml=TKuLZ_DecodeDistance(ctx)+18; }
  201.         md=TKuLZ_DecodeDistance(ctx);
  202.         if(!md)
  203.         {
  204.             if(ml==3)
  205.                 { }
  206.             else if(ml==4)
  207.                 { ml=lml; md=lmd; }
  208.             else if(ml==5)
  209.                 { ml=lml; md=TKuLZ_DecodeDistance(ctx); }
  210.             else if(ml==6)
  211.                 { ml=TKuLZ_DecodeDistance(ctx)+3; md=lmd; }
  212.             else
  213.                 { ctx->status=TKULZ_STATUS_BADESC; break; }
  214.         }
  215.         ltg=tg; lll=ll;
  216.         lml=ml; lmd=md;
  217.         if(ll)
  218.             { TKuLZ_DecodeLiterals(ctx, ll); }
  219.         if(!md)
  220.             break;
  221.         TKuLZ_CopyMatch(ctx, ml, md);
  222.     }
  223. }
  224.  
  225. void TKuLZ_DecodeLzBlock(TKuLZ_DecState *ctx)
  226.     { TKuLZ_DecodeRuns(ctx); }
  227.  
  228. void TKuLZ_DecodeRawBlock(TKuLZ_DecState *ctx)
  229. {  
  230.     int i, tgl;
  231.     tgl=TKuLZ_ReadBits(ctx, 2);
  232.     i=TKuLZ_ReadBits(ctx, 12+(tgl*4));
  233.     ctx->pos=(ctx->pos+7)&(~7);
  234.     while(i--)
  235.         { *ctx->ct++=TKuLZ_ReadBits(ctx, 8); }
  236. }
  237.  
  238. void TKuLZ_DecodeTable(TKuLZ_DecState *ctx, int tn)
  239. {
  240.     byte cl[256];
  241.     TKuLZ_ReadPackedLengths(ctx, cl);
  242.     if(tn==0)       { TKuLZ_SetupTableLengths(ctx, ctx->htab_t, cl); }
  243.     else if(tn==1)  { TKuLZ_SetupTableLengths(ctx, ctx->htab_l, cl); }
  244.     else if(tn==2)  { TKuLZ_SetupTableLengths(ctx, ctx->htab_d, cl); }
  245. }
  246.  
  247. void TKuLZ_DecodeBlock(TKuLZ_DecState *ctx)
  248. {
  249.     int tag;
  250.    
  251.     tag=TKuLZ_ReadBits(ctx, 4);
  252.     if(tag==0)
  253.         { ctx->status=TKULZ_STATUS_END; return; }
  254.     if(tag==1)
  255.         { TKuLZ_DecodeRawBlock(ctx); return; }
  256.     if(tag==2)
  257.         { TKuLZ_DecodeLzBlock(ctx); return; }
  258.     if((tag>=4) && (tag<7))
  259.         { TKuLZ_DecodeTable(ctx, tag-4); return; }
  260.     if(tag==9)
  261.         { ctx->status=TKULZ_STATUS_END; TKuLZ_DecodeRawBlock(ctx); return; }
  262.     if(tag==10)
  263.         { ctx->status=TKULZ_STATUS_END; TKuLZ_DecodeLzBlock(ctx); return; }
  264.     ctx->status=TKULZ_STATUS_BADTAG;
  265. }
  266.  
  267. void TKuLZ_SetupDecodeBuffers(TKuLZ_DecState *ctx,
  268.     byte *dst, byte *src, int dsz, int ssz)
  269. {
  270.     ctx->cs=src;    ctx->ct=dst;
  271.     ctx->pos=0;     ctx->status=0;
  272.     TKuLZ_SkipBits(ctx, 16);
  273.     TKuLZ_SkipBits(ctx, 16);
  274. }
  275.  
  276. int TKuLZ_DecodeBuffer(TKuLZ_DecState *ctx,
  277.     byte *dst, byte *src, int dsz, int ssz)
  278. {
  279.     TKuLZ_SetupDecodeBuffers(ctx, dst, src, dsz, ssz);
  280.     while(!(ctx->status))
  281.         { TKuLZ_DecodeBlock(ctx); }
  282.     if(ctx->status && (ctx->status!=1))
  283.         printf("Error %d\n", ctx->status);
  284.     return(ctx->ct-dst);
  285. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement