Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendxtn.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
1.7.6.1
|