1b8e80941Smrg/* 2b8e80941Smrg * Copyright (C) 2011 Red Hat Inc. 3b8e80941Smrg * 4b8e80941Smrg * block compression parts are: 5b8e80941Smrg * Copyright (C) 2004 Roland Scheidegger All Rights Reserved. 6b8e80941Smrg * 7b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 9b8e80941Smrg * to deal in the Software without restriction, including without limitation 10b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 12b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 13b8e80941Smrg * 14b8e80941Smrg * The above copyright notice and this permission notice (including the next 15b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 16b8e80941Smrg * Software. 17b8e80941Smrg * 18b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24b8e80941Smrg * DEALINGS IN THE SOFTWARE. 25b8e80941Smrg * 26b8e80941Smrg * Author: 27b8e80941Smrg * Dave Airlie 28b8e80941Smrg */ 29b8e80941Smrg 30b8e80941Smrg/* included by texcompress_rgtc to define byte/ubyte compressors */ 31b8e80941Smrg 32b8e80941Smrgvoid TAG(fetch_texel_rgtc)(unsigned srcRowStride, const TYPE *pixdata, 33b8e80941Smrg unsigned i, unsigned j, TYPE *value, unsigned comps) 34b8e80941Smrg{ 35b8e80941Smrg TYPE decode; 36b8e80941Smrg const TYPE *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps); 37b8e80941Smrg const TYPE alpha0 = blksrc[0]; 38b8e80941Smrg const TYPE alpha1 = blksrc[1]; 39b8e80941Smrg const char bit_pos = ((j&3) * 4 + (i&3)) * 3; 40b8e80941Smrg const unsigned char acodelow = blksrc[2 + bit_pos / 8]; 41b8e80941Smrg const unsigned char acodehigh = (3 + bit_pos / 8) < 8 ? blksrc[3 + bit_pos / 8] : 0; 42b8e80941Smrg const unsigned char code = (acodelow >> (bit_pos & 0x7) | 43b8e80941Smrg (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7; 44b8e80941Smrg 45b8e80941Smrg if (code == 0) 46b8e80941Smrg decode = alpha0; 47b8e80941Smrg else if (code == 1) 48b8e80941Smrg decode = alpha1; 49b8e80941Smrg else if (alpha0 > alpha1) 50b8e80941Smrg decode = ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7); 51b8e80941Smrg else if (code < 6) 52b8e80941Smrg decode = ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5); 53b8e80941Smrg else if (code == 6) 54b8e80941Smrg decode = T_MIN; 55b8e80941Smrg else 56b8e80941Smrg decode = T_MAX; 57b8e80941Smrg 58b8e80941Smrg *value = decode; 59b8e80941Smrg} 60b8e80941Smrg 61b8e80941Smrgstatic void TAG(write_rgtc_encoded_channel)(TYPE *blkaddr, 62b8e80941Smrg TYPE alphabase1, 63b8e80941Smrg TYPE alphabase2, 64b8e80941Smrg TYPE alphaenc[16]) 65b8e80941Smrg{ 66b8e80941Smrg *blkaddr++ = alphabase1; 67b8e80941Smrg *blkaddr++ = alphabase2; 68b8e80941Smrg *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6); 69b8e80941Smrg *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7); 70b8e80941Smrg *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5); 71b8e80941Smrg *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6); 72b8e80941Smrg *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7); 73b8e80941Smrg *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5); 74b8e80941Smrg} 75b8e80941Smrg 76b8e80941Smrgvoid TAG(encode_rgtc_ubyte)(TYPE *blkaddr, TYPE srccolors[4][4], 77b8e80941Smrg int numxpixels, int numypixels) 78b8e80941Smrg{ 79b8e80941Smrg TYPE alphabase[2], alphause[2]; 80b8e80941Smrg short alphatest[2] = { 0 }; 81b8e80941Smrg unsigned int alphablockerror1, alphablockerror2, alphablockerror3; 82b8e80941Smrg TYPE i, j, aindex, acutValues[7]; 83b8e80941Smrg TYPE alphaenc1[16], alphaenc2[16], alphaenc3[16]; 84b8e80941Smrg int alphaabsmin = 0, alphaabsmax = 0; 85b8e80941Smrg short alphadist; 86b8e80941Smrg 87b8e80941Smrg /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */ 88b8e80941Smrg alphabase[0] = T_MAX; alphabase[1] = T_MIN; 89b8e80941Smrg for (j = 0; j < numypixels; j++) { 90b8e80941Smrg for (i = 0; i < numxpixels; i++) { 91b8e80941Smrg if (srccolors[j][i] == T_MIN) 92b8e80941Smrg alphaabsmin = 1; 93b8e80941Smrg else if (srccolors[j][i] == T_MAX) 94b8e80941Smrg alphaabsmax = 1; 95b8e80941Smrg else { 96b8e80941Smrg if (srccolors[j][i] > alphabase[1]) 97b8e80941Smrg alphabase[1] = srccolors[j][i]; 98b8e80941Smrg if (srccolors[j][i] < alphabase[0]) 99b8e80941Smrg alphabase[0] = srccolors[j][i]; 100b8e80941Smrg } 101b8e80941Smrg } 102b8e80941Smrg } 103b8e80941Smrg 104b8e80941Smrg 105b8e80941Smrg if (((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax)) 106b8e80941Smrg || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax)) { /* one color, either max or min */ 107b8e80941Smrg /* shortcut here since it is a very common case (and also avoids later problems) */ 108b8e80941Smrg /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */ 109b8e80941Smrg 110b8e80941Smrg *blkaddr++ = srccolors[0][0]; 111b8e80941Smrg blkaddr++; 112b8e80941Smrg *blkaddr++ = 0; 113b8e80941Smrg *blkaddr++ = 0; 114b8e80941Smrg *blkaddr++ = 0; 115b8e80941Smrg *blkaddr++ = 0; 116b8e80941Smrg *blkaddr++ = 0; 117b8e80941Smrg *blkaddr++ = 0; 118b8e80941Smrg#if RGTC_DEBUG 119b8e80941Smrg fprintf(stderr, "enc0 used\n"); 120b8e80941Smrg#endif 121b8e80941Smrg return; 122b8e80941Smrg } 123b8e80941Smrg 124b8e80941Smrg /* find best encoding for alpha0 > alpha1 */ 125b8e80941Smrg /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */ 126b8e80941Smrg alphablockerror1 = 0x0; 127b8e80941Smrg alphablockerror2 = 0xffffffff; 128b8e80941Smrg alphablockerror3 = 0xffffffff; 129b8e80941Smrg if (alphaabsmin) alphause[0] = T_MIN; 130b8e80941Smrg else alphause[0] = alphabase[0]; 131b8e80941Smrg if (alphaabsmax) alphause[1] = T_MAX; 132b8e80941Smrg else alphause[1] = alphabase[1]; 133b8e80941Smrg /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */ 134b8e80941Smrg for (aindex = 0; aindex < 7; aindex++) { 135b8e80941Smrg /* don't forget here is always rounded down */ 136b8e80941Smrg acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14; 137b8e80941Smrg } 138b8e80941Smrg 139b8e80941Smrg for (j = 0; j < numypixels; j++) { 140b8e80941Smrg for (i = 0; i < numxpixels; i++) { 141b8e80941Smrg /* maybe it's overkill to have the most complicated calculation just for the error 142b8e80941Smrg calculation which we only need to figure out if encoding1 or encoding2 is better... */ 143b8e80941Smrg if (srccolors[j][i] > acutValues[0]) { 144b8e80941Smrg alphaenc1[4*j + i] = 0; 145b8e80941Smrg alphadist = srccolors[j][i] - alphause[1]; 146b8e80941Smrg } 147b8e80941Smrg else if (srccolors[j][i] > acutValues[1]) { 148b8e80941Smrg alphaenc1[4*j + i] = 2; 149b8e80941Smrg alphadist = srccolors[j][i] - (alphause[1] * 6 + alphause[0] * 1) / 7; 150b8e80941Smrg } 151b8e80941Smrg else if (srccolors[j][i] > acutValues[2]) { 152b8e80941Smrg alphaenc1[4*j + i] = 3; 153b8e80941Smrg alphadist = srccolors[j][i] - (alphause[1] * 5 + alphause[0] * 2) / 7; 154b8e80941Smrg } 155b8e80941Smrg else if (srccolors[j][i] > acutValues[3]) { 156b8e80941Smrg alphaenc1[4*j + i] = 4; 157b8e80941Smrg alphadist = srccolors[j][i] - (alphause[1] * 4 + alphause[0] * 3) / 7; 158b8e80941Smrg } 159b8e80941Smrg else if (srccolors[j][i] > acutValues[4]) { 160b8e80941Smrg alphaenc1[4*j + i] = 5; 161b8e80941Smrg alphadist = srccolors[j][i] - (alphause[1] * 3 + alphause[0] * 4) / 7; 162b8e80941Smrg } 163b8e80941Smrg else if (srccolors[j][i] > acutValues[5]) { 164b8e80941Smrg alphaenc1[4*j + i] = 6; 165b8e80941Smrg alphadist = srccolors[j][i] - (alphause[1] * 2 + alphause[0] * 5) / 7; 166b8e80941Smrg } 167b8e80941Smrg else if (srccolors[j][i] > acutValues[6]) { 168b8e80941Smrg alphaenc1[4*j + i] = 7; 169b8e80941Smrg alphadist = srccolors[j][i] - (alphause[1] * 1 + alphause[0] * 6) / 7; 170b8e80941Smrg } 171b8e80941Smrg else { 172b8e80941Smrg alphaenc1[4*j + i] = 1; 173b8e80941Smrg alphadist = srccolors[j][i] - alphause[0]; 174b8e80941Smrg } 175b8e80941Smrg alphablockerror1 += alphadist * alphadist; 176b8e80941Smrg } 177b8e80941Smrg } 178b8e80941Smrg 179b8e80941Smrg#if RGTC_DEBUG 180b8e80941Smrg for (i = 0; i < 16; i++) { 181b8e80941Smrg fprintf(stderr, "%d ", alphaenc1[i]); 182b8e80941Smrg } 183b8e80941Smrg fprintf(stderr, "cutVals "); 184b8e80941Smrg for (i = 0; i < 7; i++) { 185b8e80941Smrg fprintf(stderr, "%d ", acutValues[i]); 186b8e80941Smrg } 187b8e80941Smrg fprintf(stderr, "srcVals "); 188b8e80941Smrg for (j = 0; j < numypixels; j++) { 189b8e80941Smrg for (i = 0; i < numxpixels; i++) { 190b8e80941Smrg fprintf(stderr, "%d ", srccolors[j][i]); 191b8e80941Smrg } 192b8e80941Smrg } 193b8e80941Smrg fprintf(stderr, "\n"); 194b8e80941Smrg#endif 195b8e80941Smrg 196b8e80941Smrg /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax 197b8e80941Smrg are false but try it anyway */ 198b8e80941Smrg if (alphablockerror1 >= 32) { 199b8e80941Smrg 200b8e80941Smrg /* don't bother if encoding is already very good, this condition should also imply 201b8e80941Smrg we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */ 202b8e80941Smrg alphablockerror2 = 0; 203b8e80941Smrg for (aindex = 0; aindex < 5; aindex++) { 204b8e80941Smrg /* don't forget here is always rounded down */ 205b8e80941Smrg acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10; 206b8e80941Smrg } 207b8e80941Smrg for (j = 0; j < numypixels; j++) { 208b8e80941Smrg for (i = 0; i < numxpixels; i++) { 209b8e80941Smrg /* maybe it's overkill to have the most complicated calculation just for the error 210b8e80941Smrg calculation which we only need to figure out if encoding1 or encoding2 is better... */ 211b8e80941Smrg if (srccolors[j][i] == T_MIN) { 212b8e80941Smrg alphaenc2[4*j + i] = 6; 213b8e80941Smrg alphadist = 0; 214b8e80941Smrg } 215b8e80941Smrg else if (srccolors[j][i] == T_MAX) { 216b8e80941Smrg alphaenc2[4*j + i] = 7; 217b8e80941Smrg alphadist = 0; 218b8e80941Smrg } 219b8e80941Smrg else if (srccolors[j][i] <= acutValues[0]) { 220b8e80941Smrg alphaenc2[4*j + i] = 0; 221b8e80941Smrg alphadist = srccolors[j][i] - alphabase[0]; 222b8e80941Smrg } 223b8e80941Smrg else if (srccolors[j][i] <= acutValues[1]) { 224b8e80941Smrg alphaenc2[4*j + i] = 2; 225b8e80941Smrg alphadist = srccolors[j][i] - (alphabase[0] * 4 + alphabase[1] * 1) / 5; 226b8e80941Smrg } 227b8e80941Smrg else if (srccolors[j][i] <= acutValues[2]) { 228b8e80941Smrg alphaenc2[4*j + i] = 3; 229b8e80941Smrg alphadist = srccolors[j][i] - (alphabase[0] * 3 + alphabase[1] * 2) / 5; 230b8e80941Smrg } 231b8e80941Smrg else if (srccolors[j][i] <= acutValues[3]) { 232b8e80941Smrg alphaenc2[4*j + i] = 4; 233b8e80941Smrg alphadist = srccolors[j][i] - (alphabase[0] * 2 + alphabase[1] * 3) / 5; 234b8e80941Smrg } 235b8e80941Smrg else if (srccolors[j][i] <= acutValues[4]) { 236b8e80941Smrg alphaenc2[4*j + i] = 5; 237b8e80941Smrg alphadist = srccolors[j][i] - (alphabase[0] * 1 + alphabase[1] * 4) / 5; 238b8e80941Smrg } 239b8e80941Smrg else { 240b8e80941Smrg alphaenc2[4*j + i] = 1; 241b8e80941Smrg alphadist = srccolors[j][i] - alphabase[1]; 242b8e80941Smrg } 243b8e80941Smrg alphablockerror2 += alphadist * alphadist; 244b8e80941Smrg } 245b8e80941Smrg } 246b8e80941Smrg 247b8e80941Smrg 248b8e80941Smrg /* skip this if the error is already very small 249b8e80941Smrg this encoding is MUCH better on average than #2 though, but expensive! */ 250b8e80941Smrg if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) { 251b8e80941Smrg short blockerrlin1 = 0; 252b8e80941Smrg short blockerrlin2 = 0; 253b8e80941Smrg TYPE nralphainrangelow = 0; 254b8e80941Smrg TYPE nralphainrangehigh = 0; 255b8e80941Smrg alphatest[0] = T_MAX; 256b8e80941Smrg alphatest[1] = T_MIN; 257b8e80941Smrg /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */ 258b8e80941Smrg for (j = 0; j < numypixels; j++) { 259b8e80941Smrg for (i = 0; i < numxpixels; i++) { 260b8e80941Smrg if ((srccolors[j][i] > alphatest[1]) && (srccolors[j][i] < (T_MAX -(alphabase[1] - alphabase[0]) / 28))) 261b8e80941Smrg alphatest[1] = srccolors[j][i]; 262b8e80941Smrg if ((srccolors[j][i] < alphatest[0]) && (srccolors[j][i] > (alphabase[1] - alphabase[0]) / 28)) 263b8e80941Smrg alphatest[0] = srccolors[j][i]; 264b8e80941Smrg } 265b8e80941Smrg } 266b8e80941Smrg /* shouldn't happen too often, don't really care about those degenerated cases */ 267b8e80941Smrg if (alphatest[1] <= alphatest[0]) { 268b8e80941Smrg alphatest[0] = T_MIN+1; 269b8e80941Smrg alphatest[1] = T_MAX-1; 270b8e80941Smrg } 271b8e80941Smrg for (aindex = 0; aindex < 5; aindex++) { 272b8e80941Smrg /* don't forget here is always rounded down */ 273b8e80941Smrg acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; 274b8e80941Smrg } 275b8e80941Smrg 276b8e80941Smrg /* find the "average" difference between the alpha values and the next encoded value. 277b8e80941Smrg This is then used to calculate new base values. 278b8e80941Smrg Should there be some weighting, i.e. those values closer to alphatest[x] have more weight, 279b8e80941Smrg since they will see more improvement, and also because the values in the middle are somewhat 280b8e80941Smrg likely to get no improvement at all (because the base values might move in different directions)? 281b8e80941Smrg OTOH it would mean the values in the middle are even less likely to get an improvement 282b8e80941Smrg */ 283b8e80941Smrg for (j = 0; j < numypixels; j++) { 284b8e80941Smrg for (i = 0; i < numxpixels; i++) { 285b8e80941Smrg if (srccolors[j][i] <= alphatest[0] / 2) { 286b8e80941Smrg } 287b8e80941Smrg else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) { 288b8e80941Smrg } 289b8e80941Smrg else if (srccolors[j][i] <= acutValues[0]) { 290b8e80941Smrg blockerrlin1 += (srccolors[j][i] - alphatest[0]); 291b8e80941Smrg nralphainrangelow += 1; 292b8e80941Smrg } 293b8e80941Smrg else if (srccolors[j][i] <= acutValues[1]) { 294b8e80941Smrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); 295b8e80941Smrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); 296b8e80941Smrg nralphainrangelow += 1; 297b8e80941Smrg nralphainrangehigh += 1; 298b8e80941Smrg } 299b8e80941Smrg else if (srccolors[j][i] <= acutValues[2]) { 300b8e80941Smrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); 301b8e80941Smrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); 302b8e80941Smrg nralphainrangelow += 1; 303b8e80941Smrg nralphainrangehigh += 1; 304b8e80941Smrg } 305b8e80941Smrg else if (srccolors[j][i] <= acutValues[3]) { 306b8e80941Smrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); 307b8e80941Smrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); 308b8e80941Smrg nralphainrangelow += 1; 309b8e80941Smrg nralphainrangehigh += 1; 310b8e80941Smrg } 311b8e80941Smrg else if (srccolors[j][i] <= acutValues[4]) { 312b8e80941Smrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); 313b8e80941Smrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); 314b8e80941Smrg nralphainrangelow += 1; 315b8e80941Smrg nralphainrangehigh += 1; 316b8e80941Smrg } 317b8e80941Smrg else { 318b8e80941Smrg blockerrlin2 += (srccolors[j][i] - alphatest[1]); 319b8e80941Smrg nralphainrangehigh += 1; 320b8e80941Smrg } 321b8e80941Smrg } 322b8e80941Smrg } 323b8e80941Smrg /* shouldn't happen often, needed to avoid div by zero */ 324b8e80941Smrg if (nralphainrangelow == 0) nralphainrangelow = 1; 325b8e80941Smrg if (nralphainrangehigh == 0) nralphainrangehigh = 1; 326b8e80941Smrg alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow); 327b8e80941Smrg#if RGTC_DEBUG 328b8e80941Smrg fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow); 329b8e80941Smrg fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh); 330b8e80941Smrg#endif 331b8e80941Smrg /* again shouldn't really happen often... */ 332b8e80941Smrg if (alphatest[0] < T_MIN) { 333b8e80941Smrg alphatest[0] = T_MIN; 334b8e80941Smrg } 335b8e80941Smrg alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh); 336b8e80941Smrg if (alphatest[1] > T_MAX) { 337b8e80941Smrg alphatest[1] = T_MAX; 338b8e80941Smrg } 339b8e80941Smrg 340b8e80941Smrg alphablockerror3 = 0; 341b8e80941Smrg for (aindex = 0; aindex < 5; aindex++) { 342b8e80941Smrg /* don't forget here is always rounded down */ 343b8e80941Smrg acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; 344b8e80941Smrg } 345b8e80941Smrg for (j = 0; j < numypixels; j++) { 346b8e80941Smrg for (i = 0; i < numxpixels; i++) { 347b8e80941Smrg /* maybe it's overkill to have the most complicated calculation just for the error 348b8e80941Smrg calculation which we only need to figure out if encoding1 or encoding2 is better... */ 349b8e80941Smrg if (srccolors[j][i] <= alphatest[0] / 2) { 350b8e80941Smrg alphaenc3[4*j + i] = 6; 351b8e80941Smrg alphadist = srccolors[j][i]; 352b8e80941Smrg } 353b8e80941Smrg else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) { 354b8e80941Smrg alphaenc3[4*j + i] = 7; 355b8e80941Smrg alphadist = T_MAX - srccolors[j][i]; 356b8e80941Smrg } 357b8e80941Smrg else if (srccolors[j][i] <= acutValues[0]) { 358b8e80941Smrg alphaenc3[4*j + i] = 0; 359b8e80941Smrg alphadist = srccolors[j][i] - alphatest[0]; 360b8e80941Smrg } 361b8e80941Smrg else if (srccolors[j][i] <= acutValues[1]) { 362b8e80941Smrg alphaenc3[4*j + i] = 2; 363b8e80941Smrg alphadist = srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5; 364b8e80941Smrg } 365b8e80941Smrg else if (srccolors[j][i] <= acutValues[2]) { 366b8e80941Smrg alphaenc3[4*j + i] = 3; 367b8e80941Smrg alphadist = srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5; 368b8e80941Smrg } 369b8e80941Smrg else if (srccolors[j][i] <= acutValues[3]) { 370b8e80941Smrg alphaenc3[4*j + i] = 4; 371b8e80941Smrg alphadist = srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5; 372b8e80941Smrg } 373b8e80941Smrg else if (srccolors[j][i] <= acutValues[4]) { 374b8e80941Smrg alphaenc3[4*j + i] = 5; 375b8e80941Smrg alphadist = srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5; 376b8e80941Smrg } 377b8e80941Smrg else { 378b8e80941Smrg alphaenc3[4*j + i] = 1; 379b8e80941Smrg alphadist = srccolors[j][i] - alphatest[1]; 380b8e80941Smrg } 381b8e80941Smrg alphablockerror3 += alphadist * alphadist; 382b8e80941Smrg } 383b8e80941Smrg } 384b8e80941Smrg } 385b8e80941Smrg } 386b8e80941Smrg 387b8e80941Smrg /* write the alpha values and encoding back. */ 388b8e80941Smrg if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) { 389b8e80941Smrg#if RGTC_DEBUG 390b8e80941Smrg if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1); 391b8e80941Smrg fprintf(stderr,"w1: min %d max %d au0 %d au1 %d\n", 392b8e80941Smrg T_MIN, T_MAX, 393b8e80941Smrg alphause[1], alphause[0]); 394b8e80941Smrg#endif 395b8e80941Smrg 396b8e80941Smrg TAG(write_rgtc_encoded_channel)( blkaddr, alphause[1], alphause[0], alphaenc1 ); 397b8e80941Smrg } 398b8e80941Smrg else if (alphablockerror2 <= alphablockerror3) { 399b8e80941Smrg#if RGTC_DEBUG 400b8e80941Smrg if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2); 401b8e80941Smrg fprintf(stderr,"w2: min %d max %d au0 %d au1 %d\n", 402b8e80941Smrg T_MIN, T_MAX, 403b8e80941Smrg alphabase[0], alphabase[1]); 404b8e80941Smrg#endif 405b8e80941Smrg 406b8e80941Smrg TAG(write_rgtc_encoded_channel)( blkaddr, alphabase[0], alphabase[1], alphaenc2 ); 407b8e80941Smrg } 408b8e80941Smrg else { 409b8e80941Smrg#if RGTC_DEBUG 410b8e80941Smrg fprintf(stderr, "enc3 used, error %d\n", alphablockerror3); 411b8e80941Smrg fprintf(stderr,"w3: min %d max %d au0 %d au1 %d\n", 412b8e80941Smrg T_MIN, T_MAX, 413b8e80941Smrg alphatest[0], alphatest[1]); 414b8e80941Smrg#endif 415b8e80941Smrg 416b8e80941Smrg TAG(write_rgtc_encoded_channel)( blkaddr, (TYPE)alphatest[0], (TYPE)alphatest[1], alphaenc3 ); 417b8e80941Smrg } 418b8e80941Smrg} 419