ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dxtn.c
Go to the documentation of this file.
00001 /*
00002  * DXTn codec
00003  * Version:  1.1
00004  *
00005  * Copyright (C) 2004  Daniel Borca   All Rights Reserved.
00006  *
00007  * this is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2, or (at your option)
00010  * any later version.
00011  *
00012  * this is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Make; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.    
00020  */
00021 
00022 
00023 #include <stdlib.h>
00024 #include <string.h>
00025 
00026 #include "types.h"
00027 #include "internal.h"
00028 #include "dxtn.h"
00029 
00030 
00031 /***************************************************************************\
00032  * DXTn encoder
00033  *
00034  * The encoder was built by reversing the decoder,
00035  * and is vaguely based on FXT1 codec. Note that this code
00036  * is merely a proof of concept, since it is highly UNoptimized!
00037 \***************************************************************************/
00038 
00039 
00040 #define MAX_COMP 4 /* ever needed maximum number of components in texel */
00041 #define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
00042 #define N_TEXELS 16 /* number of texels in a block (always 16) */
00043 #define COLOR565(v) (word)((((v)[RCOMP] & 0xf8) << 8) | (((v)[GCOMP] & 0xfc) << 3) | ((v)[BCOMP] >> 3))
00044 
00045 
00046 static const int dxtn_color_tlat[2][4] = {
00047     { 0, 2, 3, 1 },
00048     { 0, 2, 1, 3 }
00049 };
00050 
00051 static const int dxtn_alpha_tlat[2][8] = {
00052     { 0, 2, 3, 4, 5, 6, 7, 1 },
00053     { 0, 2, 3, 4, 5, 1, 6, 7 }
00054 };
00055 
00056 
00057 static void
00058 dxt1_rgb_quantize (dword *cc, const byte *lines[], int comps)
00059 {
00060     float b, iv[MAX_COMP];   /* interpolation vector */
00061 
00062     dword hi; /* high doubleword */
00063     int color0, color1;
00064     int n_vect;
00065     const int n_comp = 3;
00066     int black = 0;
00067 
00068     int minSum = 2000; /* big enough */
00069     int maxSum = -1; /* small enough */
00070     int minCol = 0; /* phoudoin: silent compiler! */
00071     int maxCol = 0; /* phoudoin: silent compiler! */
00072 
00073     byte input[N_TEXELS][MAX_COMP];
00074     int i, k, l;
00075 
00076     /* make the whole block opaque */
00077     /* we will NEVER reference ACOMP of any pixel */
00078 
00079     /* 4 texels each line */
00080     for (l = 0; l < 4; l++) {
00081     for (k = 0; k < 4; k++) {
00082         for (i = 0; i < comps; i++) {
00083         input[k + l * 4][i] = *lines[l]++;
00084         }
00085     }
00086     }
00087 
00088     /* Our solution here is to find the darkest and brightest colors in
00089      * the 4x4 tile and use those as the two representative colors.
00090      * There are probably better algorithms to use (histogram-based).
00091      */
00092     for (k = 0; k < N_TEXELS; k++) {
00093     int sum = 0;
00094     for (i = 0; i < n_comp; i++) {
00095         sum += input[k][i];
00096     }
00097     if (minSum > sum) {
00098         minSum = sum;
00099         minCol = k;
00100     }
00101     if (maxSum < sum) {
00102         maxSum = sum;
00103         maxCol = k;
00104     }
00105     if (sum == 0) {
00106         black = 1;
00107     }
00108     }
00109 
00110     color0 = COLOR565(input[minCol]);
00111     color1 = COLOR565(input[maxCol]);
00112 
00113     if (color0 == color1) {
00114     /* we'll use 3-vector */
00115     cc[0] = color0 | (color1 << 16);
00116     hi = black ? -1 : 0;
00117     } else {
00118     if (black && ((color0 == 0) || (color1 == 0))) {
00119         /* we still can use 4-vector */
00120         black = 0;
00121     }
00122 
00123     if (black ^ (color0 <= color1)) {
00124         int aux;
00125         aux = color0;
00126         color0 = color1;
00127         color1 = aux;
00128         aux = minCol;
00129         minCol = maxCol;
00130         maxCol = aux;
00131     }
00132     n_vect = (color0 <= color1) ? 2 : 3;
00133 
00134     MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
00135 
00136     /* add in texels */
00137     cc[0] = color0 | (color1 << 16);
00138     hi = 0;
00139     for (k = N_TEXELS - 1; k >= 0; k--) {
00140         int texel = 3;
00141         int sum = 0;
00142         if (black) {
00143         for (i = 0; i < n_comp; i++) {
00144             sum += input[k][i];
00145         }
00146         }
00147         if (!black || sum) {
00148         /* interpolate color */
00149         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
00150         texel = dxtn_color_tlat[black][texel];
00151         }
00152         /* add in texel */
00153         hi <<= 2;
00154         hi |= texel;
00155     }
00156     }
00157     cc[1] = hi;
00158 }
00159 
00160 
00161 static void
00162 dxt1_rgba_quantize (dword *cc, const byte *lines[], int comps)
00163 {
00164     float b, iv[MAX_COMP];  /* interpolation vector */
00165 
00166     dword hi;       /* high doubleword */
00167     int color0, color1;
00168     int n_vect;
00169     const int n_comp = 3;
00170     int transparent = 0;
00171 
00172     int minSum = 2000;      /* big enough */
00173     int maxSum = -1;        /* small enough */
00174     int minCol = 0;     /* phoudoin: silent compiler! */
00175     int maxCol = 0;     /* phoudoin: silent compiler! */
00176 
00177     byte input[N_TEXELS][MAX_COMP];
00178     int i, k, l;
00179 
00180     if (comps == 3) {
00181     /* make the whole block opaque */
00182     memset(input, -1, sizeof(input));
00183     }
00184 
00185     /* 4 texels each line */
00186     for (l = 0; l < 4; l++) {
00187     for (k = 0; k < 4; k++) {
00188         for (i = 0; i < comps; i++) {
00189         input[k + l * 4][i] = *lines[l]++;
00190         }
00191     }
00192     }
00193 
00194     /* Our solution here is to find the darkest and brightest colors in
00195      * the 4x4 tile and use those as the two representative colors.
00196      * There are probably better algorithms to use (histogram-based).
00197      */
00198     for (k = 0; k < N_TEXELS; k++) {
00199     int sum = 0;
00200     for (i = 0; i < n_comp; i++) {
00201         sum += input[k][i];
00202     }
00203     if (minSum > sum) {
00204         minSum = sum;
00205         minCol = k;
00206     }
00207     if (maxSum < sum) {
00208         maxSum = sum;
00209         maxCol = k;
00210     }
00211     if (input[k][ACOMP] < 128) {
00212         transparent = 1;
00213     }
00214     }
00215 
00216     color0 = COLOR565(input[minCol]);
00217     color1 = COLOR565(input[maxCol]);
00218 
00219     if (color0 == color1) {
00220     /* we'll use 3-vector */
00221     cc[0] = color0 | (color1 << 16);
00222     hi = transparent ? -1 : 0;
00223     } else {
00224     if (transparent ^ (color0 <= color1)) {
00225         int aux;
00226         aux = color0;
00227         color0 = color1;
00228         color1 = aux;
00229         aux = minCol;
00230         minCol = maxCol;
00231         maxCol = aux;
00232     }
00233     n_vect = (color0 <= color1) ? 2 : 3;
00234 
00235     MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
00236 
00237     /* add in texels */
00238     cc[0] = color0 | (color1 << 16);
00239     hi = 0;
00240     for (k = N_TEXELS - 1; k >= 0; k--) {
00241         int texel = 3;
00242         if (input[k][ACOMP] >= 128) {
00243         /* interpolate color */
00244         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
00245         texel = dxtn_color_tlat[transparent][texel];
00246         }
00247         /* add in texel */
00248         hi <<= 2;
00249         hi |= texel;
00250     }
00251     }
00252     cc[1] = hi;
00253 }
00254 
00255 
00256 static void
00257 dxt3_rgba_quantize (dword *cc, const byte *lines[], int comps)
00258 {
00259     float b, iv[MAX_COMP];  /* interpolation vector */
00260 
00261     dword lolo, lohi;   /* low quadword: lo dword, hi dword */
00262     dword hihi;     /* high quadword: high dword */
00263     int color0, color1;
00264     const int n_vect = 3;
00265     const int n_comp = 3;
00266 
00267     int minSum = 2000;      /* big enough */
00268     int maxSum = -1;        /* small enough */
00269     int minCol = 0;     /* phoudoin: silent compiler! */
00270     int maxCol = 0;     /* phoudoin: silent compiler! */
00271 
00272     byte input[N_TEXELS][MAX_COMP];
00273     int i, k, l;
00274 
00275     if (comps == 3) {
00276     /* make the whole block opaque */
00277     memset(input, -1, sizeof(input));
00278     }
00279 
00280     /* 4 texels each line */
00281     for (l = 0; l < 4; l++) {
00282     for (k = 0; k < 4; k++) {
00283         for (i = 0; i < comps; i++) {
00284         input[k + l * 4][i] = *lines[l]++;
00285         }
00286     }
00287     }
00288 
00289     /* Our solution here is to find the darkest and brightest colors in
00290      * the 4x4 tile and use those as the two representative colors.
00291      * There are probably better algorithms to use (histogram-based).
00292      */
00293     for (k = 0; k < N_TEXELS; k++) {
00294     int sum = 0;
00295     for (i = 0; i < n_comp; i++) {
00296         sum += input[k][i];
00297     }
00298     if (minSum > sum) {
00299         minSum = sum;
00300         minCol = k;
00301     }
00302     if (maxSum < sum) {
00303         maxSum = sum;
00304         maxCol = k;
00305     }
00306     }
00307 
00308     /* add in alphas */
00309     lolo = lohi = 0;
00310     for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
00311     /* add in alpha */
00312     lohi <<= 4;
00313     lohi |= input[k][ACOMP] >> 4;
00314     }
00315     cc[1] = lohi;
00316     for (; k >= 0; k--) {
00317     /* add in alpha */
00318     lolo <<= 4;
00319     lolo |= input[k][ACOMP] >> 4;
00320     }
00321     cc[0] = lolo;
00322 
00323     color0 = COLOR565(input[minCol]);
00324     color1 = COLOR565(input[maxCol]);
00325     cc[2] = color0 | (color1 << 16);
00326 
00327     hihi = 0;
00328     if (color0 != color1) {
00329     MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
00330 
00331     /* add in texels */
00332     for (k = N_TEXELS - 1; k >= 0; k--) {
00333         int texel;
00334         /* interpolate color */
00335         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
00336         texel = dxtn_color_tlat[0][texel];
00337         /* add in texel */
00338         hihi <<= 2;
00339         hihi |= texel;
00340     }
00341     }
00342     cc[3] = hihi;
00343 }
00344 
00345 
00346 static void
00347 dxt5_rgba_quantize (dword *cc, const byte *lines[], int comps)
00348 {
00349     float b, iv[MAX_COMP];  /* interpolation vector */
00350 
00351     qword lo;           /* low quadword */
00352     dword hihi;     /* high quadword: high dword */
00353     int color0, color1;
00354     const int n_vect = 3;
00355     const int n_comp = 3;
00356 
00357     int minSum = 2000;      /* big enough */
00358     int maxSum = -1;        /* small enough */
00359     int minCol = 0;     /* phoudoin: silent compiler! */
00360     int maxCol = 0;     /* phoudoin: silent compiler! */
00361     int alpha0 = 2000;      /* big enough */
00362     int alpha1 = -1;        /* small enough */
00363     int anyZero = 0, anyOne = 0;
00364     int a_vect;
00365 
00366     byte input[N_TEXELS][MAX_COMP];
00367     int i, k, l;
00368 
00369     if (comps == 3) {
00370     /* make the whole block opaque */
00371     memset(input, -1, sizeof(input));
00372     }
00373 
00374     /* 4 texels each line */
00375     for (l = 0; l < 4; l++) {
00376     for (k = 0; k < 4; k++) {
00377         for (i = 0; i < comps; i++) {
00378         input[k + l * 4][i] = *lines[l]++;
00379         }
00380     }
00381     }
00382 
00383     /* Our solution here is to find the darkest and brightest colors in
00384      * the 4x4 tile and use those as the two representative colors.
00385      * There are probably better algorithms to use (histogram-based).
00386      */
00387     for (k = 0; k < N_TEXELS; k++) {
00388     int sum = 0;
00389     for (i = 0; i < n_comp; i++) {
00390         sum += input[k][i];
00391     }
00392     if (minSum > sum) {
00393         minSum = sum;
00394         minCol = k;
00395     }
00396     if (maxSum < sum) {
00397         maxSum = sum;
00398         maxCol = k;
00399     }
00400     if (alpha0 > input[k][ACOMP]) {
00401         alpha0 = input[k][ACOMP];
00402     }
00403     if (alpha1 < input[k][ACOMP]) {
00404         alpha1 = input[k][ACOMP];
00405     }
00406     if (input[k][ACOMP] == 0) {
00407         anyZero = 1;
00408     }
00409     if (input[k][ACOMP] == 255) {
00410         anyOne = 1;
00411     }
00412     }
00413 
00414     /* add in alphas */
00415     if (alpha0 == alpha1) {
00416     /* we'll use 6-vector */
00417     cc[0] = alpha0 | (alpha1 << 8);
00418     cc[1] = 0;
00419     } else {
00420     if (anyZero && ((alpha0 == 0) || (alpha1 == 0))) {
00421         /* we still might use 8-vector */
00422         anyZero = 0;
00423     }
00424     if (anyOne && ((alpha0 == 255) || (alpha1 == 255))) {
00425         /* we still might use 8-vector */
00426         anyOne = 0;
00427     }
00428     if ((anyZero | anyOne) ^ (alpha0 <= alpha1)) {
00429         int aux;
00430         aux = alpha0;
00431         alpha0 = alpha1;
00432         alpha1 = aux;
00433     }
00434     a_vect = (alpha0 <= alpha1) ? 5 : 7;
00435 
00436     /* compute interpolation vector */
00437     iv[ACOMP] = (float)a_vect / (alpha1 - alpha0);
00438     b = -iv[ACOMP] * alpha0 + 0.5F;
00439 
00440     /* add in alphas */
00441     Q_MOV32(lo, 0);
00442     for (k = N_TEXELS - 1; k >= 0; k--) {
00443         int texel = -1;
00444         if (anyZero | anyOne) {
00445         if (input[k][ACOMP] == 0) {
00446             texel = 6;
00447         } else if (input[k][ACOMP] == 255) {
00448             texel = 7;
00449         }
00450         }
00451         /* interpolate alpha */
00452         if (texel == -1) {
00453         float dot = input[k][ACOMP] * iv[ACOMP];
00454         texel = (int)(dot + b);
00455 #if SAFECDOT
00456         if (texel < 0) {
00457             texel = 0;
00458         } else if (texel > a_vect) {
00459             texel = a_vect;
00460         }
00461 #endif
00462         texel = dxtn_alpha_tlat[anyZero | anyOne][texel];
00463         }
00464         /* add in texel */
00465         Q_SHL(lo, 3);
00466         Q_OR32(lo, texel);
00467     }
00468     Q_SHL(lo, 16);
00469     Q_OR32(lo, alpha0 | (alpha1 << 8));
00470     ((qword *)cc)[0] = lo;
00471     }
00472 
00473     color0 = COLOR565(input[minCol]);
00474     color1 = COLOR565(input[maxCol]);
00475     cc[2] = color0 | (color1 << 16);
00476 
00477     hihi = 0;
00478     if (color0 != color1) {
00479     MAKEIVEC(n_vect, n_comp, iv, b, input[minCol], input[maxCol]);
00480 
00481     /* add in texels */
00482     for (k = N_TEXELS - 1; k >= 0; k--) {
00483         int texel;
00484         /* interpolate color */
00485         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
00486         texel = dxtn_color_tlat[0][texel];
00487         /* add in texel */
00488         hihi <<= 2;
00489         hihi |= texel;
00490     }
00491     }
00492     cc[3] = hihi;
00493 }
00494 
00495 
00496 #define ENCODER(dxtn, n)                        \
00497 int TAPIENTRY                               \
00498 dxtn##_encode (int width, int height, int comps,            \
00499            const void *source, int srcRowStride,            \
00500            void *dest, int destRowStride)               \
00501 {                                   \
00502     int x, y;                               \
00503     const byte *data;                           \
00504     dword *encoded = (dword *)dest;                 \
00505     void *newSource = NULL;                     \
00506                                     \
00507     /* Replicate image if width is not M4 or height is not M4 */    \
00508     if ((width & 3) | (height & 3)) {                   \
00509     int newWidth = (width + 3) & ~3;                \
00510     int newHeight = (height + 3) & ~3;              \
00511     newSource = malloc(comps * newWidth * newHeight * sizeof(byte *));\
00512     _mesa_upscale_teximage2d(width, height, newWidth, newHeight,    \
00513                                comps, (const byte *)source,     \
00514                    srcRowStride, (byte *)newSource);    \
00515     source = newSource;                     \
00516     width = newWidth;                       \
00517     height = newHeight;                     \
00518     srcRowStride = comps * newWidth;                \
00519     }                                   \
00520                                     \
00521     data = (const byte *)source;                    \
00522     destRowStride = (destRowStride - width * n) / 4;            \
00523     for (y = 0; y < height; y += 4) {                   \
00524     unsigned int offs = 0 + (y + 0) * srcRowStride;         \
00525     for (x = 0; x < width; x += 4) {                \
00526         const byte *lines[4];                   \
00527         lines[0] = &data[offs];                 \
00528         lines[1] = lines[0] + srcRowStride;             \
00529         lines[2] = lines[1] + srcRowStride;             \
00530         lines[3] = lines[2] + srcRowStride;             \
00531         offs += 4 * comps;                      \
00532         dxtn##_quantize(encoded, lines, comps);         \
00533         /* 4x4 block */                     \
00534         encoded += n;                       \
00535     }                               \
00536     encoded += destRowStride;                   \
00537     }                                   \
00538                                     \
00539     if (newSource != NULL) {                        \
00540     free(newSource);                        \
00541     }                                   \
00542                                     \
00543     return 0;                               \
00544 }
00545 
00546 ENCODER(dxt1_rgb,  2)
00547 ENCODER(dxt1_rgba, 2)
00548 ENCODER(dxt3_rgba, 4)
00549 ENCODER(dxt5_rgba, 4)
00550 
00551 
00552 /***************************************************************************\
00553  * DXTn decoder
00554  *
00555  * The decoder is based on GL_EXT_texture_compression_s3tc
00556  * specification and serves as a concept for the encoder.
00557 \***************************************************************************/
00558 
00559 
00560 /* lookup table for scaling 4 bit colors up to 8 bits */
00561 static const byte _rgb_scale_4[] = {
00562     0,   17,  34,  51,  68,  85,  102, 119,
00563     136, 153, 170, 187, 204, 221, 238, 255
00564 };
00565 
00566 /* lookup table for scaling 5 bit colors up to 8 bits */
00567 static const byte _rgb_scale_5[] = {
00568     0,   8,   16,  25,  33,  41,  49,  58,
00569     66,  74,  82,  90,  99,  107, 115, 123,
00570     132, 140, 148, 156, 165, 173, 181, 189,
00571     197, 206, 214, 222, 230, 239, 247, 255
00572 };
00573 
00574 /* lookup table for scaling 6 bit colors up to 8 bits */
00575 static const byte _rgb_scale_6[] = {
00576     0,   4,   8,   12,  16,  20,  24,  28,
00577     32,  36,  40,  45,  49,  53,  57,  61,
00578     65,  69,  73,  77,  81,  85,  89,  93,
00579     97,  101, 105, 109, 113, 117, 121, 125,
00580     130, 134, 138, 142, 146, 150, 154, 158,
00581     162, 166, 170, 174, 178, 182, 186, 190,
00582     194, 198, 202, 206, 210, 215, 219, 223,
00583     227, 231, 235, 239, 243, 247, 251, 255
00584 };
00585 
00586 
00587 #define CC_SEL(cc, which) (((dword *)(cc))[(which) / 32] >> ((which) & 31))
00588 #define UP4(c) _rgb_scale_4[(c) & 15]
00589 #define UP5(c) _rgb_scale_5[(c) & 31]
00590 #define UP6(c) _rgb_scale_6[(c) & 63]
00591 #define ZERO_4UBV(v) *((dword *)(v)) = 0
00592 
00593 
00594 void TAPIENTRY
00595 dxt1_rgb_decode_1 (const void *texture, int stride,
00596            int i, int j, byte *rgba)
00597 {
00598     const byte *src = (const byte *)texture
00599                + ((j / 4) * ((stride + 3) / 4) + i / 4) * 8;
00600     const int code = (src[4 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
00601     if (code == 0) {
00602     rgba[RCOMP] = UP5(CC_SEL(src, 11));
00603     rgba[GCOMP] = UP6(CC_SEL(src,  5));
00604     rgba[BCOMP] = UP5(CC_SEL(src,  0));
00605     } else if (code == 1) {
00606     rgba[RCOMP] = UP5(CC_SEL(src, 27));
00607     rgba[GCOMP] = UP6(CC_SEL(src, 21));
00608     rgba[BCOMP] = UP5(CC_SEL(src, 16));
00609     } else {
00610     const word col0 = src[0] | (src[1] << 8);
00611     const word col1 = src[2] | (src[3] << 8);
00612     if (col0 > col1) {
00613         if (code == 2) {
00614         rgba[RCOMP] = (UP5(col0 >> 11) * 2 + UP5(col1 >> 11)) / 3;
00615         rgba[GCOMP] = (UP6(col0 >>  5) * 2 + UP6(col1 >>  5)) / 3;
00616         rgba[BCOMP] = (UP5(col0      ) * 2 + UP5(col1      )) / 3;
00617         } else {
00618         rgba[RCOMP] = (UP5(col0 >> 11) + 2 * UP5(col1 >> 11)) / 3;
00619         rgba[GCOMP] = (UP6(col0 >>  5) + 2 * UP6(col1 >>  5)) / 3;
00620         rgba[BCOMP] = (UP5(col0      ) + 2 * UP5(col1      )) / 3;
00621         }
00622     } else {
00623         if (code == 2) {
00624         rgba[RCOMP] = (UP5(col0 >> 11) + UP5(col1 >> 11)) / 2;
00625         rgba[GCOMP] = (UP6(col0 >>  5) + UP6(col1 >>  5)) / 2;
00626         rgba[BCOMP] = (UP5(col0      ) + UP5(col1      )) / 2;
00627         } else {
00628         ZERO_4UBV(rgba);
00629         }
00630     }
00631     }
00632     rgba[ACOMP] = 255;
00633 }
00634 
00635 
00636 void TAPIENTRY
00637 dxt1_rgba_decode_1 (const void *texture, int stride,
00638             int i, int j, byte *rgba)
00639 {
00640     /* Same as rgb_dxt1 above, except alpha=0 if col0<=col1 and code=3. */
00641     const byte *src = (const byte *)texture
00642                + ((j / 4) * ((stride + 3) / 4) + i / 4) * 8;
00643     const int code = (src[4 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
00644     if (code == 0) {
00645     rgba[RCOMP] = UP5(CC_SEL(src, 11));
00646     rgba[GCOMP] = UP6(CC_SEL(src,  5));
00647     rgba[BCOMP] = UP5(CC_SEL(src,  0));
00648     rgba[ACOMP] = 255;
00649     } else if (code == 1) {
00650     rgba[RCOMP] = UP5(CC_SEL(src, 27));
00651     rgba[GCOMP] = UP6(CC_SEL(src, 21));
00652     rgba[BCOMP] = UP5(CC_SEL(src, 16));
00653     rgba[ACOMP] = 255;
00654     } else {
00655     const word col0 = src[0] | (src[1] << 8);
00656     const word col1 = src[2] | (src[3] << 8);
00657     if (col0 > col1) {
00658         if (code == 2) {
00659         rgba[RCOMP] = (UP5(col0 >> 11) * 2 + UP5(col1 >> 11)) / 3;
00660         rgba[GCOMP] = (UP6(col0 >>  5) * 2 + UP6(col1 >>  5)) / 3;
00661         rgba[BCOMP] = (UP5(col0      ) * 2 + UP5(col1      )) / 3;
00662         } else {
00663         rgba[RCOMP] = (UP5(col0 >> 11) + 2 * UP5(col1 >> 11)) / 3;
00664         rgba[GCOMP] = (UP6(col0 >>  5) + 2 * UP6(col1 >>  5)) / 3;
00665         rgba[BCOMP] = (UP5(col0      ) + 2 * UP5(col1      )) / 3;
00666         }
00667         rgba[ACOMP] = 255;
00668     } else {
00669         if (code == 2) {
00670         rgba[RCOMP] = (UP5(col0 >> 11) + UP5(col1 >> 11)) / 2;
00671         rgba[GCOMP] = (UP6(col0 >>  5) + UP6(col1 >>  5)) / 2;
00672         rgba[BCOMP] = (UP5(col0      ) + UP5(col1      )) / 2;
00673         rgba[ACOMP] = 255;
00674         } else {
00675         ZERO_4UBV(rgba);
00676         }
00677     }
00678     }
00679 }
00680 
00681 
00682 void TAPIENTRY
00683 dxt3_rgba_decode_1 (const void *texture, int stride,
00684             int i, int j, byte *rgba)
00685 {
00686     const byte *src = (const byte *)texture
00687                + ((j / 4) * ((stride + 3) / 4) + i / 4) * 16;
00688     const int code = (src[12 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
00689     const dword *cc = (const dword *)(src + 8);
00690     if (code == 0) {
00691     rgba[RCOMP] = UP5(CC_SEL(cc, 11));
00692     rgba[GCOMP] = UP6(CC_SEL(cc,  5));
00693     rgba[BCOMP] = UP5(CC_SEL(cc,  0));
00694     } else if (code == 1) {
00695     rgba[RCOMP] = UP5(CC_SEL(cc, 27));
00696     rgba[GCOMP] = UP6(CC_SEL(cc, 21));
00697     rgba[BCOMP] = UP5(CC_SEL(cc, 16));
00698     } else if (code == 2) {
00699     /* (col0 * (4 - code) + col1 * (code - 1)) / 3 */
00700     rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) * 2 + UP5(CC_SEL(cc, 27))) / 3;
00701     rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) * 2 + UP6(CC_SEL(cc, 21))) / 3;
00702     rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) * 2 + UP5(CC_SEL(cc, 16))) / 3;
00703     } else {
00704     rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) + 2 * UP5(CC_SEL(cc, 27))) / 3;
00705     rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) + 2 * UP6(CC_SEL(cc, 21))) / 3;
00706     rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) + 2 * UP5(CC_SEL(cc, 16))) / 3;
00707     }
00708     rgba[ACOMP] = UP4(src[((j & 3) * 4 + (i & 3)) / 2] >> ((i & 1) * 4));
00709 }
00710 
00711 
00712 void TAPIENTRY
00713 dxt5_rgba_decode_1 (const void *texture, int stride,
00714             int i, int j, byte *rgba)
00715 {
00716     const byte *src = (const byte *)texture
00717                + ((j / 4) * ((stride + 3) / 4) + i / 4) * 16;
00718     const int code = (src[12 + (j & 3)] >> ((i & 3) * 2)) & 0x3;
00719     const dword *cc = (const dword *)(src + 8);
00720     const byte alpha0 = src[0];
00721     const byte alpha1 = src[1];
00722     const int alphaShift = (((j & 3) * 4) + (i & 3)) * 3 + 16;
00723     const int acode = ((alphaShift == 31)
00724             ? CC_SEL(src + 2, alphaShift - 16)
00725             : CC_SEL(src, alphaShift)) & 0x7;
00726     if (code == 0) {
00727     rgba[RCOMP] = UP5(CC_SEL(cc, 11));
00728     rgba[GCOMP] = UP6(CC_SEL(cc,  5));
00729     rgba[BCOMP] = UP5(CC_SEL(cc,  0));
00730     } else if (code == 1) {
00731     rgba[RCOMP] = UP5(CC_SEL(cc, 27));
00732     rgba[GCOMP] = UP6(CC_SEL(cc, 21));
00733     rgba[BCOMP] = UP5(CC_SEL(cc, 16));
00734     } else if (code == 2) {
00735     /* (col0 * (4 - code) + col1 * (code - 1)) / 3 */
00736     rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) * 2 + UP5(CC_SEL(cc, 27))) / 3;
00737     rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) * 2 + UP6(CC_SEL(cc, 21))) / 3;
00738     rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) * 2 + UP5(CC_SEL(cc, 16))) / 3;
00739     } else {
00740     rgba[RCOMP] = (UP5(CC_SEL(cc, 11)) + 2 * UP5(CC_SEL(cc, 27))) / 3;
00741     rgba[GCOMP] = (UP6(CC_SEL(cc,  5)) + 2 * UP6(CC_SEL(cc, 21))) / 3;
00742     rgba[BCOMP] = (UP5(CC_SEL(cc,  0)) + 2 * UP5(CC_SEL(cc, 16))) / 3;
00743     }
00744     if (acode == 0) {
00745     rgba[ACOMP] = alpha0;
00746     } else if (acode == 1) {
00747     rgba[ACOMP] = alpha1;
00748     } else if (alpha0 > alpha1) {
00749     rgba[ACOMP] = ((8 - acode) * alpha0 + (acode - 1) * alpha1) / 7;
00750     } else if (acode == 6) {
00751     rgba[ACOMP] = 0;
00752     } else if (acode == 7) {
00753     rgba[ACOMP] = 255;
00754     } else {
00755     rgba[ACOMP] = ((6 - acode) * alpha0 + (acode - 1) * alpha1) / 5;
00756     }
00757 }

Generated on Sat May 26 2012 04:18:08 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.