[gimp-dds] / tags / release-2.0.3 / dxt.c Repository:
ViewVC logotype

View of /tags/release-2.0.3/dxt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 102 - (download) (as text) (annotate)
Fri Apr 11 18:08:24 2008 UTC (19 months, 1 week ago) by cocidius
File size: 35249 byte(s)
Release 2.0.3 tag
    1 /*
    2    DDS GIMP plugin
    3 
    4    Copyright (C) 2004-2008 Shawn Kirst <skirst@insightbb.com>,
    5    with parts (C) 2003 Arne Reuter <homepage@arnereuter.de> where specified.
    6 
    7    This program is free software; you can redistribute it and/or
    8    modify it under the terms of the GNU General Public
    9    License as published by the Free Software Foundation; either
   10    version 2 of the License, or (at your option) any later version.
   11 
   12    This program is distributed in the hope that it will be useful,
   13    but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15    General Public License for more details.
   16 
   17    You should have received a copy of the GNU General Public License
   18    along with this program; see the file COPYING.  If not, write to
   19    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   20    Boston, MA 02111-1307, USA.
   21 */
   22 
   23 /*
   24  * Parts of this code have been generously released in the public domain
   25  * by Fabian 'ryg' Giesen.  The original code can be found (at the time
   26  * of writing) here:  http://mollyrocket.com/forums/viewtopic.php?t=392
   27  *
   28  * For more information about this code, see the README.dxt file that
   29  * came with the source.
   30  */
   31 
   32 #include <stdlib.h>
   33 #include <string.h>
   34 #include <math.h>
   35 #include <glib.h>
   36 
   37 #include "dds.h"
   38 #include "endian.h"
   39 #include "mipmap.h"
   40 
   41 #include "dxt_tables.h"
   42 
   43 #ifndef MIN
   44 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
   45 #endif
   46 #ifndef MAX
   47 #define MAX(a, b)  ((a) > (b) ? (a) : (b))
   48 #endif
   49 
   50 /* extract 4x4 BGRA block */
   51 static void extract_block(const unsigned char *src, int w,
   52                           unsigned char *block)
   53 {
   54    int i;
   55    for(i = 0; i < 4; ++i)
   56    {
   57       memcpy(&block[i * 4 * 4], src, 4 * 4);
   58       src += w * 4;
   59    }
   60 }
   61 
   62 static inline int mul8bit(int a, int b)
   63 {
   64    int t = a * b + 128;
   65    return((t + (t >> 8)) >> 8);
   66 }
   67 
   68 /* pack BGR8 to RGB565 */
   69 static inline unsigned short pack_rgb565(const unsigned char *c)
   70 {
   71    return(((c[2] >> 3) << 11) | ((c[1] >> 2) << 5) | (c[0] >> 3));
   72 }
   73 
   74 /* unpack RGB565 to BGR */
   75 static void unpack_rgb565(unsigned char *dst, unsigned short v)
   76 {
   77    int r = (v >> 11) & 0x1f;
   78    int g = (v >>  5) & 0x3f;
   79    int b = (v      ) & 0x1f;
   80 
   81    dst[0] = (b << 3) | (b >> 2);
   82    dst[1] = (g << 2) | (g >> 4);
   83    dst[2] = (r << 3) | (r >> 2);
   84 }
   85 
   86 static void lerp_rgb(unsigned char *dst, unsigned char *a, unsigned char *b, int f)
   87 {
   88    dst[0] = a[0] + mul8bit(b[0] - a[0], f);
   89    dst[1] = a[1] + mul8bit(b[1] - a[1], f);
   90    dst[2] = a[2] + mul8bit(b[2] - a[2], f);
   91 }
   92 
   93 static int color_distance(const unsigned char *c0,
   94                           const unsigned char *c1)
   95 {
   96    return(((c0[0] - c1[0]) * (c0[0] - c1[0])) +
   97           ((c0[1] - c1[1]) * (c0[1] - c1[1])) +
   98           ((c0[2] - c1[2]) * (c0[2] - c1[2])));
   99 }
  100 
  101 static int luminance(const unsigned char *c)
  102 {
  103    return((c[2] * 54 + c[1] * 182 + c[0] * 20) >> 8);
  104 }
  105 
  106 /* Block dithering function.  Simply dithers a block to 565 RGB.
  107  * (Floyd-Steinberg)
  108  */
  109 static void dither_block(unsigned char *dst, const unsigned char *block)
  110 {
  111    int err[8], *ep1 = err, *ep2 = err + 4, *tmp;
  112    int c, y;
  113    unsigned char *bp, *dp;
  114    const unsigned char *quant;
  115 
  116    /* process channels seperately */
  117    for(c = 0; c < 3; ++c)
  118    {
  119       bp = (unsigned char *)block;
  120       dp = dst;
  121       quant = (c == 1) ? quantG + 8 : quantRB + 8;
  122 
  123       bp += c;
  124       dp += c;
  125 
  126       memset(err, 0, sizeof(err));
  127 
  128       for(y = 0; y < 4; ++y)
  129       {
  130          /* pixel 0 */
  131          dp[ 0] = quant[bp[ 0] + ((3 * ep2[1] + 5 * ep2[0]) >> 4)];
  132          ep1[0] = bp[ 0] - dp[ 0];
  133 
  134          /* pixel 1 */
  135          dp[ 4] = quant[bp[ 4] + ((7 * ep1[0] + 3 * ep2[2] + 5 * ep2[1] + ep2[0]) >> 4)];
  136          ep1[1] = bp[ 4] - dp[ 4];
  137 
  138          /* pixel 2 */
  139          dp[ 8] = quant[bp[ 8] + ((7 * ep1[1] + 3 * ep2[3] + 5 * ep2[2] + ep2[1]) >> 4)];
  140          ep1[2] = bp[ 8] - dp[ 8];
  141 
  142          /* pixel 3 */
  143          dp[12] = quant[bp[12] + ((7 * ep1[2] + 5 * ep2[3] + ep2[2]) >> 4)];
  144          ep1[3] = bp[12] - dp[12];
  145 
  146          /* advance to next line */
  147          tmp = ep1;
  148          ep1 = ep2;
  149          ep2 = tmp;
  150 
  151          bp += 16;
  152          dp += 16;
  153       }
  154    }
  155 }
  156 
  157 /* Color matching function */
  158 static unsigned int match_colors_block(const unsigned char *block,
  159                                        unsigned char color[4][3],
  160                                        int dither)
  161 {
  162    unsigned int mask = 0;
  163    int dirb = color[0][0] - color[1][0];
  164    int dirg = color[0][1] - color[1][1];
  165    int dirr = color[0][2] - color[1][2];
  166    int dots[16], stops[4];
  167    int c0pt, halfpt, c3pt, dot;
  168    int i;
  169 
  170    for(i = 0; i < 16; ++i)
  171       dots[i] = block[4 * i] * dirb + block[4 * i + 1] * dirg + block[4 * i + 2] * dirr;
  172 
  173    for(i = 0; i < 4; ++i)
  174       stops[i] = color[i][0] * dirb + color[i][1] * dirg + color[i][2] * dirr;
  175 
  176    c0pt = (stops[1] + stops[3]) >> 1;
  177    halfpt = (stops[3] + stops[2]) >> 1;
  178    c3pt = (stops[2] + stops[0]) >> 1;
  179 
  180    if(!dither)
  181    {
  182       /* the version without dithering is straight-forward */
  183       for(i = 15; i >= 0; --i)
  184       {
  185          mask <<= 2;
  186          dot = dots[i];
  187 
  188          if(dot < halfpt)
  189             mask |= (dot < c0pt) ? 1 : 3;
  190          else
  191             mask |= (dot < c3pt) ? 2 : 0;
  192       }
  193    }
  194    else
  195    {
  196       /* with floyd-steinberg dithering (see above) */
  197       int err[8], *ep1 = err, *ep2 = err + 4, *tmp;
  198       int *dp = dots, y, lmask, step;
  199 
  200       c0pt <<= 4;
  201       halfpt <<= 4;
  202       c3pt <<= 4;
  203 
  204       memset(err, 0, sizeof(err));
  205 
  206       for(y = 0; y < 4; ++y)
  207       {
  208          /* pixel 0 */
  209          dot = (dp[0] << 4) + (3 * ep2[1] + 5 * ep2[0]);
  210          if(dot < halfpt)
  211             step = (dot < c0pt) ? 1 : 3;
  212          else
  213             step = (dot < c3pt) ? 2 : 0;
  214 
  215          ep1[0] = dp[0] - stops[step];
  216          lmask = step;
  217 
  218          /* pixel 1 */
  219          dot = (dp[1] << 4) + (7 * ep1[0] + 3 * ep2[2] + 5 * ep2[1] + ep2[0]);
  220          if(dot < halfpt)
  221             step = (dot < c0pt) ? 1 : 3;
  222          else
  223             step = (dot < c3pt) ? 2 : 0;
  224 
  225          ep1[1] = dp[1] - stops[step];
  226          lmask |= step << 2;
  227 
  228          /* pixel 2 */
  229          dot = (dp[2] << 4) + (7 * ep1[1] + 3 * ep2[3] + 5 * ep2[2] + ep2[1]);
  230          if(dot < halfpt)
  231             step = (dot < c0pt) ? 1 : 3;
  232          else
  233             step = (dot < c3pt) ? 2 : 0;
  234 
  235          ep1[2] = dp[2] - stops[step];
  236          lmask |= step << 4;
  237 
  238          /* pixel 3 */
  239          dot = (dp[3] << 4) + (7 * ep1[2] + 5 * ep2[3] + ep2[2]);
  240          if(dot < halfpt)
  241             step = (dot < c0pt) ? 1 : 3;
  242          else
  243             step = (dot < c3pt) ? 2 : 0;
  244 
  245          ep1[3] = dp[3] - stops[step];
  246          lmask |= step << 6;
  247 
  248          /* advance to next line */
  249          tmp = ep1;
  250          ep1 = ep2;
  251          ep2 = tmp;
  252 
  253          dp += 4;
  254          mask |= lmask << (y * 8);
  255       }
  256    }
  257 
  258    return(mask);
  259 }
  260 
  261 /* Special case color matching for DXT1 color blocks with non-opaque
  262  * alpha values.  Simple distance based color matching.  This is my
  263  * little hack, Fabian had no need for DXT1-alpha :)
  264  */
  265 static unsigned int match_colors_block_DXT1alpha(const unsigned char *block,
  266                                                  unsigned char color[4][3])
  267 {
  268    int i, d0, d1, d2, idx;
  269    unsigned int mask = 0;
  270 
  271    for(i = 15; i >= 0; --i)
  272    {
  273       mask <<= 2;
  274       d0 = color_distance(&block[4 * i], color[0]);
  275       d1 = color_distance(&block[4 * i], color[1]);
  276       d2 = color_distance(&block[4 * i], color[2]);
  277       if(block[4 * i + 3] < 128)
  278          idx = 3;
  279       else if(d0 < d1 && d0 < d2)
  280          idx = 0;
  281       else if(d1 < d2)
  282          idx = 1;
  283       else
  284          idx = 2;
  285       mask |= idx;
  286    }
  287 
  288    return(mask);
  289 }
  290 
  291 /* The color optimization function. (Clever code, part 1) */
  292 static void optimize_colors_block(const unsigned char *block,
  293                                   unsigned short *max16, unsigned short *min16)
  294 {
  295    static const int niterpow = 4;
  296 
  297    int mu[3], mn[3], mx[3];
  298    int i, c, r, g, b, dot, iter;
  299    int muv, mnv, mxv, mnd, mxd;
  300    int cov[6];
  301    unsigned char *bp, mnc[3], mxc[3];
  302    float covf[6], vfr, vfg, vfb, magn;
  303    float fr, fg, fb;
  304 
  305    /* determine color distribution */
  306    for(c = 0; c < 3; ++c)
  307    {
  308       bp = (unsigned char *)block + c;
  309 
  310       muv = mnv = mxv = bp[0];
  311       for(i = 4; i < 64; i += 4)
  312       {
  313          muv += bp[i];
  314          if(mnv > bp[i]) mnv = bp[i];
  315          if(mxv < bp[i]) mxv = bp[i];
  316       }
  317 
  318       mu[c] = (muv + 8) >> 4;
  319       mn[c] = mnv;
  320       mx[c] = mxv;
  321    }
  322 
  323    memset(cov, 0, sizeof(cov));
  324 
  325    /* determine covariance matrix */
  326    for(i = 0; i < 16; ++i)
  327    {
  328       b = block[4 * i + 0] - mu[0];
  329       g = block[4 * i + 1] - mu[1];
  330       r = block[4 * i + 2] - mu[2];
  331 
  332       cov[0] += r * r;
  333       cov[1] += r * g;
  334       cov[2] += r * b;
  335       cov[3] += g * g;
  336       cov[4] += g * b;
  337       cov[5] += b * b;
  338    }
  339 
  340    /* convert covariance matrix to float, find principal axis via power iter */
  341    for(i = 0; i < 6; ++i)
  342       covf[i] = cov[i] / 255.0f;
  343 
  344    vfb = mx[0] - mn[0];
  345    vfg = mx[1] - mn[1];
  346    vfr = mx[2] - mn[2];
  347 
  348    for(iter = 0; iter < niterpow; ++iter)
  349    {
  350       fr = vfr * covf[0] + vfg * covf[1] + vfb * covf[2];
  351       fg = vfr * covf[1] + vfg * covf[3] + vfb * covf[4];
  352       fb = vfr * covf[2] + vfg * covf[4] + vfb * covf[5];
  353 
  354       vfr = fr;
  355       vfg = fg;
  356       vfb = fb;
  357    }
  358 
  359    vfr = fabsf(vfr);
  360    vfg = fabsf(vfg);
  361    vfb = fabsf(vfb);
  362 
  363    magn = MAX(MAX(vfr, vfg), vfb);
  364 
  365    if(magn < 4.0) /* too small, default to luminance */
  366    {
  367       r = 148;
  368       g = 300;
  369       b = 58;
  370    }
  371    else
  372    {
  373       magn = 512.0f / magn;
  374       r = (int)(vfr * magn);
  375       g = (int)(vfg * magn);
  376       b = (int)(vfb * magn);
  377    }
  378 
  379    /* pick colors at extreme points */
  380    mnd =  0x7fffffff;
  381    mxd = -0x7fffffff;
  382 
  383    for(i = 0; i < 16; ++i)
  384    {
  385       dot = block[4 * i] * b + block[4 * i + 1] * g + block[4 * i + 2] * r;
  386 
  387       if(dot < mnd)
  388       {
  389          mnd = dot;
  390          memcpy(mnc, &block[4 * i], 3);
  391       }
  392       if(dot > mxd)
  393       {
  394          mxd = dot;
  395          memcpy(mxc, &block[4 * i], 3);
  396       }
  397    }
  398 
  399    /* reduce to 16-bit colors */
  400    *max16 = pack_rgb565(mxc);
  401    *min16 = pack_rgb565(mnc);
  402 }
  403 
  404 /* The refinement function (Clever code, part 2)
  405  * Tries to optimize colors to suit block contents better.
  406  * (By solving a least squares system via normal equations + Cramer's rule)
  407  */
  408 static int refine_block(const unsigned char *block,
  409                         unsigned short *max16, unsigned short *min16,
  410                         unsigned int mask)
  411 {
  412    static const int w1tab[4] = {3, 0, 2, 1};
  413    static const int prods[4] = {0x090000, 0x000900, 0x040102, 0x010402};
  414    /* ^ Some magic to save a lot of multiplies in the accumulating loop... */
  415 
  416    int akku = 0;
  417    int At1_r, At1_g, At1_b;
  418    int At2_r, At2_g, At2_b;
  419    unsigned int cm = mask;
  420    int i, step, w1, r, g, b;
  421    int xx, yy, xy;
  422    float frb, fg;
  423    unsigned short v, oldmin, oldmax;
  424    int s;
  425 
  426    oldmin = *min16;
  427    oldmax = *max16;
  428    if((mask ^ (mask << 2)) < 4) /* all pixels have the same index */
  429    {
  430       /* degenerate system, use optimal single-color match for average color */
  431       r = g = b = 8;
  432       for(i = 0; i < 16; ++i)
  433       {
  434          r += block[4 * i + 2];
  435          g += block[4 * i + 1];
  436          b += block[4 * i + 0];
  437       }
  438 
  439       r >>= 4;
  440       g >>= 4;
  441       b >>= 4;
  442 
  443       *max16 = (omatch5[r][0] << 11) | (omatch6[g][0] << 5) | omatch5[b][0];
  444       *min16 = (omatch5[r][1] << 11) | (omatch6[g][1] << 5) | omatch5[b][1];
  445       return(*min16 != oldmin || *max16 != oldmax);
  446    }
  447 
  448    At1_r = At1_g = At1_b = 0;
  449    At2_r = At2_g = At2_b = 0;
  450 
  451    for(i = 0; i < 16; ++i, cm >>= 2)
  452    {
  453       step = cm & 3;
  454       w1 = w1tab[step];
  455       r = block[4 * i + 2];
  456       g = block[4 * i + 1];
  457       b = block[4 * i + 0];
  458 
  459       akku  += prods[step];
  460       At1_r += w1 * r;
  461       At1_g += w1 * g;
  462       At1_b += w1 * b;
  463       At2_r += r;
  464       At2_g += g;
  465       At2_b += b;
  466    }
  467 
  468    At2_r = 3 * At2_r - At1_r;
  469    At2_g = 3 * At2_g - At1_g;
  470    At2_b = 3 * At2_b - At1_b;
  471 
  472    /* extract solutions and decide solvability */
  473    xx = akku >> 16;
  474    yy = (akku >> 8) & 0xff;
  475    xy = (akku >> 0) & 0xff;
  476 
  477    frb = 3.0f * 31.0f / 255.0f / (xx * yy - xy * xy);
  478    fg = frb * 63.0f / 31.0f;
  479 
  480    /* solve */
  481    s = (int)((At1_r * yy - At2_r * xy) * frb + 0.5f);
  482    if(s < 0) s = 0;
  483    if(s > 31) s = 31;
  484    v = s << 11;
  485    s = (int)((At1_g * yy - At2_g * xy) * fg + 0.5f);
  486    if(s < 0) s = 0;
  487    if(s > 63) s = 63;
  488    v |= s << 5;
  489    s = (int)((At1_b * yy - At2_b * xy) * frb + 0.5f);
  490    if(s < 0) s = 0;
  491    if(s > 31) s = 31;
  492    v |= s;
  493    *max16 = v;
  494 
  495    s = (int)((At2_r * xx - At1_r * xy) * frb + 0.5f);
  496    if(s < 0) s = 0;
  497    if(s > 31) s = 31;
  498    v = s << 11;
  499    s = (int)((At2_g * xx - At1_g * xy) * fg + 0.5f);
  500    if(s < 0) s = 0;
  501    if(s > 63) s = 63;
  502    v |= s << 5;
  503    s = (int)((At2_b * xx - At1_b * xy) * frb + 0.5f);
  504    if(s < 0) s = 0;
  505    if(s > 31) s = 31;
  506    v |= s;
  507    *min16 = v;
  508 
  509    return(oldmin != *min16 || oldmax != *max16);
  510 }
  511 
  512 /* Find min/max colors by distance */
  513 static void get_min_max_colors_distance(const unsigned char *block,
  514                                         unsigned short *max16,
  515                                         unsigned short *min16)
  516 {
  517    int i, j, dist, maxdist = -1;
  518    unsigned short c0 = 0, c1 = 0;
  519 
  520    for(i = 0; i < 64 - 4; i += 4)
  521    {
  522       for(j = i + 4; j < 64; j += 4)
  523       {
  524          dist = color_distance(&block[i], &block[j]);
  525          if(dist > maxdist)
  526          {
  527             maxdist = dist;
  528             c0 = pack_rgb565(block + i);
  529             c1 = pack_rgb565(block + j);
  530          }
  531       }
  532    }
  533 
  534    *max16 = MAX(c0, c1);
  535    *min16 = MIN(c0, c1);
  536 }
  537 
  538 /* Find min-max colors by luminance */
  539 static void get_min_max_colors_luminance(const unsigned char *block,
  540                                          unsigned short *max16,
  541                                          unsigned short *min16)
  542 {
  543    int i, lum, minlum = 0x7fffffff, maxlum = -0x7fffffff;
  544    unsigned char mn[3], mx[3];
  545 
  546    for(i = 0; i < 16; ++i)
  547    {
  548       lum = luminance(&block[4 * i]);
  549       if(lum > maxlum)
  550       {
  551          maxlum = lum;
  552          memcpy(mx, &block[4 * i], 3);
  553       }
  554       if(lum < minlum)
  555       {
  556          minlum = lum;
  557          memcpy(mn, &block[4 * i], 3);
  558       }
  559    }
  560 
  561    *max16 = pack_rgb565(mx);
  562    *min16 = pack_rgb565(mn);
  563 }
  564 
  565 #define INSET_SHIFT  4
  566 
  567 /* Find min-max colors using the inset bounding box method */
  568 static void get_min_max_colors_inset_bbox(const unsigned char *block,
  569                                           unsigned short *max16,
  570                                           unsigned short *min16)
  571 {
  572    int i;
  573    unsigned char inset[3], mx[3], mn[3];
  574 
  575    mn[0] = mn[1] = mn[2] = 255;
  576    mx[0] = mx[1] = mx[2] = 0;
  577 
  578    for(i = 0; i < 16; ++i)
  579    {
  580       if(block[4 * i + 0] < mn[0]) mn[0] = block[4 * i + 0];
  581       if(block[4 * i + 1] < mn[1]) mn[1] = block[4 * i + 1];
  582       if(block[4 * i + 2] < mn[2]) mn[2] = block[4 * i + 2];
  583       if(block[4 * i + 0] > mx[0]) mx[0] = block[4 * i + 0];
  584       if(block[4 * i + 1] > mx[1]) mx[1] = block[4 * i + 1];
  585       if(block[4 * i + 2] > mx[2]) mx[2] = block[4 * i + 2];
  586    }
  587 
  588    inset[0] = (mx[0] - mn[0]) >> INSET_SHIFT;
  589    inset[1] = (mx[1] - mn[1]) >> INSET_SHIFT;
  590    inset[2] = (mx[2] - mn[2]) >> INSET_SHIFT;
  591 
  592    mn[0] = (mn[0] + inset[0] <= 255) ? mn[0] + inset[0] : 255;
  593    mn[1] = (mn[1] + inset[1] <= 255) ? mn[1] + inset[1] : 255;
  594    mn[2] = (mn[2] + inset[2] <= 255) ? mn[2] + inset[2] : 255;
  595 
  596    mx[0] = (mx[0] >= inset[0]) ? mx[0] - inset[0] : 0;
  597    mx[1] = (mx[1] >= inset[1]) ? mx[1] - inset[1] : 0;
  598    mx[2] = (mx[2] >= inset[2]) ? mx[2] - inset[2] : 0;
  599 
  600    *min16 = pack_rgb565(mn);
  601    *max16 = pack_rgb565(mx);
  602 }
  603 
  604 static void get_min_max_YCoCg(const unsigned char *block,
  605                               unsigned char *mincolor, unsigned char *maxcolor)
  606 {
  607    int i;
  608 
  609    mincolor[2] = mincolor[1] = 255;
  610    maxcolor[2] = maxcolor[1] = 0;
  611 
  612    for(i = 0; i < 16; ++i)
  613    {
  614       if(block[4 * i + 2] < mincolor[2]) mincolor[2] = block[4 * i + 2];
  615       if(block[4 * i + 1] < mincolor[1]) mincolor[1] = block[4 * i + 1];
  616       if(block[4 * i + 2] > maxcolor[2]) maxcolor[2] = block[4 * i + 2];
  617       if(block[4 * i + 1] > maxcolor[1]) maxcolor[1] = block[4 * i + 1];
  618    }
  619 }
  620 
  621 static void scale_YCoCg(unsigned char *block,
  622                         unsigned char *mincolor, unsigned char *maxcolor)
  623 {
  624    const int s0 = 128 / 2 - 1;
  625    const int s1 = 128 / 4 - 1;
  626    int m0, m1, m2, m3;
  627    int mask0, mask1, scale;
  628    int i;
  629 
  630    m0 = abs(mincolor[2] - 128);
  631    m1 = abs(mincolor[1] - 128);
  632    m2 = abs(maxcolor[2] - 128);
  633    m3 = abs(maxcolor[1] - 128);
  634 
  635    if(m1 > m0) m0 = m1;
  636    if(m3 > m2) m2 = m3;
  637    if(m2 > m0) m0 = m2;
  638 
  639    mask0 = -(m0 <= s0);
  640    mask1 = -(m0 <= s1);
  641    scale = 1 + (1 & mask0) + (2 & mask1);
  642 
  643    mincolor[2] = (mincolor[2] - 128) * scale + 128;
  644    mincolor[1] = (mincolor[1] - 128) * scale + 128;
  645    mincolor[0] = (scale - 1) << 3;
  646 
  647    maxcolor[2] = (maxcolor[2] - 128) * scale + 128;
  648    maxcolor[1] = (maxcolor[1] - 128) * scale + 128;
  649    maxcolor[0] = (scale - 1) << 3;
  650 
  651    for(i = 0; i < 16; ++i)
  652    {
  653       block[i * 4 + 2] = (block[i * 4 + 2] - 128) * scale + 128;
  654       block[i * 4 + 1] = (block[i * 4 + 1] - 128) * scale + 128;
  655    }
  656 }
  657 
  658 static void inset_bbox_YCoCg(unsigned char *mincolor, unsigned char *maxcolor)
  659 {
  660    int inset[4], mini[4], maxi[4];
  661 
  662    inset[2] = (maxcolor[2] - mincolor[2]) - ((1 << (INSET_SHIFT - 1)) - 1);
  663    inset[1] = (maxcolor[1] - mincolor[1]) - ((1 << (INSET_SHIFT - 1)) - 1);
  664 
  665    mini[2] = ((mincolor[2] << INSET_SHIFT) + inset[2]) >> INSET_SHIFT;
  666    mini[1] = ((mincolor[1] << INSET_SHIFT) + inset[1]) >> INSET_SHIFT;
  667 
  668    maxi[2] = ((maxcolor[2] << INSET_SHIFT) - inset[2]) >> INSET_SHIFT;
  669    maxi[1] = ((maxcolor[1] << INSET_SHIFT) - inset[1]) >> INSET_SHIFT;
  670 
  671    mini[2] = (mini[2] >= 0) ? mini[2] : 0;
  672    mini[1] = (mini[1] >= 0) ? mini[1] : 0;
  673 
  674    maxi[2] = (maxi[2] <= 255) ? maxi[2] : 255;
  675    maxi[1] = (maxi[1] <= 255) ? maxi[1] : 255;
  676 
  677    mincolor[2] = (mini[2] & 0xf8) | (mini[2] >> 5);
  678    mincolor[1] = (mini[1] & 0xfc) | (mini[1] >> 6);
  679 
  680    maxcolor[2] = (maxi[2] & 0xf8) | (maxi[2] >> 5);
  681    maxcolor[1] = (maxi[1] & 0xfc) | (maxi[1] >> 6);
  682 }
  683 
  684 static void select_diagonal_YCoCg(const unsigned char *block,
  685                                   unsigned char *mincolor,
  686                                   unsigned char *maxcolor)
  687 {
  688    unsigned char mid0, mid1, side, mask, b0, b1, c0, c1;
  689    int i;
  690 
  691    mid0 = ((int)mincolor[2] + maxcolor[2] + 1) >> 1;
  692    mid1 = ((int)mincolor[1] + maxcolor[1] + 1) >> 1;
  693 
  694    side = 0;
  695    for(i = 0; i < 16; ++i)
  696    {
  697       b0 = block[i * 4 + 2] >= mid0;
  698       b1 = block[i * 4 + 1] >= mid1;
  699       side += (b0 ^ b1);
  700    }
  701 
  702    mask = -(side > 8);
  703    mask &= -(mincolor[2] != maxcolor[2]);
  704 
  705    c0 = mincolor[1];
  706    c1 = maxcolor[1];
  707 
  708    c0 ^= c1;
  709    mask &= c0;
  710    c1 ^= mask;
  711    c0 ^= c1;
  712 
  713    mincolor[1] = c0;
  714    maxcolor[1] = c1;
  715 }
  716 
  717 static void eval_colors(unsigned char color[4][3],
  718                         unsigned short c0, unsigned short c1)
  719 {
  720    unpack_rgb565(color[0], c0);
  721    unpack_rgb565(color[1], c1);
  722    if(c0 > c1)
  723    {
  724       lerp_rgb(color[2], color[0], color[1], 0x55);
  725       lerp_rgb(color[3], color[0], color[1], 0xaa);
  726    }
  727    else
  728    {
  729       color[2][0] = (color[0][0] + color[1][0]) >> 1;
  730       color[2][1] = (color[0][1] + color[1][1]) >> 1;
  731       color[2][2] = (color[0][2] + color[1][2]) >> 1;
  732 
  733       color[3][0] = color[3][1] = color[3][2] = 0;
  734    }
  735 }
  736 
  737 static void encode_color_block(unsigned char *dst,
  738                                const unsigned char *block,
  739                                int type, int dither, int dxt1_alpha)
  740 {
  741    unsigned char dblock[64], color[4][3];
  742    unsigned short min16, max16;
  743    unsigned int v, mn, mx, mask;
  744    int i, block_has_alpha = 0;
  745 
  746    /* find min/max colors, determine if alpha values present in block
  747     * (for DXT1-alpha)
  748     */
  749    mn = mx = GETL32(block);
  750    for(i = 0; i < 16; ++i)
  751    {
  752       block_has_alpha = block_has_alpha || (block[4 * i + 3] < 255);
  753       v = GETL32(&block[4 * i]);
  754       if(v > mx) mx = v;
  755       if(v < mn) mn = v;
  756    }
  757 
  758    if(mn != mx) /* block is not a solid color, continue with compression */
  759    {
  760       /* compute dithered block for PCA if desired */
  761       if(dither)
  762          dither_block(dblock, block);
  763 
  764       switch(type)
  765       {
  766          case DDS_COLOR_DISTANCE:
  767             get_min_max_colors_distance(dither ? dblock : block, &max16, &min16);
  768             break;
  769          case DDS_COLOR_LUMINANCE:
  770             get_min_max_colors_luminance(dither ? dblock : block, &max16, &min16);
  771             break;
  772          case DDS_COLOR_INSET_BBOX:
  773             get_min_max_colors_inset_bbox(dither ? dblock : block, &max16, &min16);
  774             break;
  775          default:
  776             /* pca + map along principal axis */
  777             optimize_colors_block(dither ? dblock : block, &max16, &min16);
  778             if(max16 != min16)
  779             {
  780                eval_colors(color, max16, min16);
  781                mask = match_colors_block(block, color, dither != 0);
  782             }
  783             else
  784                mask = 0;
  785 
  786             /* refine */
  787             refine_block(dither ? dblock : block, &max16, &min16, mask);
  788             break;
  789       }
  790 
  791       if(max16 != min16)
  792       {
  793          eval_colors(color, max16, min16);
  794          mask = match_colors_block(block, color, dither != 0);
  795       }
  796       else
  797          mask = 0;
  798    }
  799    else /* constant color */
  800    {
  801       mask = 0xaaaaaaaa;
  802       max16 = (omatch5[block[2]][0] << 11) |
  803               (omatch6[block[1]][0] <<  5) |
  804               (omatch5[block[0]][0]      );
  805       min16 = (omatch5[block[2]][1] << 11) |
  806               (omatch6[block[1]][1] <<  5) |
  807               (omatch5[block[0]][1]      );
  808    }
  809 
  810    /* HACK! for DXT1 blocks which have non-opaque pixels */
  811    if(dxt1_alpha && block_has_alpha)
  812    {
  813       if(max16 > min16)
  814       {
  815          max16 ^= min16; min16 ^= max16; max16 ^= min16;
  816       }
  817       eval_colors(color, max16, min16);
  818       mask = match_colors_block_DXT1alpha(block, color);
  819    }
  820 
  821    if(max16 < min16 && !(dxt1_alpha && block_has_alpha))
  822    {
  823       max16 ^= min16; min16 ^= max16; max16 ^= min16;
  824       mask ^= 0x55555555;
  825    }
  826 
  827    PUTL16(&dst[0], max16);
  828    PUTL16(&dst[2], min16);
  829    PUTL32(&dst[4], mask);
  830 }
  831 
  832 /* write DXT3 alpha block */
  833 static void encode_alpha_block_DXT3(unsigned char *dst,
  834                                     const unsigned char *block)
  835 {
  836    int i, a1, a2;
  837 
  838    block += 3;
  839 
  840    for(i = 0; i < 8; ++i)
  841    {
  842       a1 = block[8 * i + 0];
  843       a2 = block[8 * i + 4];
  844       *dst++ = ((a2 >> 4) << 4) | (a1 >> 4);
  845    }
  846 }
  847 
  848 /* Write DXT5 alpha block */
  849 static void encode_alpha_block_DXT5(unsigned char *dst,
  850                                     const unsigned char *block)
  851 {
  852    int i, v, mn, mx;
  853    int dist, bias, dist2, dist4, bits, mask;
  854    int a, idx, t;
  855 
  856    block += 3;
  857 
  858    /* find min/max alpha pair */
  859    mn = mx = block[0];
  860    for(i = 0; i < 16; ++i)
  861    {
  862       v = block[4 * i];
  863       if(v > mx) mx = v;
  864       if(v < mn) mn = v;
  865    }
  866 
  867    /* encode them */
  868    *dst++ = mx;
  869    *dst++ = mn;
  870 
  871    /* determine bias and emit indices */
  872    dist = mx - mn;
  873    bias = mn * 7 - (dist >> 1);
  874    dist4 = dist * 4;
  875    dist2 = dist * 2;
  876    bits = 0;
  877    mask = 0;
  878 
  879    for(i = 0; i < 16; ++i)
  880    {
  881       a = block[4 * i] * 7 - bias;
  882 
  883       /* select index (hooray for bit magic) */
  884       t = (dist4 - a) >> 31; idx =  t & 4; a -= dist4 & t;
  885       t = (dist2 - a) >> 31; idx += t & 2; a -= dist2 & t;
  886       t = (dist  - a) >> 31; idx += t & 1;
  887 
  888       idx = -idx & 7;
  889       idx ^= (2 > idx);
  890 
  891       /* write index */
  892       mask |= idx << bits;
  893       if((bits += 3) >= 8)
  894       {
  895          *dst++ = mask;
  896          mask >>= 8;
  897          bits -= 8;
  898       }
  899    }
  900 }
  901 
  902 static void compress_DXT1(unsigned char *dst, const unsigned char *src,
  903                           int w, int h, int type, int dither, int alpha)
  904 {
  905    unsigned char block[64];
  906    int x, y;
  907 
  908    for(y = 0; y < h; y += 4, src += w * 4 * 4)
  909    {
  910       for(x = 0; x < w; x += 4)
  911       {
  912          extract_block(src + x * 4, w, block);
  913          encode_color_block(dst, block, type, dither, alpha);
  914          dst += 8;
  915       }
  916    }
  917 }
  918 
  919 static void compress_DXT3(unsigned char *dst, const unsigned char *src,
  920                           int w, int h, int type, int dither)
  921 {
  922    unsigned char block[64];
  923    int x, y;
  924 
  925    for(y = 0; y < h; y += 4, src += w * 4 * 4)
  926    {
  927       for(x = 0; x < w; x += 4)
  928       {
  929          extract_block(src + x * 4, w, block);
  930          encode_alpha_block_DXT3(dst, block);
  931          encode_color_block(dst + 8, block, type, dither, 0);
  932          dst += 16;
  933       }
  934    }
  935 }
  936 
  937 static void compress_DXT5(unsigned char *dst, const unsigned char *src,
  938                           int w, int h, int type, int dither)
  939 {
  940    unsigned char block[64];
  941    int x, y;
  942 
  943    for(y = 0; y < h; y += 4, src += w * 4 * 4)
  944    {
  945       for(x = 0; x < w; x += 4)
  946       {
  947          extract_block(src + x * 4, w, block);
  948          encode_alpha_block_DXT5(dst, block);
  949          encode_color_block(dst + 8, block, type, dither, 0);
  950          dst += 16;
  951       }
  952    }
  953 }
  954 
  955 static void compress_BC4(unsigned char *dst, const unsigned char *src,
  956                          int w, int h)
  957 {
  958    unsigned char block[64];
  959    int x, y;
  960 
  961    for(y = 0; y < h; y += 4, src += w * 4 * 4)
  962    {
  963       for(x = 0; x < w; x += 4)
  964       {
  965          extract_block(src + x * 4, w, block);
  966          encode_alpha_block_DXT5(dst, block - 1);
  967          dst += 8;
  968       }
  969    }
  970 }
  971 
  972 static void compress_BC5(unsigned char *dst, const unsigned char *src,
  973                          int w, int h)
  974 {
  975    unsigned char block[64];
  976    int x, y;
  977 
  978    for(y = 0; y < h; y += 4, src += w * 4 * 4)
  979    {
  980       for(x = 0; x < w; x += 4)
  981       {
  982          extract_block(src + x * 4, w, block);
  983          encode_alpha_block_DXT5(dst, block - 2);
  984          encode_alpha_block_DXT5(dst + 8, block - 1);
  985          dst += 16;
  986       }
  987    }
  988 }
  989 
  990 static void compress_YCoCg(unsigned char *dst, const unsigned char *src,
  991                            int w, int h)
  992 {
  993    unsigned char block[64], colors[4][3];
  994    unsigned char *maxcolor, *mincolor;
  995    unsigned int mask;
  996    int c0, c1, d0, d1, d2, d3;
  997    int b0, b1, b2, b3, b4;
  998    int x0, x1, x2;
  999    int x, y, i;
 1000 
 1001    for(y = 0; y < h; y += 4, src += w * 4 * 4)
 1002    {
 1003       for(x = 0; x < w; x += 4)
 1004       {
 1005          extract_block(src + x * 4, w, block);
 1006 
 1007          encode_alpha_block_DXT5(dst, block);
 1008 
 1009          maxcolor = &colors[0][0];
 1010          mincolor = &colors[1][0];
 1011 
 1012          get_min_max_YCoCg(block, mincolor, maxcolor);
 1013          scale_YCoCg(block, mincolor, maxcolor);
 1014          inset_bbox_YCoCg(mincolor, maxcolor);
 1015          select_diagonal_YCoCg(block, mincolor, maxcolor);
 1016 
 1017          lerp_rgb(&colors[2][0], maxcolor, mincolor, 0x55);
 1018          lerp_rgb(&colors[3][0], maxcolor, mincolor, 0xaa);
 1019 
 1020          mask = 0;
 1021 
 1022          for(i = 15; i >= 0; --i)
 1023          {
 1024             c0 = block[4 * i + 2];
 1025             c1 = block[4 * i + 1];
 1026 
 1027             d0 = abs(colors[0][2] - c0) + abs(colors[0][1] - c1);
 1028             d1 = abs(colors[1][2] - c0) + abs(colors[1][1] - c1);
 1029             d2 = abs(colors[2][2] - c0) + abs(colors[2][1] - c1);
 1030             d3 = abs(colors[3][2] - c0) + abs(colors[3][1] - c1);
 1031 
 1032             b0 = d0 > d3;
 1033             b1 = d1 > d2;
 1034             b2 = d0 > d2;
 1035             b3 = d1 > d3;
 1036             b4 = d2 > d3;
 1037 
 1038             x0 = b1 & b2;
 1039             x1 = b0 & b3;
 1040             x2 = b0 & b4;
 1041 
 1042             mask <<= 2;
 1043             mask |= (x1 | ((x0 | x1) << 1));
 1044          }
 1045 
 1046          PUTL16(&dst[ 8], pack_rgb565(maxcolor));
 1047          PUTL16(&dst[10], pack_rgb565(mincolor));
 1048          PUTL32(&dst[12], mask);
 1049 
 1050          dst += 16;
 1051       }
 1052    }
 1053 }
 1054 
 1055 int dxt_compress(unsigned char *dst, unsigned char *src, int format,
 1056                  unsigned int width, unsigned int height, int bpp,
 1057                  int mipmaps, int type, int dither)
 1058 {
 1059    int i, size, w, h;
 1060    unsigned int offset;
 1061    unsigned char *tmp;
 1062    int j;
 1063    unsigned char *tmp2, *s;
 1064    int dxt1_alpha = 0;
 1065 
 1066    if(!(IS_POT(width) && IS_POT(height)))
 1067       return(0);
 1068 
 1069    size = get_mipmapped_size(width, height, bpp, 0, mipmaps,
 1070                              DDS_COMPRESS_NONE);
 1071    tmp = g_malloc(size);
 1072    generate_mipmaps(tmp, src, width, height, bpp, 0, mipmaps);
 1073 
 1074    if(bpp == 4 && format == DDS_COMPRESS_BC1)
 1075       dxt1_alpha = 1;
 1076 
 1077    if(bpp == 1)
 1078    {
 1079       /* grayscale promoted to BGRA */
 1080 
 1081       size = get_mipmapped_size(width, height, 4, 0, mipmaps,
 1082                                 DDS_COMPRESS_NONE);
 1083       tmp2 = g_malloc(size);
 1084 
 1085       for(i = j = 0; j < size; ++i, j += 4)
 1086       {
 1087          tmp2[j + 0] = tmp[i];
 1088          tmp2[j + 1] = tmp[i];
 1089          tmp2[j + 2] = tmp[i];
 1090          tmp2[j + 3] = 255;
 1091       }
 1092 
 1093       g_free(tmp);
 1094       tmp = tmp2;
 1095       bpp = 4;
 1096    }
 1097    else if(bpp == 2)
 1098    {
 1099       /* gray-alpha promoted to BGRA */
 1100 
 1101       size = get_mipmapped_size(width, height, 4, 0, mipmaps,
 1102                                 DDS_COMPRESS_NONE);
 1103       tmp2 = g_malloc(size);
 1104 
 1105       for(i = j = 0; j < size; i += 2, j += 4)
 1106       {
 1107          tmp2[j + 0] = tmp[i];
 1108          tmp2[j + 1] = tmp[i];
 1109          tmp2[j + 2] = tmp[i];
 1110          tmp2[j + 3] = tmp[i + 1];
 1111       }
 1112 
 1113       g_free(tmp);
 1114       tmp = tmp2;
 1115       bpp = 4;
 1116    }
 1117    else if(bpp == 3)
 1118    {
 1119       size = get_mipmapped_size(width, height, 4, 0, mipmaps,
 1120                                 DDS_COMPRESS_NONE);
 1121       tmp2 = g_malloc(size);
 1122 
 1123       for(i = j = 0; j < size; i += 3, j += 4)
 1124       {
 1125          tmp2[j + 0] = tmp[i + 0];
 1126          tmp2[j + 1] = tmp[i + 1];
 1127          tmp2[j + 2] = tmp[i + 2];
 1128          tmp2[j + 3] = 255;
 1129       }
 1130 
 1131       g_free(tmp);
 1132       tmp = tmp2;
 1133       bpp = 4;
 1134    }
 1135 
 1136    offset = 0;
 1137    w = width;
 1138    h = height;
 1139    s = tmp;
 1140 
 1141    for(i = 0; i < mipmaps; ++i)
 1142    {
 1143       switch(format)
 1144       {
 1145          case DDS_COMPRESS_BC1:
 1146             compress_DXT1(dst + offset, s, w, h, type, dither, dxt1_alpha);
 1147             break;
 1148          case DDS_COMPRESS_BC2:
 1149             compress_DXT3(dst + offset, s, w, h, type, dither);
 1150             break;
 1151          case DDS_COMPRESS_BC3:
 1152             compress_DXT5(dst + offset, s, w, h, type, dither);
 1153             break;
 1154          case DDS_COMPRESS_BC4:
 1155             compress_BC4(dst + offset, s, w, h);
 1156             break;
 1157          case DDS_COMPRESS_BC5:
 1158             compress_BC5(dst + offset, s, w, h);
 1159             break;
 1160          case DDS_COMPRESS_YCOCGS:
 1161             compress_YCoCg(dst + offset, s, w, h);
 1162             break;
 1163          default:
 1164             compress_DXT5(dst + offset, s, w, h, type, dither);
 1165             break;
 1166       }
 1167       s += (w * h * bpp);
 1168       offset += get_mipmapped_size(w, h, 0, 0, 1, format);
 1169       if(w > 1) w >>= 1;
 1170       if(h > 1) h >>= 1;
 1171    }
 1172 
 1173    g_free(tmp);
 1174 
 1175    return(1);
 1176 }
 1177 
 1178 static void decode_color_block(unsigned char *dst, unsigned char *src,
 1179                                int w, int h, int rowbytes, int format)
 1180 {
 1181    int i, x, y;
 1182    unsigned int indexes, idx;
 1183    unsigned char *d;
 1184    unsigned char colors[4][3];
 1185    unsigned short c0, c1;
 1186 
 1187    c0 = GETL16(&src[0]);
 1188    c1 = GETL16(&src[2]);
 1189 
 1190    unpack_rgb565(colors[0], c0);
 1191    unpack_rgb565(colors[1], c1);
 1192 
 1193    if((c0 > c1) || (format == DDS_COMPRESS_BC3))
 1194    {
 1195       lerp_rgb(colors[2], colors[0], colors[1], 0x55);
 1196       lerp_rgb(colors[3], colors[0], colors[1], 0xaa);
 1197    }
 1198    else
 1199    {
 1200       for(i = 0; i < 3; ++i)
 1201       {
 1202          colors[2][i] = (colors[0][i] + colors[1][i] + 1) >> 1;
 1203          colors[3][i] = 255;
 1204       }
 1205    }
 1206 
 1207    src += 4;
 1208    for(y = 0; y < h; ++y)
 1209    {
 1210       d = dst + (y * rowbytes);
 1211       indexes = src[y];
 1212       for(x = 0; x < w; ++x)
 1213       {
 1214          idx = indexes & 0x03;
 1215          d[0] = colors[idx][2];
 1216          d[1] = colors[idx][1];
 1217          d[2] = colors[idx][0];
 1218          if(format == DDS_COMPRESS_BC1)
 1219             d[3] = ((c0 <= c1) && idx == 3) ? 0 : 255;
 1220          indexes >>= 2;
 1221          d += 4;
 1222       }
 1223    }
 1224 }
 1225 
 1226 static void decode_alpha_block_DXT3(unsigned char *dst, unsigned char *src,
 1227                                     int w, int h, int rowbytes)
 1228 {
 1229    int x, y;
 1230    unsigned char *d;
 1231    unsigned int bits;
 1232 
 1233    for(y = 0; y < h; ++y)
 1234    {
 1235       d = dst + (y * rowbytes);
 1236       bits = GETL16(&src[2 * y]);
 1237       for(x = 0; x < w; ++x)
 1238       {
 1239          d[0] = (bits & 0x0f) * 17;
 1240          bits >>= 4;
 1241          d += 4;
 1242       }
 1243    }
 1244 }
 1245 
 1246 static void decode_alpha_block_DXT5(unsigned char *dst, unsigned char *src,
 1247                                     int w, int h, int bpp, int rowbytes)
 1248 {
 1249    int x, y, code;
 1250    unsigned char *d;
 1251    unsigned char a0 = src[0];
 1252    unsigned char a1 = src[1];
 1253    unsigned long long bits = GETL64(src) >> 16;
 1254 
 1255    for(y = 0; y < h; ++y)
 1256    {
 1257       d = dst + (y * rowbytes);
 1258       for(x = 0; x < w; ++x)
 1259       {
 1260          code = ((unsigned int)bits) & 0x07;
 1261          if(code == 0)
 1262             d[0] = a0;
 1263          else if(code == 1)
 1264             d[0] = a1;
 1265          else if(a0 > a1)
 1266             d[0] = ((8 - code) * a0 + (code - 1) * a1) / 7;
 1267          else if(code >= 6)
 1268             d[0] = (code == 6) ? 0 : 255;
 1269          else
 1270             d[0] = ((6 - code) * a0 + (code - 1) * a1) / 5;
 1271          bits >>= 3;
 1272          d += bpp;
 1273       }
 1274       if(w < 4) bits >>= (3 * (4 - w));
 1275    }
 1276 }
 1277 
 1278 int dxt_decompress(unsigned char *dst, unsigned char *src, int format,
 1279                    unsigned int size, unsigned int width, unsigned int height,
 1280                    int bpp)
 1281 {
 1282    unsigned char *d, *s;
 1283    unsigned int x, y, sx, sy;
 1284 
 1285    if(!(IS_POT(width) && IS_POT(height)))
 1286       return(0);
 1287 
 1288    sx = (width  < 4) ? width  : 4;
 1289    sy = (height < 4) ? height : 4;
 1290 
 1291    s = src;
 1292 
 1293    for(y = 0; y < height; y += 4)
 1294    {
 1295       for(x = 0; x < width; x += 4)
 1296       {
 1297          d = dst + (y * width + x) * bpp;
 1298          if(format == DDS_COMPRESS_BC1)
 1299          {
 1300             decode_color_block(d, s, sx, sy, width * bpp, format);
 1301             s += 8;
 1302          }
 1303          else if(format == DDS_COMPRESS_BC2)
 1304          {
 1305             decode_alpha_block_DXT3(d + 3, s, sx, sy, width * bpp);
 1306             s += 8;
 1307             decode_color_block(d, s, sx, sy, width * bpp, format);
 1308             s += 8;
 1309          }
 1310          else if(format == DDS_COMPRESS_BC3)
 1311          {
 1312             decode_alpha_block_DXT5(d + 3, s, sx, sy, bpp, width * bpp);
 1313             s += 8;
 1314             decode_color_block(d, s, sx, sy, width * bpp, format);
 1315             s += 8;
 1316          }
 1317          else if(format == DDS_COMPRESS_BC4)
 1318          {
 1319             decode_alpha_block_DXT5(d, s, sx, sy, bpp, width * bpp);
 1320             s += 8;
 1321          }
 1322          else if(format == DDS_COMPRESS_BC5)
 1323          {
 1324             decode_alpha_block_DXT5(d, s + 8, sx, sy, bpp, width * bpp);
 1325             decode_alpha_block_DXT5(d + 1, s, sx, sy, bpp, width * bpp);
 1326             s += 16;
 1327          }
 1328       }
 1329    }
 1330 
 1331    return(1);
 1332 }

ViewVC Help
Powered by ViewVC 1.0.4