Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

vaguely fast DXT5 encoder.

By: cr88192 on Feb 12th, 2013  |  syntax: C  |  size: 3.67 KB  |  hits: 47  |  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. Tries to deliver moderate quality, while still trying to allow for reasonably fast encoding.
  9. Generally handles interpolation by treating it like a fixed-point fraction, and using this fraction to index into a table.
  10. */
  11.  
  12. void BGBBTJ_BCn_EncodeBlockDXT5(byte *block,
  13.         byte *rgba, int xstride, int ystride)
  14. {
  15.         static const char idxtab[16]=
  16.                 { 0,0,0,0, 0,0,2,2, 3,3,1,1, 1,1,1,1 };
  17.         static const char idxtab2[16]=
  18.                 { 0,0,0,0, 2,2,3,3, 4,4,5,5, 1,1,1,1 };
  19.         byte pxa[16], pxy[16];
  20.         int p0, p1, p2, p3, p4, p5, p6, p7;
  21.         int l0, l1;
  22.         int mcr, mcg, mcb, mca, mcy;
  23.         int ncr, ncg, ncb, nca, ncy;
  24.         int aca, acy;
  25.         int cr, cg, cb, ca, cy;
  26.         int i, j, k, l;
  27.        
  28.         mcr=255; mcg=255; mcb=255; mca=255; mcy=255;
  29.         ncr=  0; ncg=  0; ncb=  0; nca=  0; ncy=  0;
  30.        
  31.         for(i=0; i<4; i++)
  32.                 for(j=0; j<4; j++)
  33.         {
  34.                 k=(i*ystride)+(j*xstride);
  35.                 cr=rgba[k+0];   cg=rgba[k+1];
  36.                 cb=rgba[k+2];   ca=rgba[k+3];
  37.                 cy=(cr+(2*cg)+cb)>>2;           //Luma
  38.  
  39.                 pxa[i*4+j]=ca;
  40.                 pxy[i*4+j]=cy;
  41.  
  42.                 //Find Mins/Maxs
  43.                 if(cy<mcy) { mcr=cr; mcg=cg; mcb=cb; mcy=cy; }
  44.                 if(cy>ncy) { ncr=cr; ncg=cg; ncb=cb; ncy=cy; }
  45.                 if(ca<mca) { mca=ca; }
  46.                 if(ca>nca) { nca=ca; }
  47.         }
  48.  
  49.         aca=(mca+nca)>>1;               //Median Alpha
  50.         acy=(mcy+ncy)>>1;               //Median Luma
  51.         l0=49152/(nca-aca+1);           //Fix-Point Scale (Alpha)
  52.         l1=32768/(ncy-acy+1);           //Fix-Point Scale (Luma)
  53.  
  54.         //Emit Alpha Block
  55.         block[0]=mca;
  56.         block[1]=nca;
  57.        
  58.         p0=idxtab2[(((pxa[ 0]-aca)*l0)>>13)+8];
  59.         p1=idxtab2[(((pxa[ 1]-aca)*l0)>>13)+8];
  60.         p2=idxtab2[(((pxa[ 2]-aca)*l0)>>13)+8];
  61.         p3=idxtab2[(((pxa[ 3]-aca)*l0)>>13)+8];
  62.         p4=idxtab2[(((pxa[ 4]-aca)*l0)>>13)+8];
  63.         p5=idxtab2[(((pxa[ 5]-aca)*l0)>>13)+8];
  64.         p6=idxtab2[(((pxa[ 6]-aca)*l0)>>13)+8];
  65.         p7=idxtab2[(((pxa[ 7]-aca)*l0)>>13)+8];
  66.         block[2]=p0|(p1<<3)|(p2<<6);
  67.         block[3]=(p2>>2)|(p3<<1)|(p4<<4)|(p5<<7);
  68.         block[4]=(p5>>1)|(p6<<2)|(p7<<5);
  69.         p0=idxtab2[(((pxa[ 8]-aca)*l0)>>13)+8];
  70.         p1=idxtab2[(((pxa[ 9]-aca)*l0)>>13)+8];
  71.         p2=idxtab2[(((pxa[10]-aca)*l0)>>13)+8];
  72.         p3=idxtab2[(((pxa[11]-aca)*l0)>>13)+8];
  73.         p4=idxtab2[(((pxa[12]-aca)*l0)>>13)+8];
  74.         p5=idxtab2[(((pxa[13]-aca)*l0)>>13)+8];
  75.         p6=idxtab2[(((pxa[14]-aca)*l0)>>13)+8];
  76.         p7=idxtab2[(((pxa[15]-aca)*l0)>>13)+8];
  77.         block[5]=p0|(p1<<3)|(p2<<6);
  78.         block[6]=(p2>>2)|(p3<<1)|(p4<<4)|(p5<<7);
  79.         block[7]=(p5>>1)|(p6<<2)|(p7<<5);
  80.  
  81.         //Emit RGB Block
  82.         i=((mcr<<8)&0xF800) | ((mcg<<3)&0x07E0) | ((mcb>>3)&0x001F);
  83.         j=((ncr<<8)&0xF800) | ((ncg<<3)&0x07E0) | ((ncb>>3)&0x001F);
  84.         block[ 8]=i;    block[ 9]=i>>8;
  85.         block[10]=j;    block[11]=j>>8;
  86.  
  87.         p0=idxtab[(((pxy[ 0]-acy)*l1)>>13)+8];
  88.         p1=idxtab[(((pxy[ 1]-acy)*l1)>>13)+8];
  89.         p2=idxtab[(((pxy[ 2]-acy)*l1)>>13)+8];
  90.         p3=idxtab[(((pxy[ 3]-acy)*l1)>>13)+8];
  91.         block[12]=(p3<<6)|(p2<<4)|(p1<<2)|p0;
  92.         p0=idxtab[(((pxy[ 4]-acy)*l1)>>13)+8];
  93.         p1=idxtab[(((pxy[ 5]-acy)*l1)>>13)+8];
  94.         p2=idxtab[(((pxy[ 6]-acy)*l1)>>13)+8];
  95.         p3=idxtab[(((pxy[ 7]-acy)*l1)>>13)+8];
  96.         block[13]=(p3<<6)|(p2<<4)|(p1<<2)|p0;
  97.         p0=idxtab[(((pxy[ 8]-acy)*l1)>>13)+8];
  98.         p1=idxtab[(((pxy[ 9]-acy)*l1)>>13)+8];
  99.         p2=idxtab[(((pxy[10]-acy)*l1)>>13)+8];
  100.         p3=idxtab[(((pxy[11]-acy)*l1)>>13)+8];
  101.         block[14]=(p3<<6)|(p2<<4)|(p1<<2)|p0;
  102.         p0=idxtab[(((pxy[12]-acy)*l1)>>13)+8];
  103.         p1=idxtab[(((pxy[13]-acy)*l1)>>13)+8];
  104.         p2=idxtab[(((pxy[14]-acy)*l1)>>13)+8];
  105.         p3=idxtab[(((pxy[15]-acy)*l1)>>13)+8];
  106.         block[15]=(p3<<6)|(p2<<4)|(p1<<2)|p0;
  107. }
  108.  
  109. BGBBTJ_API void BGBBTJ_BCn_EncodeImageDXT5(byte *block,
  110.         byte *rgba, int xs, int ys, int stride)
  111. {
  112.         int xs1, ys1;
  113.         int i, j;
  114.        
  115.         xs1=xs>>2; ys1=ys>>2;
  116.         for(i=0; i<ys1; i++)
  117.                 for(j=0; j<xs1; j++)
  118.         {
  119.                 BGBBTJ_BCn_EncodeBlockDXT5(
  120.                         block+(i*xs1+j)*16,
  121.                         rgba+(i*4*xs+j*4)*stride,
  122.                         stride, xs*stride);
  123.         }
  124. }