101e04c3fSmrg/* 201e04c3fSmrg * Copyright (C) 2011 Red Hat Inc. 301e04c3fSmrg * 401e04c3fSmrg * block compression parts are: 501e04c3fSmrg * Copyright (C) 2004 Roland Scheidegger All Rights Reserved. 601e04c3fSmrg * 701e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 801e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 901e04c3fSmrg * to deal in the Software without restriction, including without limitation 1001e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1101e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 1201e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1301e04c3fSmrg * 1401e04c3fSmrg * The above copyright notice and this permission notice (including the next 1501e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1601e04c3fSmrg * Software. 1701e04c3fSmrg * 1801e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1901e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2001e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2101e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2201e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2301e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2401e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2501e04c3fSmrg * 2601e04c3fSmrg * Author: 2701e04c3fSmrg * Dave Airlie 2801e04c3fSmrg */ 2901e04c3fSmrg 3001e04c3fSmrg/* included by texcompress_rgtc to define byte/ubyte compressors */ 3101e04c3fSmrg 3201e04c3fSmrgvoid TAG(fetch_texel_rgtc)(unsigned srcRowStride, const TYPE *pixdata, 3301e04c3fSmrg unsigned i, unsigned j, TYPE *value, unsigned comps) 3401e04c3fSmrg{ 3501e04c3fSmrg TYPE decode; 3601e04c3fSmrg const TYPE *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps); 3701e04c3fSmrg const TYPE alpha0 = blksrc[0]; 3801e04c3fSmrg const TYPE alpha1 = blksrc[1]; 3901e04c3fSmrg const char bit_pos = ((j&3) * 4 + (i&3)) * 3; 4001e04c3fSmrg const unsigned char acodelow = blksrc[2 + bit_pos / 8]; 4101e04c3fSmrg const unsigned char acodehigh = (3 + bit_pos / 8) < 8 ? blksrc[3 + bit_pos / 8] : 0; 4201e04c3fSmrg const unsigned char code = (acodelow >> (bit_pos & 0x7) | 4301e04c3fSmrg (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7; 4401e04c3fSmrg 4501e04c3fSmrg if (code == 0) 4601e04c3fSmrg decode = alpha0; 4701e04c3fSmrg else if (code == 1) 4801e04c3fSmrg decode = alpha1; 4901e04c3fSmrg else if (alpha0 > alpha1) 5001e04c3fSmrg decode = ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7); 5101e04c3fSmrg else if (code < 6) 5201e04c3fSmrg decode = ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5); 5301e04c3fSmrg else if (code == 6) 5401e04c3fSmrg decode = T_MIN; 5501e04c3fSmrg else 5601e04c3fSmrg decode = T_MAX; 5701e04c3fSmrg 5801e04c3fSmrg *value = decode; 5901e04c3fSmrg} 6001e04c3fSmrg 6101e04c3fSmrgstatic void TAG(write_rgtc_encoded_channel)(TYPE *blkaddr, 6201e04c3fSmrg TYPE alphabase1, 6301e04c3fSmrg TYPE alphabase2, 6401e04c3fSmrg TYPE alphaenc[16]) 6501e04c3fSmrg{ 6601e04c3fSmrg *blkaddr++ = alphabase1; 6701e04c3fSmrg *blkaddr++ = alphabase2; 6801e04c3fSmrg *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6); 6901e04c3fSmrg *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7); 7001e04c3fSmrg *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5); 7101e04c3fSmrg *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6); 7201e04c3fSmrg *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7); 7301e04c3fSmrg *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5); 7401e04c3fSmrg} 7501e04c3fSmrg 7601e04c3fSmrgvoid TAG(encode_rgtc_ubyte)(TYPE *blkaddr, TYPE srccolors[4][4], 7701e04c3fSmrg int numxpixels, int numypixels) 7801e04c3fSmrg{ 7901e04c3fSmrg TYPE alphabase[2], alphause[2]; 8001e04c3fSmrg short alphatest[2] = { 0 }; 8101e04c3fSmrg unsigned int alphablockerror1, alphablockerror2, alphablockerror3; 8201e04c3fSmrg TYPE i, j, aindex, acutValues[7]; 8301e04c3fSmrg TYPE alphaenc1[16], alphaenc2[16], alphaenc3[16]; 8401e04c3fSmrg int alphaabsmin = 0, alphaabsmax = 0; 8501e04c3fSmrg short alphadist; 8601e04c3fSmrg 8701e04c3fSmrg /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */ 8801e04c3fSmrg alphabase[0] = T_MAX; alphabase[1] = T_MIN; 8901e04c3fSmrg for (j = 0; j < numypixels; j++) { 9001e04c3fSmrg for (i = 0; i < numxpixels; i++) { 9101e04c3fSmrg if (srccolors[j][i] == T_MIN) 9201e04c3fSmrg alphaabsmin = 1; 9301e04c3fSmrg else if (srccolors[j][i] == T_MAX) 9401e04c3fSmrg alphaabsmax = 1; 9501e04c3fSmrg else { 9601e04c3fSmrg if (srccolors[j][i] > alphabase[1]) 9701e04c3fSmrg alphabase[1] = srccolors[j][i]; 9801e04c3fSmrg if (srccolors[j][i] < alphabase[0]) 9901e04c3fSmrg alphabase[0] = srccolors[j][i]; 10001e04c3fSmrg } 10101e04c3fSmrg } 10201e04c3fSmrg } 10301e04c3fSmrg 10401e04c3fSmrg 10501e04c3fSmrg if (((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax)) 10601e04c3fSmrg || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax)) { /* one color, either max or min */ 10701e04c3fSmrg /* shortcut here since it is a very common case (and also avoids later problems) */ 10801e04c3fSmrg /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */ 10901e04c3fSmrg 11001e04c3fSmrg *blkaddr++ = srccolors[0][0]; 11101e04c3fSmrg blkaddr++; 11201e04c3fSmrg *blkaddr++ = 0; 11301e04c3fSmrg *blkaddr++ = 0; 11401e04c3fSmrg *blkaddr++ = 0; 11501e04c3fSmrg *blkaddr++ = 0; 11601e04c3fSmrg *blkaddr++ = 0; 11701e04c3fSmrg *blkaddr++ = 0; 11801e04c3fSmrg#if RGTC_DEBUG 11901e04c3fSmrg fprintf(stderr, "enc0 used\n"); 12001e04c3fSmrg#endif 12101e04c3fSmrg return; 12201e04c3fSmrg } 12301e04c3fSmrg 12401e04c3fSmrg /* find best encoding for alpha0 > alpha1 */ 12501e04c3fSmrg /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */ 12601e04c3fSmrg alphablockerror1 = 0x0; 12701e04c3fSmrg alphablockerror2 = 0xffffffff; 12801e04c3fSmrg alphablockerror3 = 0xffffffff; 12901e04c3fSmrg if (alphaabsmin) alphause[0] = T_MIN; 13001e04c3fSmrg else alphause[0] = alphabase[0]; 13101e04c3fSmrg if (alphaabsmax) alphause[1] = T_MAX; 13201e04c3fSmrg else alphause[1] = alphabase[1]; 13301e04c3fSmrg /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */ 13401e04c3fSmrg for (aindex = 0; aindex < 7; aindex++) { 13501e04c3fSmrg /* don't forget here is always rounded down */ 13601e04c3fSmrg acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14; 13701e04c3fSmrg } 13801e04c3fSmrg 13901e04c3fSmrg for (j = 0; j < numypixels; j++) { 14001e04c3fSmrg for (i = 0; i < numxpixels; i++) { 14101e04c3fSmrg /* maybe it's overkill to have the most complicated calculation just for the error 14201e04c3fSmrg calculation which we only need to figure out if encoding1 or encoding2 is better... */ 14301e04c3fSmrg if (srccolors[j][i] > acutValues[0]) { 14401e04c3fSmrg alphaenc1[4*j + i] = 0; 14501e04c3fSmrg alphadist = srccolors[j][i] - alphause[1]; 14601e04c3fSmrg } 14701e04c3fSmrg else if (srccolors[j][i] > acutValues[1]) { 14801e04c3fSmrg alphaenc1[4*j + i] = 2; 14901e04c3fSmrg alphadist = srccolors[j][i] - (alphause[1] * 6 + alphause[0] * 1) / 7; 15001e04c3fSmrg } 15101e04c3fSmrg else if (srccolors[j][i] > acutValues[2]) { 15201e04c3fSmrg alphaenc1[4*j + i] = 3; 15301e04c3fSmrg alphadist = srccolors[j][i] - (alphause[1] * 5 + alphause[0] * 2) / 7; 15401e04c3fSmrg } 15501e04c3fSmrg else if (srccolors[j][i] > acutValues[3]) { 15601e04c3fSmrg alphaenc1[4*j + i] = 4; 15701e04c3fSmrg alphadist = srccolors[j][i] - (alphause[1] * 4 + alphause[0] * 3) / 7; 15801e04c3fSmrg } 15901e04c3fSmrg else if (srccolors[j][i] > acutValues[4]) { 16001e04c3fSmrg alphaenc1[4*j + i] = 5; 16101e04c3fSmrg alphadist = srccolors[j][i] - (alphause[1] * 3 + alphause[0] * 4) / 7; 16201e04c3fSmrg } 16301e04c3fSmrg else if (srccolors[j][i] > acutValues[5]) { 16401e04c3fSmrg alphaenc1[4*j + i] = 6; 16501e04c3fSmrg alphadist = srccolors[j][i] - (alphause[1] * 2 + alphause[0] * 5) / 7; 16601e04c3fSmrg } 16701e04c3fSmrg else if (srccolors[j][i] > acutValues[6]) { 16801e04c3fSmrg alphaenc1[4*j + i] = 7; 16901e04c3fSmrg alphadist = srccolors[j][i] - (alphause[1] * 1 + alphause[0] * 6) / 7; 17001e04c3fSmrg } 17101e04c3fSmrg else { 17201e04c3fSmrg alphaenc1[4*j + i] = 1; 17301e04c3fSmrg alphadist = srccolors[j][i] - alphause[0]; 17401e04c3fSmrg } 17501e04c3fSmrg alphablockerror1 += alphadist * alphadist; 17601e04c3fSmrg } 17701e04c3fSmrg } 17801e04c3fSmrg 17901e04c3fSmrg#if RGTC_DEBUG 18001e04c3fSmrg for (i = 0; i < 16; i++) { 18101e04c3fSmrg fprintf(stderr, "%d ", alphaenc1[i]); 18201e04c3fSmrg } 18301e04c3fSmrg fprintf(stderr, "cutVals "); 18401e04c3fSmrg for (i = 0; i < 7; i++) { 18501e04c3fSmrg fprintf(stderr, "%d ", acutValues[i]); 18601e04c3fSmrg } 18701e04c3fSmrg fprintf(stderr, "srcVals "); 18801e04c3fSmrg for (j = 0; j < numypixels; j++) { 18901e04c3fSmrg for (i = 0; i < numxpixels; i++) { 19001e04c3fSmrg fprintf(stderr, "%d ", srccolors[j][i]); 19101e04c3fSmrg } 19201e04c3fSmrg } 19301e04c3fSmrg fprintf(stderr, "\n"); 19401e04c3fSmrg#endif 19501e04c3fSmrg 19601e04c3fSmrg /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax 19701e04c3fSmrg are false but try it anyway */ 19801e04c3fSmrg if (alphablockerror1 >= 32) { 19901e04c3fSmrg 20001e04c3fSmrg /* don't bother if encoding is already very good, this condition should also imply 20101e04c3fSmrg we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */ 20201e04c3fSmrg alphablockerror2 = 0; 20301e04c3fSmrg for (aindex = 0; aindex < 5; aindex++) { 20401e04c3fSmrg /* don't forget here is always rounded down */ 20501e04c3fSmrg acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10; 20601e04c3fSmrg } 20701e04c3fSmrg for (j = 0; j < numypixels; j++) { 20801e04c3fSmrg for (i = 0; i < numxpixels; i++) { 20901e04c3fSmrg /* maybe it's overkill to have the most complicated calculation just for the error 21001e04c3fSmrg calculation which we only need to figure out if encoding1 or encoding2 is better... */ 21101e04c3fSmrg if (srccolors[j][i] == T_MIN) { 21201e04c3fSmrg alphaenc2[4*j + i] = 6; 21301e04c3fSmrg alphadist = 0; 21401e04c3fSmrg } 21501e04c3fSmrg else if (srccolors[j][i] == T_MAX) { 21601e04c3fSmrg alphaenc2[4*j + i] = 7; 21701e04c3fSmrg alphadist = 0; 21801e04c3fSmrg } 21901e04c3fSmrg else if (srccolors[j][i] <= acutValues[0]) { 22001e04c3fSmrg alphaenc2[4*j + i] = 0; 22101e04c3fSmrg alphadist = srccolors[j][i] - alphabase[0]; 22201e04c3fSmrg } 22301e04c3fSmrg else if (srccolors[j][i] <= acutValues[1]) { 22401e04c3fSmrg alphaenc2[4*j + i] = 2; 22501e04c3fSmrg alphadist = srccolors[j][i] - (alphabase[0] * 4 + alphabase[1] * 1) / 5; 22601e04c3fSmrg } 22701e04c3fSmrg else if (srccolors[j][i] <= acutValues[2]) { 22801e04c3fSmrg alphaenc2[4*j + i] = 3; 22901e04c3fSmrg alphadist = srccolors[j][i] - (alphabase[0] * 3 + alphabase[1] * 2) / 5; 23001e04c3fSmrg } 23101e04c3fSmrg else if (srccolors[j][i] <= acutValues[3]) { 23201e04c3fSmrg alphaenc2[4*j + i] = 4; 23301e04c3fSmrg alphadist = srccolors[j][i] - (alphabase[0] * 2 + alphabase[1] * 3) / 5; 23401e04c3fSmrg } 23501e04c3fSmrg else if (srccolors[j][i] <= acutValues[4]) { 23601e04c3fSmrg alphaenc2[4*j + i] = 5; 23701e04c3fSmrg alphadist = srccolors[j][i] - (alphabase[0] * 1 + alphabase[1] * 4) / 5; 23801e04c3fSmrg } 23901e04c3fSmrg else { 24001e04c3fSmrg alphaenc2[4*j + i] = 1; 24101e04c3fSmrg alphadist = srccolors[j][i] - alphabase[1]; 24201e04c3fSmrg } 24301e04c3fSmrg alphablockerror2 += alphadist * alphadist; 24401e04c3fSmrg } 24501e04c3fSmrg } 24601e04c3fSmrg 24701e04c3fSmrg 24801e04c3fSmrg /* skip this if the error is already very small 24901e04c3fSmrg this encoding is MUCH better on average than #2 though, but expensive! */ 25001e04c3fSmrg if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) { 25101e04c3fSmrg short blockerrlin1 = 0; 25201e04c3fSmrg short blockerrlin2 = 0; 25301e04c3fSmrg TYPE nralphainrangelow = 0; 25401e04c3fSmrg TYPE nralphainrangehigh = 0; 25501e04c3fSmrg alphatest[0] = T_MAX; 25601e04c3fSmrg alphatest[1] = T_MIN; 25701e04c3fSmrg /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */ 25801e04c3fSmrg for (j = 0; j < numypixels; j++) { 25901e04c3fSmrg for (i = 0; i < numxpixels; i++) { 26001e04c3fSmrg if ((srccolors[j][i] > alphatest[1]) && (srccolors[j][i] < (T_MAX -(alphabase[1] - alphabase[0]) / 28))) 26101e04c3fSmrg alphatest[1] = srccolors[j][i]; 26201e04c3fSmrg if ((srccolors[j][i] < alphatest[0]) && (srccolors[j][i] > (alphabase[1] - alphabase[0]) / 28)) 26301e04c3fSmrg alphatest[0] = srccolors[j][i]; 26401e04c3fSmrg } 26501e04c3fSmrg } 26601e04c3fSmrg /* shouldn't happen too often, don't really care about those degenerated cases */ 26701e04c3fSmrg if (alphatest[1] <= alphatest[0]) { 26801e04c3fSmrg alphatest[0] = T_MIN+1; 26901e04c3fSmrg alphatest[1] = T_MAX-1; 27001e04c3fSmrg } 27101e04c3fSmrg for (aindex = 0; aindex < 5; aindex++) { 27201e04c3fSmrg /* don't forget here is always rounded down */ 27301e04c3fSmrg acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; 27401e04c3fSmrg } 27501e04c3fSmrg 27601e04c3fSmrg /* find the "average" difference between the alpha values and the next encoded value. 27701e04c3fSmrg This is then used to calculate new base values. 27801e04c3fSmrg Should there be some weighting, i.e. those values closer to alphatest[x] have more weight, 27901e04c3fSmrg since they will see more improvement, and also because the values in the middle are somewhat 28001e04c3fSmrg likely to get no improvement at all (because the base values might move in different directions)? 28101e04c3fSmrg OTOH it would mean the values in the middle are even less likely to get an improvement 28201e04c3fSmrg */ 28301e04c3fSmrg for (j = 0; j < numypixels; j++) { 28401e04c3fSmrg for (i = 0; i < numxpixels; i++) { 28501e04c3fSmrg if (srccolors[j][i] <= alphatest[0] / 2) { 28601e04c3fSmrg } 28701e04c3fSmrg else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) { 28801e04c3fSmrg } 28901e04c3fSmrg else if (srccolors[j][i] <= acutValues[0]) { 29001e04c3fSmrg blockerrlin1 += (srccolors[j][i] - alphatest[0]); 29101e04c3fSmrg nralphainrangelow += 1; 29201e04c3fSmrg } 29301e04c3fSmrg else if (srccolors[j][i] <= acutValues[1]) { 29401e04c3fSmrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); 29501e04c3fSmrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); 29601e04c3fSmrg nralphainrangelow += 1; 29701e04c3fSmrg nralphainrangehigh += 1; 29801e04c3fSmrg } 29901e04c3fSmrg else if (srccolors[j][i] <= acutValues[2]) { 30001e04c3fSmrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); 30101e04c3fSmrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); 30201e04c3fSmrg nralphainrangelow += 1; 30301e04c3fSmrg nralphainrangehigh += 1; 30401e04c3fSmrg } 30501e04c3fSmrg else if (srccolors[j][i] <= acutValues[3]) { 30601e04c3fSmrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); 30701e04c3fSmrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); 30801e04c3fSmrg nralphainrangelow += 1; 30901e04c3fSmrg nralphainrangehigh += 1; 31001e04c3fSmrg } 31101e04c3fSmrg else if (srccolors[j][i] <= acutValues[4]) { 31201e04c3fSmrg blockerrlin1 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); 31301e04c3fSmrg blockerrlin2 += (srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); 31401e04c3fSmrg nralphainrangelow += 1; 31501e04c3fSmrg nralphainrangehigh += 1; 31601e04c3fSmrg } 31701e04c3fSmrg else { 31801e04c3fSmrg blockerrlin2 += (srccolors[j][i] - alphatest[1]); 31901e04c3fSmrg nralphainrangehigh += 1; 32001e04c3fSmrg } 32101e04c3fSmrg } 32201e04c3fSmrg } 32301e04c3fSmrg /* shouldn't happen often, needed to avoid div by zero */ 32401e04c3fSmrg if (nralphainrangelow == 0) nralphainrangelow = 1; 32501e04c3fSmrg if (nralphainrangehigh == 0) nralphainrangehigh = 1; 32601e04c3fSmrg alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow); 32701e04c3fSmrg#if RGTC_DEBUG 32801e04c3fSmrg fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow); 32901e04c3fSmrg fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh); 33001e04c3fSmrg#endif 33101e04c3fSmrg /* again shouldn't really happen often... */ 33201e04c3fSmrg if (alphatest[0] < T_MIN) { 33301e04c3fSmrg alphatest[0] = T_MIN; 33401e04c3fSmrg } 33501e04c3fSmrg alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh); 33601e04c3fSmrg if (alphatest[1] > T_MAX) { 33701e04c3fSmrg alphatest[1] = T_MAX; 33801e04c3fSmrg } 33901e04c3fSmrg 34001e04c3fSmrg alphablockerror3 = 0; 34101e04c3fSmrg for (aindex = 0; aindex < 5; aindex++) { 34201e04c3fSmrg /* don't forget here is always rounded down */ 34301e04c3fSmrg acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; 34401e04c3fSmrg } 34501e04c3fSmrg for (j = 0; j < numypixels; j++) { 34601e04c3fSmrg for (i = 0; i < numxpixels; i++) { 34701e04c3fSmrg /* maybe it's overkill to have the most complicated calculation just for the error 34801e04c3fSmrg calculation which we only need to figure out if encoding1 or encoding2 is better... */ 34901e04c3fSmrg if (srccolors[j][i] <= alphatest[0] / 2) { 35001e04c3fSmrg alphaenc3[4*j + i] = 6; 35101e04c3fSmrg alphadist = srccolors[j][i]; 35201e04c3fSmrg } 35301e04c3fSmrg else if (srccolors[j][i] > ((T_MAX + alphatest[1]) / 2)) { 35401e04c3fSmrg alphaenc3[4*j + i] = 7; 35501e04c3fSmrg alphadist = T_MAX - srccolors[j][i]; 35601e04c3fSmrg } 35701e04c3fSmrg else if (srccolors[j][i] <= acutValues[0]) { 35801e04c3fSmrg alphaenc3[4*j + i] = 0; 35901e04c3fSmrg alphadist = srccolors[j][i] - alphatest[0]; 36001e04c3fSmrg } 36101e04c3fSmrg else if (srccolors[j][i] <= acutValues[1]) { 36201e04c3fSmrg alphaenc3[4*j + i] = 2; 36301e04c3fSmrg alphadist = srccolors[j][i] - (alphatest[0] * 4 + alphatest[1] * 1) / 5; 36401e04c3fSmrg } 36501e04c3fSmrg else if (srccolors[j][i] <= acutValues[2]) { 36601e04c3fSmrg alphaenc3[4*j + i] = 3; 36701e04c3fSmrg alphadist = srccolors[j][i] - (alphatest[0] * 3 + alphatest[1] * 2) / 5; 36801e04c3fSmrg } 36901e04c3fSmrg else if (srccolors[j][i] <= acutValues[3]) { 37001e04c3fSmrg alphaenc3[4*j + i] = 4; 37101e04c3fSmrg alphadist = srccolors[j][i] - (alphatest[0] * 2 + alphatest[1] * 3) / 5; 37201e04c3fSmrg } 37301e04c3fSmrg else if (srccolors[j][i] <= acutValues[4]) { 37401e04c3fSmrg alphaenc3[4*j + i] = 5; 37501e04c3fSmrg alphadist = srccolors[j][i] - (alphatest[0] * 1 + alphatest[1] * 4) / 5; 37601e04c3fSmrg } 37701e04c3fSmrg else { 37801e04c3fSmrg alphaenc3[4*j + i] = 1; 37901e04c3fSmrg alphadist = srccolors[j][i] - alphatest[1]; 38001e04c3fSmrg } 38101e04c3fSmrg alphablockerror3 += alphadist * alphadist; 38201e04c3fSmrg } 38301e04c3fSmrg } 38401e04c3fSmrg } 38501e04c3fSmrg } 38601e04c3fSmrg 38701e04c3fSmrg /* write the alpha values and encoding back. */ 38801e04c3fSmrg if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) { 38901e04c3fSmrg#if RGTC_DEBUG 39001e04c3fSmrg if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1); 39101e04c3fSmrg fprintf(stderr,"w1: min %d max %d au0 %d au1 %d\n", 39201e04c3fSmrg T_MIN, T_MAX, 39301e04c3fSmrg alphause[1], alphause[0]); 39401e04c3fSmrg#endif 39501e04c3fSmrg 39601e04c3fSmrg TAG(write_rgtc_encoded_channel)( blkaddr, alphause[1], alphause[0], alphaenc1 ); 39701e04c3fSmrg } 39801e04c3fSmrg else if (alphablockerror2 <= alphablockerror3) { 39901e04c3fSmrg#if RGTC_DEBUG 40001e04c3fSmrg if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2); 40101e04c3fSmrg fprintf(stderr,"w2: min %d max %d au0 %d au1 %d\n", 40201e04c3fSmrg T_MIN, T_MAX, 40301e04c3fSmrg alphabase[0], alphabase[1]); 40401e04c3fSmrg#endif 40501e04c3fSmrg 40601e04c3fSmrg TAG(write_rgtc_encoded_channel)( blkaddr, alphabase[0], alphabase[1], alphaenc2 ); 40701e04c3fSmrg } 40801e04c3fSmrg else { 40901e04c3fSmrg#if RGTC_DEBUG 41001e04c3fSmrg fprintf(stderr, "enc3 used, error %d\n", alphablockerror3); 41101e04c3fSmrg fprintf(stderr,"w3: min %d max %d au0 %d au1 %d\n", 41201e04c3fSmrg T_MIN, T_MAX, 41301e04c3fSmrg alphatest[0], alphatest[1]); 41401e04c3fSmrg#endif 41501e04c3fSmrg 41601e04c3fSmrg TAG(write_rgtc_encoded_channel)( blkaddr, (TYPE)alphatest[0], (TYPE)alphatest[1], alphaenc3 ); 41701e04c3fSmrg } 41801e04c3fSmrg} 419