2 * Copyright (C) 2011 Red Hat Inc.
4 * block compression parts are:
5 * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
31 * \file texcompress_rgtc.c
32 * GL_EXT_texture_compression_rgtc support.
41 #include "mfeatures.h"
43 #include "texcompress.h"
44 #include "texcompress_rgtc.h"
49 static void encode_rgtc_chan_u(GLubyte
*blkaddr
, GLubyte srccolors
[4][4],
50 GLint numxpixels
, GLint numypixels
);
51 static void encode_rgtc_chan_s(GLbyte
*blkaddr
, GLbyte srccolors
[4][4],
52 GLint numxpixels
, GLint numypixels
);
54 static void extractsrc_u( GLubyte srcpixels
[4][4], const GLchan
*srcaddr
,
55 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
58 const GLchan
*curaddr
;
59 for (j
= 0; j
< numypixels
; j
++) {
60 curaddr
= srcaddr
+ j
* srcRowStride
* comps
;
61 for (i
= 0; i
< numxpixels
; i
++) {
62 srcpixels
[j
][i
] = *curaddr
/ (CHAN_MAX
/ 255);
68 static void extractsrc_s( GLbyte srcpixels
[4][4], const GLfloat
*srcaddr
,
69 GLint srcRowStride
, GLint numxpixels
, GLint numypixels
, GLint comps
)
72 const GLfloat
*curaddr
;
73 for (j
= 0; j
< numypixels
; j
++) {
74 curaddr
= srcaddr
+ j
* srcRowStride
* comps
;
75 for (i
= 0; i
< numxpixels
; i
++) {
76 srcpixels
[j
][i
] = FLOAT_TO_BYTE_TEX(*curaddr
);
84 _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS
)
87 const GLint texWidth
= dstRowStride
* 4 / 8; /* a bit of a hack */
88 const GLchan
*tempImage
= NULL
;
90 int numxpixels
, numypixels
;
91 const GLchan
*srcaddr
;
92 GLubyte srcpixels
[4][4];
95 ASSERT(dstFormat
== MESA_FORMAT_RED_RGTC1
);
96 ASSERT(dstXoffset
% 4 == 0);
97 ASSERT(dstYoffset
% 4 == 0);
98 ASSERT(dstZoffset
% 4 == 0);
100 (void) dstImageOffsets
;
103 tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
105 _mesa_get_format_base_format(dstFormat
),
106 srcWidth
, srcHeight
, srcDepth
,
107 srcFormat
, srcType
, srcAddr
,
110 return GL_FALSE
; /* out of memory */
112 dst
= _mesa_compressed_image_address(dstXoffset
, dstYoffset
, 0,
114 texWidth
, (GLubyte
*) dstAddr
);
117 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
118 for (j
= 0; j
< srcHeight
; j
+=4) {
119 if (srcHeight
> j
+ 3) numypixels
= 4;
120 else numypixels
= srcHeight
- j
;
121 srcaddr
= tempImage
+ j
* srcWidth
;
122 for (i
= 0; i
< srcWidth
; i
+= 4) {
123 if (srcWidth
> i
+ 3) numxpixels
= 4;
124 else numxpixels
= srcWidth
- i
;
125 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
126 encode_rgtc_chan_u(blkaddr
, srcpixels
, numxpixels
, numypixels
);
127 srcaddr
+= numxpixels
;
130 blkaddr
+= dstRowDiff
;
133 free((void *) tempImage
);
139 _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS
)
142 const GLint texWidth
= dstRowStride
* 4 / 8; /* a bit of a hack */
143 const GLfloat
*tempImage
= NULL
;
145 int numxpixels
, numypixels
;
146 const GLfloat
*srcaddr
;
147 GLbyte srcpixels
[4][4];
150 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RED_RGTC1
);
151 ASSERT(dstXoffset
% 4 == 0);
152 ASSERT(dstYoffset
% 4 == 0);
153 ASSERT(dstZoffset
% 4 == 0);
155 (void) dstImageOffsets
;
157 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
159 _mesa_get_format_base_format(dstFormat
),
160 srcWidth
, srcHeight
, srcDepth
,
161 srcFormat
, srcType
, srcAddr
,
164 return GL_FALSE
; /* out of memory */
166 dst
= (GLbyte
*)_mesa_compressed_image_address(dstXoffset
, dstYoffset
, 0,
168 texWidth
, (GLubyte
*) dstAddr
);
171 dstRowDiff
= dstRowStride
>= (srcWidth
* 4) ? dstRowStride
- (((srcWidth
+ 3) & ~3) * 4) : 0;
172 for (j
= 0; j
< srcHeight
; j
+=4) {
173 if (srcHeight
> j
+ 3) numypixels
= 4;
174 else numypixels
= srcHeight
- j
;
175 srcaddr
= tempImage
+ j
* srcWidth
;
176 for (i
= 0; i
< srcWidth
; i
+= 4) {
177 if (srcWidth
> i
+ 3) numxpixels
= 4;
178 else numxpixels
= srcWidth
- i
;
179 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 1);
180 encode_rgtc_chan_s(blkaddr
, srcpixels
, numxpixels
, numypixels
);
181 srcaddr
+= numxpixels
;
184 blkaddr
+= dstRowDiff
;
187 free((void *) tempImage
);
193 _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS
)
196 const GLint texWidth
= dstRowStride
* 4 / 16; /* a bit of a hack */
197 const GLchan
*tempImage
= NULL
;
199 int numxpixels
, numypixels
;
200 const GLchan
*srcaddr
;
201 GLubyte srcpixels
[4][4];
205 ASSERT(dstFormat
== MESA_FORMAT_RG_RGTC2
);
206 ASSERT(dstXoffset
% 4 == 0);
207 ASSERT(dstYoffset
% 4 == 0);
208 ASSERT(dstZoffset
% 4 == 0);
210 (void) dstImageOffsets
;
212 tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
214 _mesa_get_format_base_format(dstFormat
),
215 srcWidth
, srcHeight
, srcDepth
,
216 srcFormat
, srcType
, srcAddr
,
219 return GL_FALSE
; /* out of memory */
221 dst
= _mesa_compressed_image_address(dstXoffset
, dstYoffset
, 0,
223 texWidth
, (GLubyte
*) dstAddr
);
226 dstRowDiff
= dstRowStride
>= (srcWidth
* 8) ? dstRowStride
- (((srcWidth
+ 7) & ~7) * 8) : 0;
227 for (j
= 0; j
< srcHeight
; j
+=4) {
228 if (srcHeight
> j
+ 3) numypixels
= 4;
229 else numypixels
= srcHeight
- j
;
230 srcaddr
= tempImage
+ j
* srcWidth
* 2;
231 for (i
= 0; i
< srcWidth
; i
+= 4) {
232 if (srcWidth
> i
+ 3) numxpixels
= 4;
233 else numxpixels
= srcWidth
- i
;
234 extractsrc_u(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
235 encode_rgtc_chan_u(blkaddr
, srcpixels
, numxpixels
, numypixels
);
238 extractsrc_u(srcpixels
, (GLchan
*)srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
239 encode_rgtc_chan_u(blkaddr
, srcpixels
, numxpixels
, numypixels
);
243 srcaddr
+= numxpixels
* 2;
245 blkaddr
+= dstRowDiff
;
248 free((void *) tempImage
);
254 _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS
)
257 const GLint texWidth
= dstRowStride
* 4 / 16; /* a bit of a hack */
258 const GLfloat
*tempImage
= NULL
;
260 int numxpixels
, numypixels
;
261 const GLfloat
*srcaddr
;
262 GLbyte srcpixels
[4][4];
266 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RG_RGTC2
);
267 ASSERT(dstXoffset
% 4 == 0);
268 ASSERT(dstYoffset
% 4 == 0);
269 ASSERT(dstZoffset
% 4 == 0);
271 (void) dstImageOffsets
;
273 tempImage
= _mesa_make_temp_float_image(ctx
, dims
,
275 _mesa_get_format_base_format(dstFormat
),
276 srcWidth
, srcHeight
, srcDepth
,
277 srcFormat
, srcType
, srcAddr
,
280 return GL_FALSE
; /* out of memory */
282 dst
= (GLbyte
*)_mesa_compressed_image_address(dstXoffset
, dstYoffset
, 0,
284 texWidth
, (GLubyte
*) dstAddr
);
287 dstRowDiff
= dstRowStride
>= (srcWidth
* 8) ? dstRowStride
- (((srcWidth
+ 7) & ~7) * 8) : 0;
288 for (j
= 0; j
< srcHeight
; j
+= 4) {
289 if (srcHeight
> j
+ 3) numypixels
= 4;
290 else numypixels
= srcHeight
- j
;
291 srcaddr
= tempImage
+ j
* srcWidth
* 2;
292 for (i
= 0; i
< srcWidth
; i
+= 4) {
293 if (srcWidth
> i
+ 3) numxpixels
= 4;
294 else numxpixels
= srcWidth
- i
;
296 extractsrc_s(srcpixels
, srcaddr
, srcWidth
, numxpixels
, numypixels
, 2);
297 encode_rgtc_chan_s(blkaddr
, srcpixels
, numxpixels
, numypixels
);
300 extractsrc_s(srcpixels
, srcaddr
+ 1, srcWidth
, numxpixels
, numypixels
, 2);
301 encode_rgtc_chan_s(blkaddr
, srcpixels
, numxpixels
, numypixels
);
304 srcaddr
+= numxpixels
* 2;
307 blkaddr
+= dstRowDiff
;
310 free((void *) tempImage
);
315 static void _fetch_texel_rgtc_u(GLint srcRowStride
, const GLubyte
*pixdata
,
316 GLint i
, GLint j
, GLchan
*value
, int comps
)
319 const GLubyte
*blksrc
= (pixdata
+ ((srcRowStride
+ 3) / 4 * (j
/ 4) + (i
/ 4)) * 8 * comps
);
320 const GLubyte alpha0
= blksrc
[0];
321 const GLubyte alpha1
= blksrc
[1];
322 const GLubyte bit_pos
= ((j
&3) * 4 + (i
&3)) * 3;
323 const GLubyte acodelow
= blksrc
[2 + bit_pos
/ 8];
324 const GLubyte acodehigh
= blksrc
[3 + bit_pos
/ 8];
325 const GLubyte code
= (acodelow
>> (bit_pos
& 0x7) |
326 (acodehigh
<< (8 - (bit_pos
& 0x7)))) & 0x7;
329 decode
= UBYTE_TO_CHAN( alpha0
);
331 decode
= UBYTE_TO_CHAN( alpha1
);
332 else if (alpha0
> alpha1
)
333 decode
= UBYTE_TO_CHAN( ((alpha0
* (8 - code
) + (alpha1
* (code
- 1))) / 7) );
335 decode
= UBYTE_TO_CHAN( ((alpha0
* (6 - code
) + (alpha1
* (code
- 1))) / 5) );
345 static void _fetch_texel_rgtc_s(GLint srcRowStride
, const GLbyte
*pixdata
,
346 GLint i
, GLint j
, GLbyte
*value
, int comps
)
349 const GLbyte
*blksrc
= (pixdata
+ ((srcRowStride
+ 3) / 4 * (j
/ 4) + (i
/ 4)) * 8 * comps
);
350 const GLbyte alpha0
= blksrc
[0];
351 const GLbyte alpha1
= blksrc
[1];
352 const GLbyte bit_pos
= ((j
&3) * 4 + (i
&3)) * 3;
353 const GLbyte acodelow
= blksrc
[2 + bit_pos
/ 8];
354 const GLbyte acodehigh
= blksrc
[3 + bit_pos
/ 8];
355 const GLbyte code
= (acodelow
>> (bit_pos
& 0x7) |
356 (acodehigh
<< (8 - (bit_pos
& 0x7)))) & 0x7;
362 else if (alpha0
> alpha1
)
363 decode
= ((alpha0
* (8 - code
) + (alpha1
* (code
- 1))) / 7);
365 decode
= ((alpha0
* (6 - code
) + (alpha1
* (code
- 1))) / 5);
375 _mesa_fetch_texel_2d_f_red_rgtc1(const struct gl_texture_image
*texImage
,
376 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
379 _fetch_texel_rgtc_u(texImage
->RowStride
, (GLubyte
*)(texImage
->Data
),
381 texel
[RCOMP
] = CHAN_TO_FLOAT(red
);
388 _mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct gl_texture_image
*texImage
,
389 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
392 _fetch_texel_rgtc_s(texImage
->RowStride
, (GLbyte
*)(texImage
->Data
),
394 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
401 _mesa_fetch_texel_2d_f_rg_rgtc2(const struct gl_texture_image
*texImage
,
402 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
405 _fetch_texel_rgtc_u(texImage
->RowStride
, (GLubyte
*)(texImage
->Data
),
407 _fetch_texel_rgtc_u(texImage
->RowStride
, (GLubyte
*)(texImage
->Data
) + 8,
409 texel
[RCOMP
] = CHAN_TO_FLOAT(red
);
410 texel
[GCOMP
] = CHAN_TO_FLOAT(green
);
416 _mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct gl_texture_image
*texImage
,
417 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
420 _fetch_texel_rgtc_s(texImage
->RowStride
, (GLbyte
*)(texImage
->Data
),
422 _fetch_texel_rgtc_s(texImage
->RowStride
, (GLbyte
*)(texImage
->Data
) + 8,
424 texel
[RCOMP
] = BYTE_TO_FLOAT_TEX(red
);
425 texel
[GCOMP
] = BYTE_TO_FLOAT_TEX(green
);
430 static void write_rgtc_encoded_channel(GLubyte
*blkaddr
,
433 GLubyte alphaenc
[16])
435 *blkaddr
++ = alphabase1
;
436 *blkaddr
++ = alphabase2
;
437 *blkaddr
++ = alphaenc
[0] | (alphaenc
[1] << 3) | ((alphaenc
[2] & 3) << 6);
438 *blkaddr
++ = (alphaenc
[2] >> 2) | (alphaenc
[3] << 1) | (alphaenc
[4] << 4) | ((alphaenc
[5] & 1) << 7);
439 *blkaddr
++ = (alphaenc
[5] >> 1) | (alphaenc
[6] << 2) | (alphaenc
[7] << 5);
440 *blkaddr
++ = alphaenc
[8] | (alphaenc
[9] << 3) | ((alphaenc
[10] & 3) << 6);
441 *blkaddr
++ = (alphaenc
[10] >> 2) | (alphaenc
[11] << 1) | (alphaenc
[12] << 4) | ((alphaenc
[13] & 1) << 7);
442 *blkaddr
++ = (alphaenc
[13] >> 1) | (alphaenc
[14] << 2) | (alphaenc
[15] << 5);
445 static void encode_rgtc_chan_u(GLubyte
*blkaddr
, GLubyte srccolors
[4][4],
446 GLint numxpixels
, GLint numypixels
)
448 GLubyte alphabase
[2], alphause
[2];
449 GLshort alphatest
[2] = { 0 };
450 GLuint alphablockerror1
, alphablockerror2
, alphablockerror3
;
451 GLubyte i
, j
, aindex
, acutValues
[7];
452 GLubyte alphaenc1
[16], alphaenc2
[16], alphaenc3
[16];
453 GLboolean alphaabsmin
= GL_FALSE
;
454 GLboolean alphaabsmax
= GL_FALSE
;
457 /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */
458 alphabase
[0] = 0xff; alphabase
[1] = 0x0;
459 for (j
= 0; j
< numypixels
; j
++) {
460 for (i
= 0; i
< numxpixels
; i
++) {
461 if (srccolors
[j
][i
] == 0)
462 alphaabsmin
= GL_TRUE
;
463 else if (srccolors
[j
][i
] == 255)
464 alphaabsmax
= GL_TRUE
;
466 if (srccolors
[j
][i
] > alphabase
[1])
467 alphabase
[1] = srccolors
[j
][i
];
468 if (srccolors
[j
][i
] < alphabase
[0])
469 alphabase
[0] = srccolors
[j
][i
];
475 if ((alphabase
[0] > alphabase
[1]) && !(alphaabsmin
&& alphaabsmax
)) { /* one color, either max or min */
476 /* shortcut here since it is a very common case (and also avoids later problems) */
477 /* || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax) */
478 /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */
480 *blkaddr
++ = srccolors
[0][0];
489 fprintf(stderr
, "enc0 used\n");
494 /* find best encoding for alpha0 > alpha1 */
495 /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */
496 alphablockerror1
= 0x0;
497 alphablockerror2
= 0xffffffff;
498 alphablockerror3
= 0xffffffff;
499 if (alphaabsmin
) alphause
[0] = 0;
500 else alphause
[0] = alphabase
[0];
501 if (alphaabsmax
) alphause
[1] = 255;
502 else alphause
[1] = alphabase
[1];
503 /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */
504 for (aindex
= 0; aindex
< 7; aindex
++) {
505 /* don't forget here is always rounded down */
506 acutValues
[aindex
] = (alphause
[0] * (2*aindex
+ 1) + alphause
[1] * (14 - (2*aindex
+ 1))) / 14;
509 for (j
= 0; j
< numypixels
; j
++) {
510 for (i
= 0; i
< numxpixels
; i
++) {
511 /* maybe it's overkill to have the most complicated calculation just for the error
512 calculation which we only need to figure out if encoding1 or encoding2 is better... */
513 if (srccolors
[j
][i
] > acutValues
[0]) {
514 alphaenc1
[4*j
+ i
] = 0;
515 alphadist
= srccolors
[j
][i
] - alphause
[1];
517 else if (srccolors
[j
][i
] > acutValues
[1]) {
518 alphaenc1
[4*j
+ i
] = 2;
519 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 6 + alphause
[0] * 1) / 7;
521 else if (srccolors
[j
][i
] > acutValues
[2]) {
522 alphaenc1
[4*j
+ i
] = 3;
523 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 5 + alphause
[0] * 2) / 7;
525 else if (srccolors
[j
][i
] > acutValues
[3]) {
526 alphaenc1
[4*j
+ i
] = 4;
527 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 4 + alphause
[0] * 3) / 7;
529 else if (srccolors
[j
][i
] > acutValues
[4]) {
530 alphaenc1
[4*j
+ i
] = 5;
531 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 3 + alphause
[0] * 4) / 7;
533 else if (srccolors
[j
][i
] > acutValues
[5]) {
534 alphaenc1
[4*j
+ i
] = 6;
535 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 2 + alphause
[0] * 5) / 7;
537 else if (srccolors
[j
][i
] > acutValues
[6]) {
538 alphaenc1
[4*j
+ i
] = 7;
539 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 1 + alphause
[0] * 6) / 7;
542 alphaenc1
[4*j
+ i
] = 1;
543 alphadist
= srccolors
[j
][i
] - alphause
[0];
545 alphablockerror1
+= alphadist
* alphadist
;
550 for (i
= 0; i
< 16; i
++) {
551 fprintf(stderr
, "%d ", alphaenc1
[i
]);
553 fprintf(stderr
, "cutVals ");
554 for (i
= 0; i
< 8; i
++) {
555 fprintf(stderr
, "%d ", acutValues
[i
]);
557 fprintf(stderr
, "srcVals ");
558 for (j
= 0; j
< numypixels
; j
++) {
559 for (i
= 0; i
< numxpixels
; i
++) {
560 fprintf(stderr
, "%d ", srccolors
[j
][i
]);
563 fprintf(stderr
, "\n");
566 /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax
567 are false but try it anyway */
568 if (alphablockerror1
>= 32) {
570 /* don't bother if encoding is already very good, this condition should also imply
571 we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */
572 alphablockerror2
= 0;
573 for (aindex
= 0; aindex
< 5; aindex
++) {
574 /* don't forget here is always rounded down */
575 acutValues
[aindex
] = (alphabase
[0] * (10 - (2*aindex
+ 1)) + alphabase
[1] * (2*aindex
+ 1)) / 10;
577 for (j
= 0; j
< numypixels
; j
++) {
578 for (i
= 0; i
< numxpixels
; i
++) {
579 /* maybe it's overkill to have the most complicated calculation just for the error
580 calculation which we only need to figure out if encoding1 or encoding2 is better... */
581 if (srccolors
[j
][i
] == 0) {
582 alphaenc2
[4*j
+ i
] = 6;
585 else if (srccolors
[j
][i
] == 255) {
586 alphaenc2
[4*j
+ i
] = 7;
589 else if (srccolors
[j
][i
] <= acutValues
[0]) {
590 alphaenc2
[4*j
+ i
] = 0;
591 alphadist
= srccolors
[j
][i
] - alphabase
[0];
593 else if (srccolors
[j
][i
] <= acutValues
[1]) {
594 alphaenc2
[4*j
+ i
] = 2;
595 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 4 + alphabase
[1] * 1) / 5;
597 else if (srccolors
[j
][i
] <= acutValues
[2]) {
598 alphaenc2
[4*j
+ i
] = 3;
599 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 3 + alphabase
[1] * 2) / 5;
601 else if (srccolors
[j
][i
] <= acutValues
[3]) {
602 alphaenc2
[4*j
+ i
] = 4;
603 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 2 + alphabase
[1] * 3) / 5;
605 else if (srccolors
[j
][i
] <= acutValues
[4]) {
606 alphaenc2
[4*j
+ i
] = 5;
607 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 1 + alphabase
[1] * 4) / 5;
610 alphaenc2
[4*j
+ i
] = 1;
611 alphadist
= srccolors
[j
][i
] - alphabase
[1];
613 alphablockerror2
+= alphadist
* alphadist
;
618 /* skip this if the error is already very small
619 this encoding is MUCH better on average than #2 though, but expensive! */
620 if ((alphablockerror2
> 96) && (alphablockerror1
> 96)) {
621 GLshort blockerrlin1
= 0;
622 GLshort blockerrlin2
= 0;
623 GLubyte nralphainrangelow
= 0;
624 GLubyte nralphainrangehigh
= 0;
627 /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */
628 for (j
= 0; j
< numypixels
; j
++) {
629 for (i
= 0; i
< numxpixels
; i
++) {
630 if ((srccolors
[j
][i
] > alphatest
[1]) && (srccolors
[j
][i
] < (255 -(alphabase
[1] - alphabase
[0]) / 28)))
631 alphatest
[1] = srccolors
[j
][i
];
632 if ((srccolors
[j
][i
] < alphatest
[0]) && (srccolors
[j
][i
] > (alphabase
[1] - alphabase
[0]) / 28))
633 alphatest
[0] = srccolors
[j
][i
];
636 /* shouldn't happen too often, don't really care about those degenerated cases */
637 if (alphatest
[1] <= alphatest
[0]) {
641 for (aindex
= 0; aindex
< 5; aindex
++) {
642 /* don't forget here is always rounded down */
643 acutValues
[aindex
] = (alphatest
[0] * (10 - (2*aindex
+ 1)) + alphatest
[1] * (2*aindex
+ 1)) / 10;
646 /* find the "average" difference between the alpha values and the next encoded value.
647 This is then used to calculate new base values.
648 Should there be some weighting, i.e. those values closer to alphatest[x] have more weight,
649 since they will see more improvement, and also because the values in the middle are somewhat
650 likely to get no improvement at all (because the base values might move in different directions)?
651 OTOH it would mean the values in the middle are even less likely to get an improvement
653 for (j
= 0; j
< numypixels
; j
++) {
654 for (i
= 0; i
< numxpixels
; i
++) {
655 if (srccolors
[j
][i
] <= alphatest
[0] / 2) {
657 else if (srccolors
[j
][i
] > ((255 + alphatest
[1]) / 2)) {
659 else if (srccolors
[j
][i
] <= acutValues
[0]) {
660 blockerrlin1
+= (srccolors
[j
][i
] - alphatest
[0]);
661 nralphainrangelow
+= 1;
663 else if (srccolors
[j
][i
] <= acutValues
[1]) {
664 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 4 + alphatest
[1] * 1) / 5);
665 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 4 + alphatest
[1] * 1) / 5);
666 nralphainrangelow
+= 1;
667 nralphainrangehigh
+= 1;
669 else if (srccolors
[j
][i
] <= acutValues
[2]) {
670 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 3 + alphatest
[1] * 2) / 5);
671 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 3 + alphatest
[1] * 2) / 5);
672 nralphainrangelow
+= 1;
673 nralphainrangehigh
+= 1;
675 else if (srccolors
[j
][i
] <= acutValues
[3]) {
676 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 2 + alphatest
[1] * 3) / 5);
677 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 2 + alphatest
[1] * 3) / 5);
678 nralphainrangelow
+= 1;
679 nralphainrangehigh
+= 1;
681 else if (srccolors
[j
][i
] <= acutValues
[4]) {
682 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 1 + alphatest
[1] * 4) / 5);
683 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 1 + alphatest
[1] * 4) / 5);
684 nralphainrangelow
+= 1;
685 nralphainrangehigh
+= 1;
688 blockerrlin2
+= (srccolors
[j
][i
] - alphatest
[1]);
689 nralphainrangehigh
+= 1;
693 /* shouldn't happen often, needed to avoid div by zero */
694 if (nralphainrangelow
== 0) nralphainrangelow
= 1;
695 if (nralphainrangehigh
== 0) nralphainrangehigh
= 1;
696 alphatest
[0] = alphatest
[0] + (blockerrlin1
/ nralphainrangelow
);
698 fprintf(stderr
, "block err lin low %d, nr %d\n", blockerrlin1
, nralphainrangelow
);
699 fprintf(stderr
, "block err lin high %d, nr %d\n", blockerrlin2
, nralphainrangehigh
);
701 /* again shouldn't really happen often... */
702 if (alphatest
[0] < 0) {
705 alphatest
[1] = alphatest
[1] + (blockerrlin2
/ nralphainrangehigh
);
706 if (alphatest
[1] > 255) {
710 alphablockerror3
= 0;
711 for (aindex
= 0; aindex
< 5; aindex
++) {
712 /* don't forget here is always rounded down */
713 acutValues
[aindex
] = (alphatest
[0] * (10 - (2*aindex
+ 1)) + alphatest
[1] * (2*aindex
+ 1)) / 10;
715 for (j
= 0; j
< numypixels
; j
++) {
716 for (i
= 0; i
< numxpixels
; i
++) {
717 /* maybe it's overkill to have the most complicated calculation just for the error
718 calculation which we only need to figure out if encoding1 or encoding2 is better... */
719 if (srccolors
[j
][i
] <= alphatest
[0] / 2) {
720 alphaenc3
[4*j
+ i
] = 6;
721 alphadist
= srccolors
[j
][i
];
723 else if (srccolors
[j
][i
] > ((255 + alphatest
[1]) / 2)) {
724 alphaenc3
[4*j
+ i
] = 7;
725 alphadist
= 255 - srccolors
[j
][i
];
727 else if (srccolors
[j
][i
] <= acutValues
[0]) {
728 alphaenc3
[4*j
+ i
] = 0;
729 alphadist
= srccolors
[j
][i
] - alphatest
[0];
731 else if (srccolors
[j
][i
] <= acutValues
[1]) {
732 alphaenc3
[4*j
+ i
] = 2;
733 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 4 + alphatest
[1] * 1) / 5;
735 else if (srccolors
[j
][i
] <= acutValues
[2]) {
736 alphaenc3
[4*j
+ i
] = 3;
737 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 3 + alphatest
[1] * 2) / 5;
739 else if (srccolors
[j
][i
] <= acutValues
[3]) {
740 alphaenc3
[4*j
+ i
] = 4;
741 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 2 + alphatest
[1] * 3) / 5;
743 else if (srccolors
[j
][i
] <= acutValues
[4]) {
744 alphaenc3
[4*j
+ i
] = 5;
745 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 1 + alphatest
[1] * 4) / 5;
748 alphaenc3
[4*j
+ i
] = 1;
749 alphadist
= srccolors
[j
][i
] - alphatest
[1];
751 alphablockerror3
+= alphadist
* alphadist
;
756 /* write the alpha values and encoding back. */
757 if ((alphablockerror1
<= alphablockerror2
) && (alphablockerror1
<= alphablockerror3
)) {
759 if (alphablockerror1
> 96) fprintf(stderr
, "enc1 used, error %d\n", alphablockerror1
);
761 write_rgtc_encoded_channel( blkaddr
, alphause
[1], alphause
[0], alphaenc1
);
763 else if (alphablockerror2
<= alphablockerror3
) {
765 if (alphablockerror2
> 96) fprintf(stderr
, "enc2 used, error %d\n", alphablockerror2
);
767 write_rgtc_encoded_channel( blkaddr
, alphabase
[0], alphabase
[1], alphaenc2
);
771 fprintf(stderr
, "enc3 used, error %d\n", alphablockerror3
);
773 write_rgtc_encoded_channel( blkaddr
, (GLubyte
)alphatest
[0], (GLubyte
)alphatest
[1], alphaenc3
);
778 static void write_rgtc_encoded_channel_s(GLbyte
*blkaddr
,
783 *blkaddr
++ = alphabase1
;
784 *blkaddr
++ = alphabase2
;
785 *blkaddr
++ = alphaenc
[0] | (alphaenc
[1] << 3) | ((alphaenc
[2] & 3) << 6);
786 *blkaddr
++ = (alphaenc
[2] >> 2) | (alphaenc
[3] << 1) | (alphaenc
[4] << 4) | ((alphaenc
[5] & 1) << 7);
787 *blkaddr
++ = (alphaenc
[5] >> 1) | (alphaenc
[6] << 2) | (alphaenc
[7] << 5);
788 *blkaddr
++ = alphaenc
[8] | (alphaenc
[9] << 3) | ((alphaenc
[10] & 3) << 6);
789 *blkaddr
++ = (alphaenc
[10] >> 2) | (alphaenc
[11] << 1) | (alphaenc
[12] << 4) | ((alphaenc
[13] & 1) << 7);
790 *blkaddr
++ = (alphaenc
[13] >> 1) | (alphaenc
[14] << 2) | (alphaenc
[15] << 5);
793 static void encode_rgtc_chan_s(GLbyte
*blkaddr
, GLbyte srccolors
[4][4],
794 GLint numxpixels
, GLint numypixels
)
796 GLbyte alphabase
[2], alphause
[2];
797 GLshort alphatest
[2] = { 0 };
798 GLuint alphablockerror1
, alphablockerror2
, alphablockerror3
;
799 GLbyte i
, j
, aindex
, acutValues
[7];
800 GLbyte alphaenc1
[16], alphaenc2
[16], alphaenc3
[16];
801 GLboolean alphaabsmin
= GL_FALSE
;
802 GLboolean alphaabsmax
= GL_FALSE
;
805 /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */
806 alphabase
[0] = 0xff; alphabase
[1] = 0x0;
807 for (j
= 0; j
< numypixels
; j
++) {
808 for (i
= 0; i
< numxpixels
; i
++) {
809 if (srccolors
[j
][i
] == 0)
810 alphaabsmin
= GL_TRUE
;
811 else if (srccolors
[j
][i
] == 255)
812 alphaabsmax
= GL_TRUE
;
814 if (srccolors
[j
][i
] > alphabase
[1])
815 alphabase
[1] = srccolors
[j
][i
];
816 if (srccolors
[j
][i
] < alphabase
[0])
817 alphabase
[0] = srccolors
[j
][i
];
823 if ((alphabase
[0] > alphabase
[1]) && !(alphaabsmin
&& alphaabsmax
)) { /* one color, either max or min */
824 /* shortcut here since it is a very common case (and also avoids later problems) */
825 /* || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax) */
826 /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */
828 *blkaddr
++ = srccolors
[0][0];
837 fprintf(stderr
, "enc0 used\n");
842 /* find best encoding for alpha0 > alpha1 */
843 /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */
844 alphablockerror1
= 0x0;
845 alphablockerror2
= 0xffffffff;
846 alphablockerror3
= 0xffffffff;
847 if (alphaabsmin
) alphause
[0] = 0;
848 else alphause
[0] = alphabase
[0];
849 if (alphaabsmax
) alphause
[1] = 255;
850 else alphause
[1] = alphabase
[1];
851 /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */
852 for (aindex
= 0; aindex
< 7; aindex
++) {
853 /* don't forget here is always rounded down */
854 acutValues
[aindex
] = (alphause
[0] * (2*aindex
+ 1) + alphause
[1] * (14 - (2*aindex
+ 1))) / 14;
857 for (j
= 0; j
< numypixels
; j
++) {
858 for (i
= 0; i
< numxpixels
; i
++) {
859 /* maybe it's overkill to have the most complicated calculation just for the error
860 calculation which we only need to figure out if encoding1 or encoding2 is better... */
861 if (srccolors
[j
][i
] > acutValues
[0]) {
862 alphaenc1
[4*j
+ i
] = 0;
863 alphadist
= srccolors
[j
][i
] - alphause
[1];
865 else if (srccolors
[j
][i
] > acutValues
[1]) {
866 alphaenc1
[4*j
+ i
] = 2;
867 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 6 + alphause
[0] * 1) / 7;
869 else if (srccolors
[j
][i
] > acutValues
[2]) {
870 alphaenc1
[4*j
+ i
] = 3;
871 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 5 + alphause
[0] * 2) / 7;
873 else if (srccolors
[j
][i
] > acutValues
[3]) {
874 alphaenc1
[4*j
+ i
] = 4;
875 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 4 + alphause
[0] * 3) / 7;
877 else if (srccolors
[j
][i
] > acutValues
[4]) {
878 alphaenc1
[4*j
+ i
] = 5;
879 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 3 + alphause
[0] * 4) / 7;
881 else if (srccolors
[j
][i
] > acutValues
[5]) {
882 alphaenc1
[4*j
+ i
] = 6;
883 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 2 + alphause
[0] * 5) / 7;
885 else if (srccolors
[j
][i
] > acutValues
[6]) {
886 alphaenc1
[4*j
+ i
] = 7;
887 alphadist
= srccolors
[j
][i
] - (alphause
[1] * 1 + alphause
[0] * 6) / 7;
890 alphaenc1
[4*j
+ i
] = 1;
891 alphadist
= srccolors
[j
][i
] - alphause
[0];
893 alphablockerror1
+= alphadist
* alphadist
;
897 for (i
= 0; i
< 16; i
++) {
898 fprintf(stderr
, "%d ", alphaenc1
[i
]);
900 fprintf(stderr
, "cutVals ");
901 for (i
= 0; i
< 8; i
++) {
902 fprintf(stderr
, "%d ", acutValues
[i
]);
904 fprintf(stderr
, "srcVals ");
905 for (j
= 0; j
< numypixels
; j
++)
906 for (i
= 0; i
< numxpixels
; i
++) {
907 fprintf(stderr
, "%d ", srccolors
[j
][i
]);
910 fprintf(stderr
, "\n");
913 /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax
914 are false but try it anyway */
915 if (alphablockerror1
>= 32) {
917 /* don't bother if encoding is already very good, this condition should also imply
918 we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */
919 alphablockerror2
= 0;
920 for (aindex
= 0; aindex
< 5; aindex
++) {
921 /* don't forget here is always rounded down */
922 acutValues
[aindex
] = (alphabase
[0] * (10 - (2*aindex
+ 1)) + alphabase
[1] * (2*aindex
+ 1)) / 10;
924 for (j
= 0; j
< numypixels
; j
++) {
925 for (i
= 0; i
< numxpixels
; i
++) {
926 /* maybe it's overkill to have the most complicated calculation just for the error
927 calculation which we only need to figure out if encoding1 or encoding2 is better... */
928 if (srccolors
[j
][i
] == 0) {
929 alphaenc2
[4*j
+ i
] = 6;
932 else if (srccolors
[j
][i
] == 255) {
933 alphaenc2
[4*j
+ i
] = 7;
936 else if (srccolors
[j
][i
] <= acutValues
[0]) {
937 alphaenc2
[4*j
+ i
] = 0;
938 alphadist
= srccolors
[j
][i
] - alphabase
[0];
940 else if (srccolors
[j
][i
] <= acutValues
[1]) {
941 alphaenc2
[4*j
+ i
] = 2;
942 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 4 + alphabase
[1] * 1) / 5;
944 else if (srccolors
[j
][i
] <= acutValues
[2]) {
945 alphaenc2
[4*j
+ i
] = 3;
946 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 3 + alphabase
[1] * 2) / 5;
948 else if (srccolors
[j
][i
] <= acutValues
[3]) {
949 alphaenc2
[4*j
+ i
] = 4;
950 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 2 + alphabase
[1] * 3) / 5;
952 else if (srccolors
[j
][i
] <= acutValues
[4]) {
953 alphaenc2
[4*j
+ i
] = 5;
954 alphadist
= srccolors
[j
][i
] - (alphabase
[0] * 1 + alphabase
[1] * 4) / 5;
957 alphaenc2
[4*j
+ i
] = 1;
958 alphadist
= srccolors
[j
][i
] - alphabase
[1];
960 alphablockerror2
+= alphadist
* alphadist
;
965 /* skip this if the error is already very small
966 this encoding is MUCH better on average than #2 though, but expensive! */
967 if ((alphablockerror2
> 96) && (alphablockerror1
> 96)) {
968 GLshort blockerrlin1
= 0;
969 GLshort blockerrlin2
= 0;
970 GLubyte nralphainrangelow
= 0;
971 GLubyte nralphainrangehigh
= 0;
974 /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */
975 for (j
= 0; j
< numypixels
; j
++) {
976 for (i
= 0; i
< numxpixels
; i
++) {
977 if ((srccolors
[j
][i
] > alphatest
[1]) && (srccolors
[j
][i
] < (255 -(alphabase
[1] - alphabase
[0]) / 28)))
978 alphatest
[1] = srccolors
[j
][i
];
979 if ((srccolors
[j
][i
] < alphatest
[0]) && (srccolors
[j
][i
] > (alphabase
[1] - alphabase
[0]) / 28))
980 alphatest
[0] = srccolors
[j
][i
];
983 /* shouldn't happen too often, don't really care about those degenerated cases */
984 if (alphatest
[1] <= alphatest
[0]) {
988 for (aindex
= 0; aindex
< 5; aindex
++) {
989 /* don't forget here is always rounded down */
990 acutValues
[aindex
] = (alphatest
[0] * (10 - (2*aindex
+ 1)) + alphatest
[1] * (2*aindex
+ 1)) / 10;
993 /* find the "average" difference between the alpha values and the next encoded value.
994 This is then used to calculate new base values.
995 Should there be some weighting, i.e. those values closer to alphatest[x] have more weight,
996 since they will see more improvement, and also because the values in the middle are somewhat
997 likely to get no improvement at all (because the base values might move in different directions)?
998 OTOH it would mean the values in the middle are even less likely to get an improvement
1000 for (j
= 0; j
< numypixels
; j
++) {
1001 for (i
= 0; i
< numxpixels
; i
++) {
1002 if (srccolors
[j
][i
] <= alphatest
[0] / 2) {
1004 else if (srccolors
[j
][i
] > ((255 + alphatest
[1]) / 2)) {
1006 else if (srccolors
[j
][i
] <= acutValues
[0]) {
1007 blockerrlin1
+= (srccolors
[j
][i
] - alphatest
[0]);
1008 nralphainrangelow
+= 1;
1010 else if (srccolors
[j
][i
] <= acutValues
[1]) {
1011 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 4 + alphatest
[1] * 1) / 5);
1012 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 4 + alphatest
[1] * 1) / 5);
1013 nralphainrangelow
+= 1;
1014 nralphainrangehigh
+= 1;
1016 else if (srccolors
[j
][i
] <= acutValues
[2]) {
1017 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 3 + alphatest
[1] * 2) / 5);
1018 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 3 + alphatest
[1] * 2) / 5);
1019 nralphainrangelow
+= 1;
1020 nralphainrangehigh
+= 1;
1022 else if (srccolors
[j
][i
] <= acutValues
[3]) {
1023 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 2 + alphatest
[1] * 3) / 5);
1024 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 2 + alphatest
[1] * 3) / 5);
1025 nralphainrangelow
+= 1;
1026 nralphainrangehigh
+= 1;
1028 else if (srccolors
[j
][i
] <= acutValues
[4]) {
1029 blockerrlin1
+= (srccolors
[j
][i
] - (alphatest
[0] * 1 + alphatest
[1] * 4) / 5);
1030 blockerrlin2
+= (srccolors
[j
][i
] - (alphatest
[0] * 1 + alphatest
[1] * 4) / 5);
1031 nralphainrangelow
+= 1;
1032 nralphainrangehigh
+= 1;
1035 blockerrlin2
+= (srccolors
[j
][i
] - alphatest
[1]);
1036 nralphainrangehigh
+= 1;
1040 /* shouldn't happen often, needed to avoid div by zero */
1041 if (nralphainrangelow
== 0) nralphainrangelow
= 1;
1042 if (nralphainrangehigh
== 0) nralphainrangehigh
= 1;
1043 alphatest
[0] = alphatest
[0] + (blockerrlin1
/ nralphainrangelow
);
1045 fprintf(stderr
, "block err lin low %d, nr %d\n", blockerrlin1
, nralphainrangelow
);
1046 fprintf(stderr
, "block err lin high %d, nr %d\n", blockerrlin2
, nralphainrangehigh
);
1048 /* again shouldn't really happen often... */
1049 if (alphatest
[0] < 0) {
1052 alphatest
[1] = alphatest
[1] + (blockerrlin2
/ nralphainrangehigh
);
1053 if (alphatest
[1] > 255) {
1057 alphablockerror3
= 0;
1058 for (aindex
= 0; aindex
< 5; aindex
++) {
1059 /* don't forget here is always rounded down */
1060 acutValues
[aindex
] = (alphatest
[0] * (10 - (2*aindex
+ 1)) + alphatest
[1] * (2*aindex
+ 1)) / 10;
1062 for (j
= 0; j
< numypixels
; j
++) {
1063 for (i
= 0; i
< numxpixels
; i
++) {
1064 /* maybe it's overkill to have the most complicated calculation just for the error
1065 calculation which we only need to figure out if encoding1 or encoding2 is better... */
1066 if (srccolors
[j
][i
] <= alphatest
[0] / 2) {
1067 alphaenc3
[4*j
+ i
] = 6;
1068 alphadist
= srccolors
[j
][i
];
1070 else if (srccolors
[j
][i
] > ((255 + alphatest
[1]) / 2)) {
1071 alphaenc3
[4*j
+ i
] = 7;
1072 alphadist
= 255 - srccolors
[j
][i
];
1074 else if (srccolors
[j
][i
] <= acutValues
[0]) {
1075 alphaenc3
[4*j
+ i
] = 0;
1076 alphadist
= srccolors
[j
][i
] - alphatest
[0];
1078 else if (srccolors
[j
][i
] <= acutValues
[1]) {
1079 alphaenc3
[4*j
+ i
] = 2;
1080 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 4 + alphatest
[1] * 1) / 5;
1082 else if (srccolors
[j
][i
] <= acutValues
[2]) {
1083 alphaenc3
[4*j
+ i
] = 3;
1084 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 3 + alphatest
[1] * 2) / 5;
1086 else if (srccolors
[j
][i
] <= acutValues
[3]) {
1087 alphaenc3
[4*j
+ i
] = 4;
1088 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 2 + alphatest
[1] * 3) / 5;
1090 else if (srccolors
[j
][i
] <= acutValues
[4]) {
1091 alphaenc3
[4*j
+ i
] = 5;
1092 alphadist
= srccolors
[j
][i
] - (alphatest
[0] * 1 + alphatest
[1] * 4) / 5;
1095 alphaenc3
[4*j
+ i
] = 1;
1096 alphadist
= srccolors
[j
][i
] - alphatest
[1];
1098 alphablockerror3
+= alphadist
* alphadist
;
1103 /* write the alpha values and encoding back. */
1104 if ((alphablockerror1
<= alphablockerror2
) && (alphablockerror1
<= alphablockerror3
)) {
1106 if (alphablockerror1
> 96) fprintf(stderr
, "enc1 used, error %d\n", alphablockerror1
);
1108 write_rgtc_encoded_channel_s( blkaddr
, alphause
[1], alphause
[0], alphaenc1
);
1110 else if (alphablockerror2
<= alphablockerror3
) {
1112 if (alphablockerror2
> 96) fprintf(stderr
, "enc2 used, error %d\n", alphablockerror2
);
1114 write_rgtc_encoded_channel_s( blkaddr
, alphabase
[0], alphabase
[1], alphaenc2
);
1118 fprintf(stderr
, "enc3 used, error %d\n", alphablockerror3
);
1120 write_rgtc_encoded_channel_s( blkaddr
, (GLubyte
)alphatest
[0], (GLubyte
)alphatest
[1], alphaenc3
);