Advertisement
cr88192

vaguely fast DXT5 encoder.

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