cr88192

Packed DXTn Decoder

Feb 20th, 2013
343
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.92 KB | None | 0 0
  1. /*
  2. Copyright (C) 2013 by Brendan G Bohannon
  3. Copying: http://pastebin.com/iJxtZHm6
  4.  */
  5.  
  6. /*
  7. DXTn packed images.
  8.  
  9. Each block tag will be encoded in the form (byte):
  10. 0 <block:QWORD>     Literal Block.
  11. 1-127               Single byte block index.
  12. 128-191 X           Two byte block index (16384 blocks).
  13. 192-223 XX          Three byte block index (2097152 blocks).
  14. 224-238 I           LZ/RLE Run (2-16 blocks, Index)
  15. 239     LI          LZ/RLE Run (Length, Index)
  16. 240     XXX         24-Bit Index
  17. 241     XXXX        32-Bit Index
  18. 242-246             Literal Blocks (2-6 Blocks)
  19. 247     L           Literal Blocks (L Blocks)
  20. 248-255             Reserved
  21.  
  22. The block index will indicate how many blocks backwards to look for a matching block (1 will repeat the prior block).
  23.  
  24. Length/Index values will use the same organization as above, only limited to encoding numeric values.
  25.  
  26. 0-127               0-127.
  27. 128-191 X           128-16383.
  28. 192-223 XX          16384-2097151.
  29. 240     XXX         24-Bit Index (0-16777215)
  30. 241     XXXX        32-Bit Index (0-4294967295)
  31.  
  32. Note that DXT5 images will be split into 2 block-planes, with the first encoding the alpha component, followed by the plane encoding the RGB components.
  33. */
  34.  
  35. byte *BGBBTJ_PackBCn_DecodeValue(byte *cs, int *rval)
  36. {
  37.     int op, i;
  38.    
  39.     op=*cs++;
  40.     if(op<128)
  41.         { *rval=op; return(cs); }
  42.     if(op<192)
  43.     {
  44.         *rval=((op-128)<<8)|(*cs++);
  45.         return(cs);
  46.     }
  47.     if(op<224)
  48.     {
  49.         i=((op-192)<<8)|(*cs++);
  50.         i=(i<<8)|(*cs++);
  51.         *rval=i;
  52.         return(cs);
  53.     }
  54.  
  55.     if(op==240)
  56.     {
  57.         i=*cs++;
  58.         i=(i<<8)|(*cs++);
  59.         i=(i<<8)|(*cs++);
  60.         *rval=i;
  61.         return(cs);
  62.     }
  63.     if(op==241)
  64.     {
  65.         i=*cs++;            i=(i<<8)|(*cs++);
  66.         i=(i<<8)|(*cs++);   i=(i<<8)|(*cs++);
  67.         *rval=i;
  68.         return(cs);
  69.     }
  70.  
  71.     return(cs);
  72. }
  73.  
  74. byte *BGBBTJ_PackBCn_DecodeRun(byte *cs, int *ridx, int *rlen)
  75. {
  76.     int op, i;
  77.    
  78.     op=*cs++;
  79.     if(!op)
  80.         { *ridx=0; *rlen=0; return(cs); }
  81.     if(op<128)
  82.         { *ridx=op; *rlen=1; return(cs); }
  83.     if(op<192)
  84.     {
  85.         *ridx=((op-128)<<8)|(*cs++);
  86.         *rlen=1;
  87.         return(cs);
  88.     }
  89.     if(op<224)
  90.     {
  91.         i=((op-192)<<8)|(*cs++);
  92.         i=(i<<8)|(*cs++);
  93.         *ridx=i;
  94.         *rlen=1;
  95.         return(cs);
  96.     }
  97.     if(op<239)
  98.     {
  99.         cs=BGBBTJ_PackBCn_DecodeValue(cs, ridx);
  100.         *rlen=(op-224)+2;
  101.         return(cs);
  102.     }
  103.     if(op==239)
  104.     {
  105.         cs=BGBBTJ_PackBCn_DecodeValue(cs, rlen);
  106.         cs=BGBBTJ_PackBCn_DecodeValue(cs, ridx);
  107.         return(cs);
  108.     }
  109.     if(op==240)
  110.     {
  111.         i=*cs++;
  112.         i=(i<<8)|(*cs++);
  113.         i=(i<<8)|(*cs++);
  114.         *ridx=i;
  115.         *rlen=1;
  116.         return(cs);
  117.     }
  118.     if(op==241)
  119.     {
  120.         i=*cs++;            i=(i<<8)|(*cs++);
  121.         i=(i<<8)|(*cs++);   i=(i<<8)|(*cs++);
  122.         *ridx=i;
  123.         *rlen=1;
  124.         return(cs);
  125.     }
  126.  
  127.     if(op<247)
  128.     {
  129.         *ridx=0;
  130.         *rlen=(op-242)+2;
  131.         return(cs);
  132.     }
  133.     if(op==247)
  134.     {
  135.         *ridx=0;
  136.         cs=BGBBTJ_PackBCn_DecodeValue(cs, rlen);
  137.         return(cs);
  138.     }
  139.  
  140.     *ridx=0; *rlen=0;
  141.     return(cs);
  142. }
  143.  
  144. byte *BGBBTJ_PackBCn_DecodeBlockArray(byte *ibuf, byte *blks,
  145.     int count, int stride)
  146. {
  147.     byte *cs, *ct, *cte, *cs1, *ct1, *cs1e;
  148.     int bi, bl;
  149.     int i, j;
  150.  
  151.     cs=ibuf; ct=blks; cte=ct+count*stride;
  152.     while(ct<cte)
  153.     {
  154.         cs=BGBBTJ_PackBCn_DecodeRun(cs, &bi, &bl);
  155.         if(bi==0)
  156.         {
  157.             if(bl>1)
  158.             {
  159. #if defined(X86) || defined(X86_64)
  160.                 cs1e=cs+bl*8;
  161.                 while(cs<cs1e)
  162.                 {
  163.                     *(u64 *)ct=*(u64 *)(cs);
  164.                     cs+=8; ct+=stride;
  165.                 }
  166. #else
  167.                 for(i=0; i<bl; i++)
  168.                     { memcpy(ct+i*stride, cs+i*8, 8); }
  169.                 cs+=bl*8;
  170.                 ct+=bl*stride;
  171. #endif
  172.                 continue;
  173.             }
  174. #if defined(X86) || defined(X86_64)
  175.             *(u64 *)ct=*(u64 *)cs;
  176. #else
  177.             memcpy(ct, cs, 8);
  178. #endif
  179.             ct+=stride; cs+=8;
  180.             continue;
  181.         }
  182.  
  183. #if defined(X86) || defined(X86_64)
  184.         cs1=ct-bi*stride;
  185.         cs1e=cs1+bl*stride;
  186.         while(cs1<cs1e)
  187.         {
  188.             *(u64 *)ct=*(u64 *)(cs1);
  189.             cs1+=stride; ct+=stride;
  190.         }
  191. #else
  192.         for(i=0; i<bl; i++)
  193.             { memcpy(ct+i*stride, ct+(i-bi)*stride, 8); }
  194.         ct+=bl*stride;
  195. #endif
  196.     }
  197.     return(cs);
  198. }
  199.  
  200. BGBBTJ_API int BGBBTJ_PackBCn_DecodeBlocksDXT5(
  201.     byte *ibuf, byte *blks, int count)
  202. {
  203.     byte *cs;
  204.     cs=BGBBTJ_PackBCn_DecodeBlockArray(ibuf, blks, count, 16);
  205.     cs=BGBBTJ_PackBCn_DecodeBlockArray(cs, blks+8, count, 16);
  206.     return(cs-ibuf);
  207. }
Advertisement
Add Comment
Please, Sign In to add comment