Want more features on Pastebin? Sign Up, it's FREE!
Guest

Packed DXTn Decoder

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