Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfxt1.c
Go to the documentation of this file.
00001 /* 00002 * FXT1 codec 00003 * Version: 1.1 00004 * 00005 * Copyright (C) 2004 Daniel Borca All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * DANIEL BORCA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 00026 #include <stdlib.h> 00027 #include <string.h> 00028 00029 #include "types.h" 00030 #include "internal.h" 00031 #include "fxt1.h" 00032 00033 00034 /***************************************************************************\ 00035 * FXT1 encoder 00036 * 00037 * The encoder was built by reversing the decoder, 00038 * and is vaguely based on Texus2 by 3dfx. Note that this code 00039 * is merely a proof of concept, since it is highly UNoptimized; 00040 * moreover, it is sub-optimal due to initial conditions passed 00041 * to Lloyd's algorithm (the interpolation modes are even worse). 00042 \***************************************************************************/ 00043 00044 00045 #define MAX_COMP 4 /* ever needed maximum number of components in texel */ 00046 #define MAX_VECT 4 /* ever needed maximum number of base vectors to find */ 00047 #define N_TEXELS 32 /* number of texels in a block (always 32) */ 00048 #define LL_N_REP 50 /* number of iterations in lloyd's vq */ 00049 #define LL_RMS_D 10 /* fault tolerance (maximum delta) */ 00050 #define LL_RMS_E 255 /* fault tolerance (maximum error) */ 00051 #define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */ 00052 #define ISTBLACK(v) (*((dword *)(v)) == 0) 00053 #define COPY_4UBV(DST, SRC) *((dword *)(DST)) = *((dword *)(SRC)) 00054 00055 00056 static int 00057 fxt1_bestcol (float vec[][MAX_COMP], int nv, 00058 byte input[MAX_COMP], int nc) 00059 { 00060 int i, j, best = -1; 00061 float err = 1e9; /* big enough */ 00062 00063 for (j = 0; j < nv; j++) { 00064 float e = 0.0F; 00065 for (i = 0; i < nc; i++) { 00066 e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]); 00067 } 00068 if (e < err) { 00069 err = e; 00070 best = j; 00071 } 00072 } 00073 00074 return best; 00075 } 00076 00077 00078 static int 00079 fxt1_worst (float vec[MAX_COMP], 00080 byte input[N_TEXELS][MAX_COMP], int nc, int n) 00081 { 00082 int i, k, worst = -1; 00083 float err = -1.0F; /* small enough */ 00084 00085 for (k = 0; k < n; k++) { 00086 float e = 0.0F; 00087 for (i = 0; i < nc; i++) { 00088 e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]); 00089 } 00090 if (e > err) { 00091 err = e; 00092 worst = k; 00093 } 00094 } 00095 00096 return worst; 00097 } 00098 00099 00100 static int 00101 fxt1_variance (double variance[MAX_COMP], 00102 byte input[N_TEXELS][MAX_COMP], int nc, int n) 00103 { 00104 int i, k, best = 0; 00105 dword sx, sx2; 00106 double var, maxvar = -1; /* small enough */ 00107 double teenth = 1.0 / n; 00108 00109 for (i = 0; i < nc; i++) { 00110 sx = sx2 = 0; 00111 for (k = 0; k < n; k++) { 00112 int t = input[k][i]; 00113 sx += t; 00114 sx2 += t * t; 00115 } 00116 var = sx2 * teenth - sx * sx * teenth * teenth; 00117 if (maxvar < var) { 00118 maxvar = var; 00119 best = i; 00120 } 00121 if (variance) { 00122 variance[i] = var; 00123 } 00124 } 00125 00126 return best; 00127 } 00128 00129 00130 static int 00131 fxt1_choose (float vec[][MAX_COMP], int nv, 00132 byte input[N_TEXELS][MAX_COMP], int nc, int n) 00133 { 00134 #if 0 00135 /* Choose colors from a grid. 00136 */ 00137 int i, j; 00138 00139 for (j = 0; j < nv; j++) { 00140 int m = j * (n - 1) / (nv - 1); 00141 for (i = 0; i < nc; i++) { 00142 vec[j][i] = input[m][i]; 00143 } 00144 } 00145 #else 00146 /* Our solution here is to find the darkest and brightest colors in 00147 * the 8x4 tile and use those as the two representative colors. 00148 * There are probably better algorithms to use (histogram-based). 00149 */ 00150 int i, j, k; 00151 int minSum = 2000; /* big enough */ 00152 int maxSum = -1; /* small enough */ 00153 int minCol = 0; /* phoudoin: silent compiler! */ 00154 int maxCol = 0; /* phoudoin: silent compiler! */ 00155 00156 struct { 00157 int flag; 00158 dword key; 00159 int freq; 00160 int idx; 00161 } hist[N_TEXELS]; 00162 int lenh = 0; 00163 00164 memset(hist, 0, sizeof(hist)); 00165 00166 for (k = 0; k < n; k++) { 00167 int l; 00168 dword key = 0; 00169 int sum = 0; 00170 for (i = 0; i < nc; i++) { 00171 key <<= 8; 00172 key |= input[k][i]; 00173 sum += input[k][i]; 00174 } 00175 for (l = 0; l < n; l++) { 00176 if (!hist[l].flag) { 00177 /* alloc new slot */ 00178 hist[l].flag = !0; 00179 hist[l].key = key; 00180 hist[l].freq = 1; 00181 hist[l].idx = k; 00182 lenh = l + 1; 00183 break; 00184 } else if (hist[l].key == key) { 00185 hist[l].freq++; 00186 break; 00187 } 00188 } 00189 if (minSum > sum) { 00190 minSum = sum; 00191 minCol = k; 00192 } 00193 if (maxSum < sum) { 00194 maxSum = sum; 00195 maxCol = k; 00196 } 00197 } 00198 00199 if (lenh <= nv) { 00200 for (j = 0; j < lenh; j++) { 00201 for (i = 0; i < nc; i++) { 00202 vec[j][i] = (float)input[hist[j].idx][i]; 00203 } 00204 } 00205 for (; j < nv; j++) { 00206 for (i = 0; i < nc; i++) { 00207 vec[j][i] = vec[0][i]; 00208 } 00209 } 00210 return 0; 00211 } 00212 00213 for (j = 0; j < nv; j++) { 00214 for (i = 0; i < nc; i++) { 00215 vec[j][i] = ((nv - 1 - j) * input[minCol][i] + j * input[maxCol][i] + (nv - 1) / 2) / (float)(nv - 1); 00216 } 00217 } 00218 #endif 00219 00220 return !0; 00221 } 00222 00223 00224 static int 00225 fxt1_lloyd (float vec[][MAX_COMP], int nv, 00226 byte input[N_TEXELS][MAX_COMP], int nc, int n) 00227 { 00228 /* Use the generalized lloyd's algorithm for VQ: 00229 * find 4 color vectors. 00230 * 00231 * for each sample color 00232 * sort to nearest vector. 00233 * 00234 * replace each vector with the centroid of it's matching colors. 00235 * 00236 * repeat until RMS doesn't improve. 00237 * 00238 * if a color vector has no samples, or becomes the same as another 00239 * vector, replace it with the color which is farthest from a sample. 00240 * 00241 * vec[][MAX_COMP] initial vectors and resulting colors 00242 * nv number of resulting colors required 00243 * input[N_TEXELS][MAX_COMP] input texels 00244 * nc number of components in input / vec 00245 * n number of input samples 00246 */ 00247 00248 int sum[MAX_VECT][MAX_COMP]; /* used to accumulate closest texels */ 00249 int cnt[MAX_VECT]; /* how many times a certain vector was chosen */ 00250 float error, lasterror = 1e9; 00251 00252 int i, j, k, rep; 00253 00254 /* the quantizer */ 00255 for (rep = 0; rep < LL_N_REP; rep++) { 00256 /* reset sums & counters */ 00257 for (j = 0; j < nv; j++) { 00258 for (i = 0; i < nc; i++) { 00259 sum[j][i] = 0; 00260 } 00261 cnt[j] = 0; 00262 } 00263 error = 0; 00264 00265 /* scan whole block */ 00266 for (k = 0; k < n; k++) { 00267 #if 1 00268 int best = -1; 00269 float err = 1e9; /* big enough */ 00270 /* determine best vector */ 00271 for (j = 0; j < nv; j++) { 00272 float e = (vec[j][0] - input[k][0]) * (vec[j][0] - input[k][0]) + 00273 (vec[j][1] - input[k][1]) * (vec[j][1] - input[k][1]) + 00274 (vec[j][2] - input[k][2]) * (vec[j][2] - input[k][2]); 00275 if (nc == 4) { 00276 e += (vec[j][3] - input[k][3]) * (vec[j][3] - input[k][3]); 00277 } 00278 if (e < err) { 00279 err = e; 00280 best = j; 00281 } 00282 } 00283 #else 00284 int best = fxt1_bestcol(vec, nv, input[k], nc, &err); 00285 #endif 00286 /* add in closest color */ 00287 for (i = 0; i < nc; i++) { 00288 sum[best][i] += input[k][i]; 00289 } 00290 /* mark this vector as used */ 00291 cnt[best]++; 00292 /* accumulate error */ 00293 error += err; 00294 } 00295 00296 /* check RMS */ 00297 if ((error < LL_RMS_E) || 00298 ((error < lasterror) && ((lasterror - error) < LL_RMS_D))) { 00299 return !0; /* good match */ 00300 } 00301 lasterror = error; 00302 00303 /* move each vector to the barycenter of its closest colors */ 00304 for (j = 0; j < nv; j++) { 00305 if (cnt[j]) { 00306 float div = 1.0F / cnt[j]; 00307 for (i = 0; i < nc; i++) { 00308 vec[j][i] = div * sum[j][i]; 00309 } 00310 } else { 00311 /* this vec has no samples or is identical with a previous vec */ 00312 int worst = fxt1_worst(vec[j], input, nc, n); 00313 for (i = 0; i < nc; i++) { 00314 vec[j][i] = input[worst][i]; 00315 } 00316 } 00317 } 00318 } 00319 00320 return 0; /* could not converge fast enough */ 00321 } 00322 00323 00324 static void 00325 fxt1_quantize_CHROMA (dword *cc, 00326 byte input[N_TEXELS][MAX_COMP]) 00327 { 00328 const int n_vect = 4; /* 4 base vectors to find */ 00329 const int n_comp = 3; /* 3 components: R, G, B */ 00330 float vec[MAX_VECT][MAX_COMP]; 00331 int i, j, k; 00332 qword hi; /* high quadword */ 00333 dword lohi, lolo; /* low quadword: hi dword, lo dword */ 00334 00335 if (fxt1_choose(vec, n_vect, input, n_comp, N_TEXELS) != 0) { 00336 fxt1_lloyd(vec, n_vect, input, n_comp, N_TEXELS); 00337 } 00338 00339 Q_MOV32(hi, 4); /* cc-chroma = "010" + unused bit */ 00340 for (j = n_vect - 1; j >= 0; j--) { 00341 for (i = 0; i < n_comp; i++) { 00342 /* add in colors */ 00343 Q_SHL(hi, 5); 00344 Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); 00345 } 00346 } 00347 ((qword *)cc)[1] = hi; 00348 00349 lohi = lolo = 0; 00350 /* right microtile */ 00351 for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { 00352 lohi <<= 2; 00353 lohi |= fxt1_bestcol(vec, n_vect, input[k], n_comp); 00354 } 00355 /* left microtile */ 00356 for (; k >= 0; k--) { 00357 lolo <<= 2; 00358 lolo |= fxt1_bestcol(vec, n_vect, input[k], n_comp); 00359 } 00360 cc[1] = lohi; 00361 cc[0] = lolo; 00362 } 00363 00364 00365 static void 00366 fxt1_quantize_ALPHA0 (dword *cc, 00367 byte input[N_TEXELS][MAX_COMP], 00368 byte reord[N_TEXELS][MAX_COMP], int n) 00369 { 00370 const int n_vect = 3; /* 3 base vectors to find */ 00371 const int n_comp = 4; /* 4 components: R, G, B, A */ 00372 float vec[MAX_VECT][MAX_COMP]; 00373 int i, j, k; 00374 qword hi; /* high quadword */ 00375 dword lohi, lolo; /* low quadword: hi dword, lo dword */ 00376 00377 /* the last vector indicates zero */ 00378 for (i = 0; i < n_comp; i++) { 00379 vec[n_vect][i] = 0; 00380 } 00381 00382 /* the first n texels in reord are guaranteed to be non-zero */ 00383 if (fxt1_choose(vec, n_vect, reord, n_comp, n) != 0) { 00384 fxt1_lloyd(vec, n_vect, reord, n_comp, n); 00385 } 00386 00387 Q_MOV32(hi, 6); /* alpha = "011" + lerp = 0 */ 00388 for (j = n_vect - 1; j >= 0; j--) { 00389 /* add in alphas */ 00390 Q_SHL(hi, 5); 00391 Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F)); 00392 } 00393 for (j = n_vect - 1; j >= 0; j--) { 00394 for (i = 0; i < n_comp - 1; i++) { 00395 /* add in colors */ 00396 Q_SHL(hi, 5); 00397 Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); 00398 } 00399 } 00400 ((qword *)cc)[1] = hi; 00401 00402 lohi = lolo = 0; 00403 /* right microtile */ 00404 for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { 00405 lohi <<= 2; 00406 lohi |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp); 00407 } 00408 /* left microtile */ 00409 for (; k >= 0; k--) { 00410 lolo <<= 2; 00411 lolo |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp); 00412 } 00413 cc[1] = lohi; 00414 cc[0] = lolo; 00415 } 00416 00417 00418 static void 00419 fxt1_quantize_ALPHA1 (dword *cc, 00420 byte input[N_TEXELS][MAX_COMP]) 00421 { 00422 const int n_vect = 3; /* highest vector number in each microtile */ 00423 const int n_comp = 4; /* 4 components: R, G, B, A */ 00424 float vec[1 + 1 + 1][MAX_COMP]; /* 1.5 extrema for each sub-block */ 00425 float b, iv[MAX_COMP]; /* interpolation vector */ 00426 int i, j, k; 00427 qword hi; /* high quadword */ 00428 dword lohi, lolo; /* low quadword: hi dword, lo dword */ 00429 00430 int minSum; 00431 int maxSum; 00432 int minColL = 0, maxColL = 0; 00433 int minColR = 0, maxColR = 0; 00434 int sumL = 0, sumR = 0; 00435 00436 /* Our solution here is to find the darkest and brightest colors in 00437 * the 4x4 tile and use those as the two representative colors. 00438 * There are probably better algorithms to use (histogram-based). 00439 */ 00440 minSum = 2000; /* big enough */ 00441 maxSum = -1; /* small enough */ 00442 for (k = 0; k < N_TEXELS / 2; k++) { 00443 int sum = 0; 00444 for (i = 0; i < n_comp; i++) { 00445 sum += input[k][i]; 00446 } 00447 if (minSum > sum) { 00448 minSum = sum; 00449 minColL = k; 00450 } 00451 if (maxSum < sum) { 00452 maxSum = sum; 00453 maxColL = k; 00454 } 00455 sumL += sum; 00456 } 00457 minSum = 2000; /* big enough */ 00458 maxSum = -1; /* small enough */ 00459 for (; k < N_TEXELS; k++) { 00460 int sum = 0; 00461 for (i = 0; i < n_comp; i++) { 00462 sum += input[k][i]; 00463 } 00464 if (minSum > sum) { 00465 minSum = sum; 00466 minColR = k; 00467 } 00468 if (maxSum < sum) { 00469 maxSum = sum; 00470 maxColR = k; 00471 } 00472 sumR += sum; 00473 } 00474 00475 /* choose the common vector (yuck!) */ 00476 { 00477 int j1, j2; 00478 int v1 = 0, v2 = 0; 00479 float err = 1e9; /* big enough */ 00480 float tv[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ 00481 for (i = 0; i < n_comp; i++) { 00482 tv[0][i] = input[minColL][i]; 00483 tv[1][i] = input[maxColL][i]; 00484 tv[2][i] = input[minColR][i]; 00485 tv[3][i] = input[maxColR][i]; 00486 } 00487 for (j1 = 0; j1 < 2; j1++) { 00488 for (j2 = 2; j2 < 4; j2++) { 00489 float e = 0.0F; 00490 for (i = 0; i < n_comp; i++) { 00491 e += (tv[j1][i] - tv[j2][i]) * (tv[j1][i] - tv[j2][i]); 00492 } 00493 if (e < err) { 00494 err = e; 00495 v1 = j1; 00496 v2 = j2; 00497 } 00498 } 00499 } 00500 for (i = 0; i < n_comp; i++) { 00501 vec[0][i] = tv[1 - v1][i]; 00502 vec[1][i] = (tv[v1][i] * sumL + tv[v2][i] * sumR) / (sumL + sumR); 00503 vec[2][i] = tv[5 - v2][i]; 00504 } 00505 } 00506 00507 /* left microtile */ 00508 cc[0] = 0; 00509 if (minColL != maxColL) { 00510 /* compute interpolation vector */ 00511 MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); 00512 00513 /* add in texels */ 00514 lolo = 0; 00515 for (k = N_TEXELS / 2 - 1; k >= 0; k--) { 00516 int texel; 00517 /* interpolate color */ 00518 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00519 /* add in texel */ 00520 lolo <<= 2; 00521 lolo |= texel; 00522 } 00523 00524 cc[0] = lolo; 00525 } 00526 00527 /* right microtile */ 00528 cc[1] = 0; 00529 if (minColR != maxColR) { 00530 /* compute interpolation vector */ 00531 MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]); 00532 00533 /* add in texels */ 00534 lohi = 0; 00535 for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { 00536 int texel; 00537 /* interpolate color */ 00538 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00539 /* add in texel */ 00540 lohi <<= 2; 00541 lohi |= texel; 00542 } 00543 00544 cc[1] = lohi; 00545 } 00546 00547 Q_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */ 00548 for (j = n_vect - 1; j >= 0; j--) { 00549 /* add in alphas */ 00550 Q_SHL(hi, 5); 00551 Q_OR32(hi, (dword)(vec[j][ACOMP] / 8.0F)); 00552 } 00553 for (j = n_vect - 1; j >= 0; j--) { 00554 for (i = 0; i < n_comp - 1; i++) { 00555 /* add in colors */ 00556 Q_SHL(hi, 5); 00557 Q_OR32(hi, (dword)(vec[j][i] / 8.0F)); 00558 } 00559 } 00560 ((qword *)cc)[1] = hi; 00561 } 00562 00563 00564 static void 00565 fxt1_quantize_HI (dword *cc, 00566 byte input[N_TEXELS][MAX_COMP], 00567 byte reord[N_TEXELS][MAX_COMP], int n) 00568 { 00569 const int n_vect = 6; /* highest vector number */ 00570 const int n_comp = 3; /* 3 components: R, G, B */ 00571 float b = 0.0F; /* phoudoin: silent compiler! */ 00572 float iv[MAX_COMP]; /* interpolation vector */ 00573 int i, k; 00574 dword hihi; /* high quadword: hi dword */ 00575 00576 int minSum = 2000; /* big enough */ 00577 int maxSum = -1; /* small enough */ 00578 int minCol = 0; /* phoudoin: silent compiler! */ 00579 int maxCol = 0; /* phoudoin: silent compiler! */ 00580 00581 /* Our solution here is to find the darkest and brightest colors in 00582 * the 8x4 tile and use those as the two representative colors. 00583 * There are probably better algorithms to use (histogram-based). 00584 */ 00585 for (k = 0; k < n; k++) { 00586 int sum = 0; 00587 for (i = 0; i < n_comp; i++) { 00588 sum += reord[k][i]; 00589 } 00590 if (minSum > sum) { 00591 minSum = sum; 00592 minCol = k; 00593 } 00594 if (maxSum < sum) { 00595 maxSum = sum; 00596 maxCol = k; 00597 } 00598 } 00599 00600 hihi = 0; /* cc-hi = "00" */ 00601 for (i = 0; i < n_comp; i++) { 00602 /* add in colors */ 00603 hihi <<= 5; 00604 hihi |= reord[maxCol][i] >> 3; 00605 } 00606 for (i = 0; i < n_comp; i++) { 00607 /* add in colors */ 00608 hihi <<= 5; 00609 hihi |= reord[minCol][i] >> 3; 00610 } 00611 cc[3] = hihi; 00612 cc[0] = cc[1] = cc[2] = 0; 00613 00614 /* compute interpolation vector */ 00615 if (minCol != maxCol) { 00616 MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]); 00617 } 00618 00619 /* add in texels */ 00620 for (k = N_TEXELS - 1; k >= 0; k--) { 00621 int t = k * 3; 00622 dword *kk = (dword *)((byte *)cc + t / 8); 00623 int texel = n_vect + 1; /* transparent black */ 00624 00625 if (!ISTBLACK(input[k])) { 00626 if (minCol != maxCol) { 00627 /* interpolate color */ 00628 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00629 /* add in texel */ 00630 kk[0] |= texel << (t & 7); 00631 } 00632 } else { 00633 /* add in texel */ 00634 kk[0] |= texel << (t & 7); 00635 } 00636 } 00637 } 00638 00639 00640 static void 00641 fxt1_quantize_MIXED1 (dword *cc, 00642 byte input[N_TEXELS][MAX_COMP]) 00643 { 00644 const int n_vect = 2; /* highest vector number in each microtile */ 00645 const int n_comp = 3; /* 3 components: R, G, B */ 00646 byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ 00647 float b, iv[MAX_COMP]; /* interpolation vector */ 00648 int i, j, k; 00649 qword hi; /* high quadword */ 00650 dword lohi, lolo; /* low quadword: hi dword, lo dword */ 00651 00652 int minSum; 00653 int maxSum; 00654 int minColL = 0, maxColL = -1; 00655 int minColR = 0, maxColR = -1; 00656 00657 /* Our solution here is to find the darkest and brightest colors in 00658 * the 4x4 tile and use those as the two representative colors. 00659 * There are probably better algorithms to use (histogram-based). 00660 */ 00661 minSum = 2000; /* big enough */ 00662 maxSum = -1; /* small enough */ 00663 for (k = 0; k < N_TEXELS / 2; k++) { 00664 if (!ISTBLACK(input[k])) { 00665 int sum = 0; 00666 for (i = 0; i < n_comp; i++) { 00667 sum += input[k][i]; 00668 } 00669 if (minSum > sum) { 00670 minSum = sum; 00671 minColL = k; 00672 } 00673 if (maxSum < sum) { 00674 maxSum = sum; 00675 maxColL = k; 00676 } 00677 } 00678 } 00679 minSum = 2000; /* big enough */ 00680 maxSum = -1; /* small enough */ 00681 for (; k < N_TEXELS; k++) { 00682 if (!ISTBLACK(input[k])) { 00683 int sum = 0; 00684 for (i = 0; i < n_comp; i++) { 00685 sum += input[k][i]; 00686 } 00687 if (minSum > sum) { 00688 minSum = sum; 00689 minColR = k; 00690 } 00691 if (maxSum < sum) { 00692 maxSum = sum; 00693 maxColR = k; 00694 } 00695 } 00696 } 00697 00698 /* left microtile */ 00699 if (maxColL == -1) { 00700 /* all transparent black */ 00701 cc[0] = ~0UL; 00702 for (i = 0; i < n_comp; i++) { 00703 vec[0][i] = 0; 00704 vec[1][i] = 0; 00705 } 00706 } else { 00707 cc[0] = 0; 00708 for (i = 0; i < n_comp; i++) { 00709 vec[0][i] = input[minColL][i]; 00710 vec[1][i] = input[maxColL][i]; 00711 } 00712 if (minColL != maxColL) { 00713 /* compute interpolation vector */ 00714 MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); 00715 00716 /* add in texels */ 00717 lolo = 0; 00718 for (k = N_TEXELS / 2 - 1; k >= 0; k--) { 00719 int texel = n_vect + 1; /* transparent black */ 00720 if (!ISTBLACK(input[k])) { 00721 /* interpolate color */ 00722 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00723 } 00724 /* add in texel */ 00725 lolo <<= 2; 00726 lolo |= texel; 00727 } 00728 cc[0] = lolo; 00729 } 00730 } 00731 00732 /* right microtile */ 00733 if (maxColR == -1) { 00734 /* all transparent black */ 00735 cc[1] = ~0UL; 00736 for (i = 0; i < n_comp; i++) { 00737 vec[2][i] = 0; 00738 vec[3][i] = 0; 00739 } 00740 } else { 00741 cc[1] = 0; 00742 for (i = 0; i < n_comp; i++) { 00743 vec[2][i] = input[minColR][i]; 00744 vec[3][i] = input[maxColR][i]; 00745 } 00746 if (minColR != maxColR) { 00747 /* compute interpolation vector */ 00748 MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]); 00749 00750 /* add in texels */ 00751 lohi = 0; 00752 for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { 00753 int texel = n_vect + 1; /* transparent black */ 00754 if (!ISTBLACK(input[k])) { 00755 /* interpolate color */ 00756 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00757 } 00758 /* add in texel */ 00759 lohi <<= 2; 00760 lohi |= texel; 00761 } 00762 cc[1] = lohi; 00763 } 00764 } 00765 00766 Q_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */ 00767 for (j = 2 * 2 - 1; j >= 0; j--) { 00768 for (i = 0; i < n_comp; i++) { 00769 /* add in colors */ 00770 Q_SHL(hi, 5); 00771 Q_OR32(hi, vec[j][i] >> 3); 00772 } 00773 } 00774 ((qword *)cc)[1] = hi; 00775 } 00776 00777 00778 static void 00779 fxt1_quantize_MIXED0 (dword *cc, 00780 byte input[N_TEXELS][MAX_COMP]) 00781 { 00782 const int n_vect = 3; /* highest vector number in each microtile */ 00783 const int n_comp = 3; /* 3 components: R, G, B */ 00784 byte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */ 00785 float b, iv[MAX_COMP]; /* interpolation vector */ 00786 int i, j, k; 00787 qword hi; /* high quadword */ 00788 dword lohi, lolo; /* low quadword: hi dword, lo dword */ 00789 00790 int minColL = 0, maxColL = 0; 00791 int minColR = 0, maxColR = 0; 00792 #if 0 00793 int minSum; 00794 int maxSum; 00795 00796 /* Our solution here is to find the darkest and brightest colors in 00797 * the 4x4 tile and use those as the two representative colors. 00798 * There are probably better algorithms to use (histogram-based). 00799 */ 00800 minSum = 2000; /* big enough */ 00801 maxSum = -1; /* small enough */ 00802 for (k = 0; k < N_TEXELS / 2; k++) { 00803 int sum = 0; 00804 for (i = 0; i < n_comp; i++) { 00805 sum += input[k][i]; 00806 } 00807 if (minSum > sum) { 00808 minSum = sum; 00809 minColL = k; 00810 } 00811 if (maxSum < sum) { 00812 maxSum = sum; 00813 maxColL = k; 00814 } 00815 } 00816 minSum = 2000; /* big enough */ 00817 maxSum = -1; /* small enough */ 00818 for (; k < N_TEXELS; k++) { 00819 int sum = 0; 00820 for (i = 0; i < n_comp; i++) { 00821 sum += input[k][i]; 00822 } 00823 if (minSum > sum) { 00824 minSum = sum; 00825 minColR = k; 00826 } 00827 if (maxSum < sum) { 00828 maxSum = sum; 00829 maxColR = k; 00830 } 00831 } 00832 #else 00833 int minVal; 00834 int maxVal; 00835 int maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2); 00836 int maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2); 00837 00838 /* Scan the channel with max variance for lo & hi 00839 * and use those as the two representative colors. 00840 */ 00841 minVal = 2000; /* big enough */ 00842 maxVal = -1; /* small enough */ 00843 for (k = 0; k < N_TEXELS / 2; k++) { 00844 int t = input[k][maxVarL]; 00845 if (minVal > t) { 00846 minVal = t; 00847 minColL = k; 00848 } 00849 if (maxVal < t) { 00850 maxVal = t; 00851 maxColL = k; 00852 } 00853 } 00854 minVal = 2000; /* big enough */ 00855 maxVal = -1; /* small enough */ 00856 for (; k < N_TEXELS; k++) { 00857 int t = input[k][maxVarR]; 00858 if (minVal > t) { 00859 minVal = t; 00860 minColR = k; 00861 } 00862 if (maxVal < t) { 00863 maxVal = t; 00864 maxColR = k; 00865 } 00866 } 00867 #endif 00868 00869 /* left microtile */ 00870 cc[0] = 0; 00871 for (i = 0; i < n_comp; i++) { 00872 vec[0][i] = input[minColL][i]; 00873 vec[1][i] = input[maxColL][i]; 00874 } 00875 if (minColL != maxColL) { 00876 /* compute interpolation vector */ 00877 MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]); 00878 00879 /* add in texels */ 00880 lolo = 0; 00881 for (k = N_TEXELS / 2 - 1; k >= 0; k--) { 00882 int texel; 00883 /* interpolate color */ 00884 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00885 /* add in texel */ 00886 lolo <<= 2; 00887 lolo |= texel; 00888 } 00889 00890 /* funky encoding for LSB of green */ 00891 if ((int)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) { 00892 for (i = 0; i < n_comp; i++) { 00893 vec[1][i] = input[minColL][i]; 00894 vec[0][i] = input[maxColL][i]; 00895 } 00896 lolo = ~lolo; 00897 } 00898 00899 cc[0] = lolo; 00900 } 00901 00902 /* right microtile */ 00903 cc[1] = 0; 00904 for (i = 0; i < n_comp; i++) { 00905 vec[2][i] = input[minColR][i]; 00906 vec[3][i] = input[maxColR][i]; 00907 } 00908 if (minColR != maxColR) { 00909 /* compute interpolation vector */ 00910 MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]); 00911 00912 /* add in texels */ 00913 lohi = 0; 00914 for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) { 00915 int texel; 00916 /* interpolate color */ 00917 CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]); 00918 /* add in texel */ 00919 lohi <<= 2; 00920 lohi |= texel; 00921 } 00922 00923 /* funky encoding for LSB of green */ 00924 if ((int)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) { 00925 for (i = 0; i < n_comp; i++) { 00926 vec[3][i] = input[minColR][i]; 00927 vec[2][i] = input[maxColR][i]; 00928 } 00929 lohi = ~lohi; 00930 } 00931 00932 cc[1] = lohi; 00933 } 00934 00935 Q_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */ 00936 for (j = 2 * 2 - 1; j >= 0; j--) { 00937 for (i = 0; i < n_comp; i++) { 00938 /* add in colors */ 00939 Q_SHL(hi, 5); 00940 Q_OR32(hi, vec[j][i] >> 3); 00941 } 00942 } 00943 ((qword *)cc)[1] = hi; 00944 } 00945 00946 00947 static void 00948 fxt1_quantize (dword *cc, const byte *lines[], int comps) 00949 { 00950 int trualpha; 00951 byte reord[N_TEXELS][MAX_COMP]; 00952 00953 byte input[N_TEXELS][MAX_COMP]; 00954 int i, k, l; 00955 00956 if (comps == 3) { 00957 /* make the whole block opaque */ 00958 memset(input, -1, sizeof(input)); 00959 } 00960 00961 /* 8 texels each line */ 00962 for (l = 0; l < 4; l++) { 00963 for (k = 0; k < 4; k++) { 00964 for (i = 0; i < comps; i++) { 00965 input[k + l * 4][i] = *lines[l]++; 00966 } 00967 } 00968 for (; k < 8; k++) { 00969 for (i = 0; i < comps; i++) { 00970 input[k + l * 4 + 12][i] = *lines[l]++; 00971 } 00972 } 00973 } 00974 00975 /* block layout: 00976 * 00, 01, 02, 03, 08, 09, 0a, 0b 00977 * 10, 11, 12, 13, 18, 19, 1a, 1b 00978 * 04, 05, 06, 07, 0c, 0d, 0e, 0f 00979 * 14, 15, 16, 17, 1c, 1d, 1e, 1f 00980 */ 00981 00982 /* [dBorca] 00983 * stupidity flows forth from this 00984 */ 00985 l = N_TEXELS; 00986 trualpha = 0; 00987 if (comps == 4) { 00988 /* skip all transparent black texels */ 00989 l = 0; 00990 for (k = 0; k < N_TEXELS; k++) { 00991 /* test all components against 0 */ 00992 if (!ISTBLACK(input[k])) { 00993 /* texel is not transparent black */ 00994 COPY_4UBV(reord[l], input[k]); 00995 if (reord[l][ACOMP] < (255 - ALPHA_TS)) { 00996 /* non-opaque texel */ 00997 trualpha = !0; 00998 } 00999 l++; 01000 } 01001 } 01002 } 01003 01004 #if 0 01005 if (trualpha) { 01006 fxt1_quantize_ALPHA0(cc, input, reord, l); 01007 } else if (l == 0) { 01008 cc[0] = cc[1] = cc[2] = -1; 01009 cc[3] = 0; 01010 } else if (l < N_TEXELS) { 01011 fxt1_quantize_HI(cc, input, reord, l); 01012 } else { 01013 fxt1_quantize_CHROMA(cc, input); 01014 } 01015 (void)fxt1_quantize_ALPHA1; 01016 (void)fxt1_quantize_MIXED1; 01017 (void)fxt1_quantize_MIXED0; 01018 #else 01019 if (trualpha) { 01020 fxt1_quantize_ALPHA1(cc, input); 01021 } else if (l == 0) { 01022 cc[0] = cc[1] = cc[2] = ~0UL; 01023 cc[3] = 0; 01024 } else if (l < N_TEXELS) { 01025 fxt1_quantize_MIXED1(cc, input); 01026 } else { 01027 fxt1_quantize_MIXED0(cc, input); 01028 } 01029 (void)fxt1_quantize_ALPHA0; 01030 (void)fxt1_quantize_HI; 01031 (void)fxt1_quantize_CHROMA; 01032 #endif 01033 } 01034 01035 01036 TAPI int TAPIENTRY 01037 fxt1_encode (int width, int height, int comps, 01038 const void *source, int srcRowStride, 01039 void *dest, int destRowStride) 01040 { 01041 int x, y; 01042 const byte *data; 01043 dword *encoded = (dword *)dest; 01044 void *newSource = NULL; 01045 01046 /* Replicate image if width is not M8 or height is not M4 */ 01047 if ((width & 7) | (height & 3)) { 01048 int newWidth = (width + 7) & ~7; 01049 int newHeight = (height + 3) & ~3; 01050 newSource = malloc(comps * newWidth * newHeight * sizeof(byte *)); 01051 _mesa_upscale_teximage2d(width, height, newWidth, newHeight, 01052 comps, (const byte *)source, 01053 srcRowStride, (byte *)newSource); 01054 source = newSource; 01055 width = newWidth; 01056 height = newHeight; 01057 srcRowStride = comps * newWidth; 01058 } 01059 01060 data = (const byte *)source; 01061 destRowStride = (destRowStride - width * 2) / 4; 01062 for (y = 0; y < height; y += 4) { 01063 unsigned int offs = 0 + (y + 0) * srcRowStride; 01064 for (x = 0; x < width; x += 8) { 01065 const byte *lines[4]; 01066 lines[0] = &data[offs]; 01067 lines[1] = lines[0] + srcRowStride; 01068 lines[2] = lines[1] + srcRowStride; 01069 lines[3] = lines[2] + srcRowStride; 01070 offs += 8 * comps; 01071 fxt1_quantize(encoded, lines, comps); 01072 /* 128 bits per 8x4 block */ 01073 encoded += 4; 01074 } 01075 encoded += destRowStride; 01076 } 01077 01078 if (newSource != NULL) { 01079 free(newSource); 01080 } 01081 01082 return 0; 01083 } 01084 01085 01086 /***************************************************************************\ 01087 * FXT1 decoder 01088 * 01089 * The decoder is based on GL_3DFX_texture_compression_FXT1 01090 * specification and serves as a concept for the encoder. 01091 \***************************************************************************/ 01092 01093 01094 /* lookup table for scaling 5 bit colors up to 8 bits */ 01095 static const byte _rgb_scale_5[] = { 01096 0, 8, 16, 25, 33, 41, 49, 58, 01097 66, 74, 82, 90, 99, 107, 115, 123, 01098 132, 140, 148, 156, 165, 173, 181, 189, 01099 197, 206, 214, 222, 230, 239, 247, 255 01100 }; 01101 01102 /* lookup table for scaling 6 bit colors up to 8 bits */ 01103 static const byte _rgb_scale_6[] = { 01104 0, 4, 8, 12, 16, 20, 24, 28, 01105 32, 36, 40, 45, 49, 53, 57, 61, 01106 65, 69, 73, 77, 81, 85, 89, 93, 01107 97, 101, 105, 109, 113, 117, 121, 125, 01108 130, 134, 138, 142, 146, 150, 154, 158, 01109 162, 166, 170, 174, 178, 182, 186, 190, 01110 194, 198, 202, 206, 210, 215, 219, 223, 01111 227, 231, 235, 239, 243, 247, 251, 255 01112 }; 01113 01114 01115 #define CC_SEL(cc, which) (((dword *)(cc))[(which) / 32] >> ((which) & 31)) 01116 #define UP5(c) _rgb_scale_5[(c) & 31] 01117 #define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)] 01118 #define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n) 01119 #define ZERO_4UBV(v) *((dword *)(v)) = 0 01120 01121 01122 static void 01123 fxt1_decode_1HI (const byte *code, int t, byte *rgba) 01124 { 01125 const dword *cc; 01126 01127 t *= 3; 01128 cc = (const dword *)(code + t / 8); 01129 t = (cc[0] >> (t & 7)) & 7; 01130 01131 if (t == 7) { 01132 ZERO_4UBV(rgba); 01133 } else { 01134 cc = (const dword *)(code + 12); 01135 if (t == 0) { 01136 rgba[BCOMP] = UP5(CC_SEL(cc, 0)); 01137 rgba[GCOMP] = UP5(CC_SEL(cc, 5)); 01138 rgba[RCOMP] = UP5(CC_SEL(cc, 10)); 01139 } else if (t == 6) { 01140 rgba[BCOMP] = UP5(CC_SEL(cc, 15)); 01141 rgba[GCOMP] = UP5(CC_SEL(cc, 20)); 01142 rgba[RCOMP] = UP5(CC_SEL(cc, 25)); 01143 } else { 01144 rgba[BCOMP] = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15))); 01145 rgba[GCOMP] = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20))); 01146 rgba[RCOMP] = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25))); 01147 } 01148 rgba[ACOMP] = 255; 01149 } 01150 } 01151 01152 01153 static void 01154 fxt1_decode_1CHROMA (const byte *code, int t, byte *rgba) 01155 { 01156 const dword *cc; 01157 dword kk; 01158 01159 cc = (const dword *)code; 01160 if (t & 16) { 01161 cc++; 01162 t &= 15; 01163 } 01164 t = (cc[0] >> (t * 2)) & 3; 01165 01166 t *= 15; 01167 cc = (const dword *)(code + 8 + t / 8); 01168 kk = cc[0] >> (t & 7); 01169 rgba[BCOMP] = UP5(kk); 01170 rgba[GCOMP] = UP5(kk >> 5); 01171 rgba[RCOMP] = UP5(kk >> 10); 01172 rgba[ACOMP] = 255; 01173 } 01174 01175 01176 static void 01177 fxt1_decode_1MIXED (const byte *code, int t, byte *rgba) 01178 { 01179 const dword *cc; 01180 int col[2][3]; 01181 int glsb, selb; 01182 01183 cc = (const dword *)code; 01184 if (t & 16) { 01185 t &= 15; 01186 t = (cc[1] >> (t * 2)) & 3; 01187 /* col 2 */ 01188 col[0][BCOMP] = (*(const dword *)(code + 11)) >> 6; 01189 col[0][GCOMP] = CC_SEL(cc, 99); 01190 col[0][RCOMP] = CC_SEL(cc, 104); 01191 /* col 3 */ 01192 col[1][BCOMP] = CC_SEL(cc, 109); 01193 col[1][GCOMP] = CC_SEL(cc, 114); 01194 col[1][RCOMP] = CC_SEL(cc, 119); 01195 glsb = CC_SEL(cc, 126); 01196 selb = CC_SEL(cc, 33); 01197 } else { 01198 t = (cc[0] >> (t * 2)) & 3; 01199 /* col 0 */ 01200 col[0][BCOMP] = CC_SEL(cc, 64); 01201 col[0][GCOMP] = CC_SEL(cc, 69); 01202 col[0][RCOMP] = CC_SEL(cc, 74); 01203 /* col 1 */ 01204 col[1][BCOMP] = CC_SEL(cc, 79); 01205 col[1][GCOMP] = CC_SEL(cc, 84); 01206 col[1][RCOMP] = CC_SEL(cc, 89); 01207 glsb = CC_SEL(cc, 125); 01208 selb = CC_SEL(cc, 1); 01209 } 01210 01211 if (CC_SEL(cc, 124) & 1) { 01212 /* alpha[0] == 1 */ 01213 01214 if (t == 3) { 01215 ZERO_4UBV(rgba); 01216 } else { 01217 if (t == 0) { 01218 rgba[BCOMP] = UP5(col[0][BCOMP]); 01219 rgba[GCOMP] = UP5(col[0][GCOMP]); 01220 rgba[RCOMP] = UP5(col[0][RCOMP]); 01221 } else if (t == 2) { 01222 rgba[BCOMP] = UP5(col[1][BCOMP]); 01223 rgba[GCOMP] = UP6(col[1][GCOMP], glsb); 01224 rgba[RCOMP] = UP5(col[1][RCOMP]); 01225 } else { 01226 rgba[BCOMP] = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2; 01227 rgba[GCOMP] = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2; 01228 rgba[RCOMP] = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2; 01229 } 01230 rgba[ACOMP] = 255; 01231 } 01232 } else { 01233 /* alpha[0] == 0 */ 01234 01235 if (t == 0) { 01236 rgba[BCOMP] = UP5(col[0][BCOMP]); 01237 rgba[GCOMP] = UP6(col[0][GCOMP], glsb ^ selb); 01238 rgba[RCOMP] = UP5(col[0][RCOMP]); 01239 } else if (t == 3) { 01240 rgba[BCOMP] = UP5(col[1][BCOMP]); 01241 rgba[GCOMP] = UP6(col[1][GCOMP], glsb); 01242 rgba[RCOMP] = UP5(col[1][RCOMP]); 01243 } else { 01244 rgba[BCOMP] = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP])); 01245 rgba[GCOMP] = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb), 01246 UP6(col[1][GCOMP], glsb)); 01247 rgba[RCOMP] = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP])); 01248 } 01249 rgba[ACOMP] = 255; 01250 } 01251 } 01252 01253 01254 static void 01255 fxt1_decode_1ALPHA (const byte *code, int t, byte *rgba) 01256 { 01257 const dword *cc; 01258 01259 cc = (const dword *)code; 01260 if (CC_SEL(cc, 124) & 1) { 01261 /* lerp == 1 */ 01262 int col0[4]; 01263 01264 if (t & 16) { 01265 t &= 15; 01266 t = (cc[1] >> (t * 2)) & 3; 01267 /* col 2 */ 01268 col0[BCOMP] = (*(const dword *)(code + 11)) >> 6; 01269 col0[GCOMP] = CC_SEL(cc, 99); 01270 col0[RCOMP] = CC_SEL(cc, 104); 01271 col0[ACOMP] = CC_SEL(cc, 119); 01272 } else { 01273 t = (cc[0] >> (t * 2)) & 3; 01274 /* col 0 */ 01275 col0[BCOMP] = CC_SEL(cc, 64); 01276 col0[GCOMP] = CC_SEL(cc, 69); 01277 col0[RCOMP] = CC_SEL(cc, 74); 01278 col0[ACOMP] = CC_SEL(cc, 109); 01279 } 01280 01281 if (t == 0) { 01282 rgba[BCOMP] = UP5(col0[BCOMP]); 01283 rgba[GCOMP] = UP5(col0[GCOMP]); 01284 rgba[RCOMP] = UP5(col0[RCOMP]); 01285 rgba[ACOMP] = UP5(col0[ACOMP]); 01286 } else if (t == 3) { 01287 rgba[BCOMP] = UP5(CC_SEL(cc, 79)); 01288 rgba[GCOMP] = UP5(CC_SEL(cc, 84)); 01289 rgba[RCOMP] = UP5(CC_SEL(cc, 89)); 01290 rgba[ACOMP] = UP5(CC_SEL(cc, 114)); 01291 } else { 01292 rgba[BCOMP] = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79))); 01293 rgba[GCOMP] = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84))); 01294 rgba[RCOMP] = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89))); 01295 rgba[ACOMP] = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114))); 01296 } 01297 } else { 01298 /* lerp == 0 */ 01299 01300 if (t & 16) { 01301 cc++; 01302 t &= 15; 01303 } 01304 t = (cc[0] >> (t * 2)) & 3; 01305 01306 if (t == 3) { 01307 ZERO_4UBV(rgba); 01308 } else { 01309 dword kk; 01310 cc = (const dword *)code; 01311 rgba[ACOMP] = UP5(cc[3] >> (t * 5 + 13)); 01312 t *= 15; 01313 cc = (const dword *)(code + 8 + t / 8); 01314 kk = cc[0] >> (t & 7); 01315 rgba[BCOMP] = UP5(kk); 01316 rgba[GCOMP] = UP5(kk >> 5); 01317 rgba[RCOMP] = UP5(kk >> 10); 01318 } 01319 } 01320 } 01321 01322 01323 TAPI void TAPIENTRY 01324 fxt1_decode_1 (const void *texture, int stride, 01325 int i, int j, byte *rgba) 01326 { 01327 static void (*decode_1[]) (const byte *, int, byte *) = { 01328 fxt1_decode_1HI, /* cc-high = "00?" */ 01329 fxt1_decode_1HI, /* cc-high = "00?" */ 01330 fxt1_decode_1CHROMA, /* cc-chroma = "010" */ 01331 fxt1_decode_1ALPHA, /* alpha = "011" */ 01332 fxt1_decode_1MIXED, /* mixed = "1??" */ 01333 fxt1_decode_1MIXED, /* mixed = "1??" */ 01334 fxt1_decode_1MIXED, /* mixed = "1??" */ 01335 fxt1_decode_1MIXED /* mixed = "1??" */ 01336 }; 01337 01338 const byte *code = (const byte *)texture + 01339 ((j / 4) * (stride / 8) + (i / 8)) * 16; 01340 int mode = CC_SEL(code, 125); 01341 int t = i & 7; 01342 01343 if (t & 4) { 01344 t += 12; 01345 } 01346 t += (j & 3) * 4; 01347 01348 decode_1[mode](code, t, rgba); 01349 01350 #if VERBOSE 01351 { 01352 extern int cc_chroma; 01353 extern int cc_alpha; 01354 extern int cc_high; 01355 extern int cc_mixed; 01356 static int *cctype[] = { 01357 &cc_high, 01358 &cc_high, 01359 &cc_chroma, 01360 &cc_alpha, 01361 &cc_mixed, 01362 &cc_mixed, 01363 &cc_mixed, 01364 &cc_mixed 01365 }; 01366 (*cctype[mode])++; 01367 } 01368 #endif 01369 } Generated on Sun May 27 2012 04:19:21 for ReactOS by
1.7.6.1
|