Advertisement
cr88192

Packed DXTn Decoder

Feb 20th, 2013
216
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. 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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement