2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul 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 shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * \file texcompress_fxt1.c
28 * GL_EXT_texture_compression_fxt1 support.
38 #include "texcompress.h"
39 #include "texformat.h"
44 fxt1_encode (GLcontext
*ctx
,
45 unsigned int width
, unsigned int height
,
47 const void *source
, int srcRowStride
,
48 void *dest
, int destRowStride
);
50 fxt1_decode_1 (const void *texture
, int width
,
51 int i
, int j
, unsigned char *rgba
);
55 * Called during context initialization.
58 _mesa_init_texture_fxt1( GLcontext
*ctx
)
65 * Called via TexFormat->StoreImage to store an RGB_FXT1 texture.
68 texstore_rgb_fxt1(STORE_PARAMS
)
73 const GLint texWidth
= dstRowStride
* 8 / 16; /* a bit of a hack */
74 const GLchan
*tempImage
= NULL
;
76 ASSERT(dstFormat
== &_mesa_texformat_rgb_fxt1
);
77 ASSERT(dstXoffset
% 8 == 0);
78 ASSERT(dstYoffset
% 4 == 0);
79 ASSERT(dstZoffset
== 0);
80 (void) dstZoffset
; (void) dstImageStride
;
82 if (srcFormat
!= GL_RGB
||
83 srcType
!= CHAN_TYPE
||
84 ctx
->_ImageTransferState
||
85 srcPacking
->SwapBytes
) {
86 /* convert image to RGB/GLchan */
87 tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
89 dstFormat
->BaseFormat
,
90 srcWidth
, srcHeight
, srcDepth
,
91 srcFormat
, srcType
, srcAddr
,
94 return GL_FALSE
; /* out of memory */
95 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
97 srcRowStride
= 3 * srcWidth
;
101 pixels
= (const GLchan
*) srcAddr
;
102 srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
,
103 srcType
) / sizeof(GLchan
);
106 dst
= _mesa_compressed_image_address(dstXoffset
, dstYoffset
, 0,
107 GL_COMPRESSED_RGB_FXT1_3DFX
,
108 texWidth
, (GLubyte
*) dstAddr
);
110 fxt1_encode(ctx
, srcWidth
, srcHeight
, srcFormat
, pixels
, srcRowStride
,
114 _mesa_free((void*) tempImage
);
121 * Called via TexFormat->StoreImage to store an RGBA_FXT1 texture.
124 texstore_rgba_fxt1(STORE_PARAMS
)
126 const GLchan
*pixels
;
129 GLint texWidth
= dstRowStride
* 8 / 16; /* a bit of a hack */
130 const GLchan
*tempImage
= NULL
;
132 ASSERT(dstFormat
== &_mesa_texformat_rgba_fxt1
);
133 ASSERT(dstXoffset
% 8 == 0);
134 ASSERT(dstYoffset
% 4 == 0);
135 ASSERT(dstZoffset
== 0);
136 (void) dstZoffset
; (void) dstImageStride
;
138 if (srcFormat
!= GL_RGBA
||
139 srcType
!= CHAN_TYPE
||
140 ctx
->_ImageTransferState
||
141 srcPacking
->SwapBytes
) {
142 /* convert image to RGBA/GLchan */
143 tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
145 dstFormat
->BaseFormat
,
146 srcWidth
, srcHeight
, srcDepth
,
147 srcFormat
, srcType
, srcAddr
,
150 return GL_FALSE
; /* out of memory */
151 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
153 srcRowStride
= 4 * srcWidth
;
157 pixels
= (const GLchan
*) srcAddr
;
158 srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
,
159 srcType
) / sizeof(GLchan
);
162 dst
= _mesa_compressed_image_address(dstXoffset
, dstYoffset
, 0,
163 GL_COMPRESSED_RGBA_FXT1_3DFX
,
164 texWidth
, (GLubyte
*) dstAddr
);
166 fxt1_encode(ctx
, srcWidth
, srcHeight
, srcFormat
, pixels
, srcRowStride
,
170 _mesa_free((void*) tempImage
);
177 fetch_texel_2d_rgba_fxt1( const struct gl_texture_image
*texImage
,
178 GLint i
, GLint j
, GLint k
, GLchan
*texel
)
181 fxt1_decode_1(texImage
->Data
, texImage
->RowStride
, i
, j
, texel
);
186 fetch_texel_2d_f_rgba_fxt1( const struct gl_texture_image
*texImage
,
187 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
189 /* just sample as GLchan and convert to float here */
192 fxt1_decode_1(texImage
->Data
, texImage
->RowStride
, i
, j
, rgba
);
193 texel
[RCOMP
] = CHAN_TO_FLOAT(rgba
[RCOMP
]);
194 texel
[GCOMP
] = CHAN_TO_FLOAT(rgba
[GCOMP
]);
195 texel
[BCOMP
] = CHAN_TO_FLOAT(rgba
[BCOMP
]);
196 texel
[ACOMP
] = CHAN_TO_FLOAT(rgba
[ACOMP
]);
201 fetch_texel_2d_rgb_fxt1( const struct gl_texture_image
*texImage
,
202 GLint i
, GLint j
, GLint k
, GLchan
*texel
)
205 fxt1_decode_1(texImage
->Data
, texImage
->RowStride
, i
, j
, texel
);
211 fetch_texel_2d_f_rgb_fxt1( const struct gl_texture_image
*texImage
,
212 GLint i
, GLint j
, GLint k
, GLfloat
*texel
)
214 /* just sample as GLchan and convert to float here */
217 fxt1_decode_1(texImage
->Data
, texImage
->RowStride
, i
, j
, rgba
);
218 texel
[RCOMP
] = CHAN_TO_FLOAT(rgba
[RCOMP
]);
219 texel
[GCOMP
] = CHAN_TO_FLOAT(rgba
[GCOMP
]);
220 texel
[BCOMP
] = CHAN_TO_FLOAT(rgba
[BCOMP
]);
226 const struct gl_texture_format _mesa_texformat_rgb_fxt1
= {
227 MESA_FORMAT_RGB_FXT1
, /* MesaFormat */
228 GL_RGB
, /* BaseFormat */
229 GL_UNSIGNED_NORMALIZED_ARB
, /* DataType */
230 4, /*approx*/ /* RedBits */
231 4, /*approx*/ /* GreenBits */
232 4, /*approx*/ /* BlueBits */
234 0, /* LuminanceBits */
235 0, /* IntensityBits */
239 texstore_rgb_fxt1
, /* StoreTexImageFunc */
240 NULL
, /*impossible*/ /* FetchTexel1D */
241 fetch_texel_2d_rgb_fxt1
, /* FetchTexel2D */
242 NULL
, /*impossible*/ /* FetchTexel3D */
243 NULL
, /*impossible*/ /* FetchTexel1Df */
244 fetch_texel_2d_f_rgb_fxt1
, /* FetchTexel2Df */
245 NULL
, /*impossible*/ /* FetchTexel3Df */
248 const struct gl_texture_format _mesa_texformat_rgba_fxt1
= {
249 MESA_FORMAT_RGBA_FXT1
, /* MesaFormat */
250 GL_RGBA
, /* BaseFormat */
251 GL_UNSIGNED_NORMALIZED_ARB
, /* DataType */
252 4, /*approx*/ /* RedBits */
253 4, /*approx*/ /* GreenBits */
254 4, /*approx*/ /* BlueBits */
255 1, /*approx*/ /* AlphaBits */
256 0, /* LuminanceBits */
257 0, /* IntensityBits */
261 texstore_rgba_fxt1
, /* StoreTexImageFunc */
262 NULL
, /*impossible*/ /* FetchTexel1D */
263 fetch_texel_2d_rgba_fxt1
, /* FetchTexel2D */
264 NULL
, /*impossible*/ /* FetchTexel3D */
265 NULL
, /*impossible*/ /* FetchTexel1Df */
266 fetch_texel_2d_f_rgba_fxt1
, /* FetchTexel2Df */
267 NULL
, /*impossible*/ /* FetchTexel3Df */
271 /***************************************************************************\
274 * The encoder was built by reversing the decoder,
275 * and is vaguely based on Texus2 by 3dfx. Note that this code
276 * is merely a proof of concept, since it is higly UNoptimized;
277 * moreover, it is sub-optimal due to inital conditions passed
278 * to Lloyd's algorithm (the interpolation modes are worse).
279 \***************************************************************************/
282 #define MAX_COMP 4 /* ever needed maximum number of components in texel */
283 #define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
284 #define N_TEXELS 32 /* number of texels in a block (always 32) */
285 #define LL_N_REP 50 /* number of iterations in lloyd's vq */
286 #define LL_RMS_D 10 /* fault tolerance (maximum delta) */
287 #define LL_RMS_E 255 /* fault tolerance (maximum error) */
288 #define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */
289 #define ISTBLACK(v) (*((unsigned long *)(v)) == 0)
294 #define FX64_NATIVE 1
296 typedef unsigned long long Fx64
;
298 #define FX64_MOV32(a, b) a = b
299 #define FX64_OR32(a, b) a |= b
300 #define FX64_SHL(a, c) a <<= c
302 #else /* !__GNUC__ */
304 #define FX64_NATIVE 0
307 unsigned long lo
, hi
;
310 #define FX64_MOV32(a, b) a.lo = b
311 #define FX64_OR32(a, b) a.lo |= b
313 #define FX64_SHL(a, c) \
316 a.hi = a.lo << ((c) - 32); \
319 a.hi = (a.hi << (c)) | (a.lo >> (32 - (c))); \
324 #endif /* !__GNUC__ */
328 fxt1_bestcol (float vec
[][MAX_COMP
], int nv
,
329 unsigned char input
[MAX_COMP
], int nc
)
332 float err
= 1e9
; /* big enough */
334 for (j
= 0; j
< nv
; j
++) {
336 for (i
= 0; i
< nc
; i
++) {
337 e
+= (vec
[j
][i
] - input
[i
]) * (vec
[j
][i
] - input
[i
]);
350 fxt1_worst (float vec
[MAX_COMP
],
351 unsigned char input
[N_TEXELS
][MAX_COMP
], int nc
, int n
)
353 int i
, k
, worst
= -1;
354 float err
= -1; /* small enough */
356 for (k
= 0; k
< n
; k
++) {
358 for (i
= 0; i
< nc
; i
++) {
359 e
+= (vec
[i
] - input
[k
][i
]) * (vec
[i
] - input
[k
][i
]);
372 fxt1_variance (double variance
[MAX_COMP
],
373 unsigned char input
[N_TEXELS
][MAX_COMP
], int nc
, int n
)
377 double var
, maxvar
= -1; /* small enough */
378 double teenth
= 1.0 / n
;
380 for (i
= 0; i
< nc
; i
++) {
382 for (k
= 0; k
< n
; k
++) {
387 var
= sx2
* teenth
- sx
* sx
* teenth
* teenth
;
402 fxt1_choose (float vec
[][MAX_COMP
], int nv
,
403 unsigned char input
[N_TEXELS
][MAX_COMP
], int nc
, int n
)
406 /* Choose colors from a grid.
410 for (j
= 0; j
< nv
; j
++) {
411 int m
= j
* (n
- 1) / (nv
- 1);
412 for (i
= 0; i
< nc
; i
++) {
413 vec
[j
][i
] = input
[m
][i
];
417 /* Our solution here is to find the darkest and brightest colors in
418 * the 8x4 tile and use those as the two representative colors.
419 * There are probably better algorithms to use (histogram-based).
422 int minSum
= 1000; /* big enough */
423 int maxSum
= -1; /* small enough */
424 int minCol
= 0; /* phoudoin: silent compiler! */
425 int maxCol
= 0; /* phoudoin: silent compiler! */
435 memset(hist
, 0, sizeof(hist
));
437 for (k
= 0; k
< n
; k
++) {
441 for (i
= 0; i
< nc
; i
++) {
446 for (l
= 0; l
< n
; l
++) {
455 } else if (hist
[l
].key
== key
) {
471 for (j
= 0; j
< lenh
; j
++) {
472 for (i
= 0; i
< nc
; i
++) {
473 vec
[j
][i
] = (float)input
[hist
[j
].idx
][i
];
476 for (; j
< nv
; j
++) {
477 for (i
= 0; i
< nc
; i
++) {
478 vec
[j
][i
] = vec
[0][i
];
484 for (j
= 0; j
< nv
; j
++) {
485 for (i
= 0; i
< nc
; i
++) {
486 vec
[j
][i
] = ((nv
- 1 - j
) * input
[minCol
][i
] + j
* input
[maxCol
][i
] + (nv
- 1) / 2) / (nv
- 1);
496 fxt1_lloyd (float vec
[][MAX_COMP
], int nv
,
497 unsigned char input
[N_TEXELS
][MAX_COMP
], int nc
, int n
)
499 /* Use the generalized lloyd's algorithm for VQ:
500 * find 4 color vectors.
502 * for each sample color
503 * sort to nearest vector.
505 * replace each vector with the centroid of it's matching colors.
507 * repeat until RMS doesn't improve.
509 * if a color vector has no samples, or becomes the same as another
510 * vector, replace it with the color which is farthest from a sample.
512 * vec[][MAX_COMP] initial vectors and resulting colors
513 * nv number of resulting colors required
514 * input[N_TEXELS][MAX_COMP] input texels
515 * nc number of components in input / vec
516 * n number of input samples
519 int sum
[MAX_VECT
][MAX_COMP
]; /* used to accumulate closest texels */
520 int cnt
[MAX_VECT
]; /* how many times a certain vector was chosen */
521 float error
, lasterror
= 1e9
;
526 for (rep
= 0; rep
< LL_N_REP
; rep
++) {
527 /* reset sums & counters */
528 for (j
= 0; j
< nv
; j
++) {
529 for (i
= 0; i
< nc
; i
++) {
536 /* scan whole block */
537 for (k
= 0; k
< n
; k
++) {
540 float err
= 1e9
; /* big enough */
541 /* determine best vector */
542 for (j
= 0; j
< nv
; j
++) {
543 float e
= (vec
[j
][0] - input
[k
][0]) * (vec
[j
][0] - input
[k
][0]) +
544 (vec
[j
][1] - input
[k
][1]) * (vec
[j
][1] - input
[k
][1]) +
545 (vec
[j
][2] - input
[k
][2]) * (vec
[j
][2] - input
[k
][2]);
547 e
+= (vec
[j
][3] - input
[k
][3]) * (vec
[j
][3] - input
[k
][3]);
555 int best
= fxt1_bestcol(vec
, n_vect
, input
[k
], n_comp
, &err
);
557 /* add in closest color */
558 for (i
= 0; i
< nc
; i
++) {
559 sum
[best
][i
] += input
[k
][i
];
561 /* mark this vector as used */
563 /* accumulate error */
568 if ((error
< LL_RMS_E
) ||
569 ((error
< lasterror
) && ((lasterror
- error
) < LL_RMS_D
))) {
570 return !0; /* good match */
574 /* move each vector to the barycenter of its closest colors */
575 for (j
= 0; j
< nv
; j
++) {
577 float div
= 1.0 / cnt
[j
];
578 for (i
= 0; i
< nc
; i
++) {
579 vec
[j
][i
] = div
* sum
[j
][i
];
582 /* this vec has no samples or is identical with a previous vec */
583 int worst
= fxt1_worst(vec
[j
], input
, nc
, n
);
584 for (i
= 0; i
< nc
; i
++) {
585 vec
[j
][i
] = input
[worst
][i
];
591 return 0; /* could not converge fast enough */
596 fxt1_quantize_CHROMA (unsigned long *cc
,
597 unsigned char input
[N_TEXELS
][MAX_COMP
])
599 const int n_vect
= 4; /* 4 base vectors to find */
600 const int n_comp
= 3; /* 3 components: R, G, B */
601 float vec
[MAX_VECT
][MAX_COMP
];
603 Fx64 hi
; /* high quadword */
604 unsigned long lohi
, lolo
; /* low quadword: hi dword, lo dword */
606 if (fxt1_choose(vec
, n_vect
, input
, n_comp
, N_TEXELS
) != 0) {
607 fxt1_lloyd(vec
, n_vect
, input
, n_comp
, N_TEXELS
);
610 FX64_MOV32(hi
, 4); /* cc-chroma = "010" + unused bit */
611 for (j
= n_vect
- 1; j
>= 0; j
--) {
612 for (i
= 0; i
< n_comp
; i
++) {
615 FX64_OR32(hi
, (unsigned int)(vec
[j
][i
] / 8.0));
618 ((Fx64
*)cc
)[1] = hi
;
621 /* right microtile */
622 for (k
= N_TEXELS
- 1; k
>= N_TEXELS
/2; k
--) {
624 lohi
|= fxt1_bestcol(vec
, n_vect
, input
[k
], n_comp
);
627 for (; k
>= 0; k
--) {
629 lolo
|= fxt1_bestcol(vec
, n_vect
, input
[k
], n_comp
);
637 fxt1_quantize_ALPHA0 (unsigned long *cc
,
638 unsigned char input
[N_TEXELS
][MAX_COMP
],
639 unsigned char reord
[N_TEXELS
][MAX_COMP
], int n
)
641 const int n_vect
= 3; /* 3 base vectors to find */
642 const int n_comp
= 4; /* 4 components: R, G, B, A */
643 float vec
[MAX_VECT
][MAX_COMP
];
645 Fx64 hi
; /* high quadword */
646 unsigned long lohi
, lolo
; /* low quadword: hi dword, lo dword */
648 /* the last vector indicates zero */
649 for (i
= 0; i
< n_comp
; i
++) {
653 /* the first n texels in reord are guaranteed to be non-zero */
654 if (fxt1_choose(vec
, n_vect
, reord
, n_comp
, n
) != 0) {
655 fxt1_lloyd(vec
, n_vect
, reord
, n_comp
, n
);
658 FX64_MOV32(hi
, 6); /* alpha = "011" + lerp = 0 */
659 for (j
= n_vect
- 1; j
>= 0; j
--) {
662 FX64_OR32(hi
, (unsigned int)(vec
[j
][ACOMP
] / 8.0));
664 for (j
= n_vect
- 1; j
>= 0; j
--) {
665 for (i
= 0; i
< n_comp
- 1; i
++) {
668 FX64_OR32(hi
, (unsigned int)(vec
[j
][i
] / 8.0));
671 ((Fx64
*)cc
)[1] = hi
;
674 /* right microtile */
675 for (k
= N_TEXELS
- 1; k
>= N_TEXELS
/2; k
--) {
677 lohi
|= fxt1_bestcol(vec
, n_vect
+ 1, input
[k
], n_comp
);
680 for (; k
>= 0; k
--) {
682 lolo
|= fxt1_bestcol(vec
, n_vect
+ 1, input
[k
], n_comp
);
690 fxt1_quantize_ALPHA1 (unsigned long *cc
,
691 unsigned char input
[N_TEXELS
][MAX_COMP
])
693 const int n_vect
= 3; /* highest vector number in each microtile */
694 const int n_comp
= 4; /* 4 components: R, G, B, A */
695 float vec
[1 + 1 + 1][MAX_COMP
]; /* 1.5 extrema for each sub-block */
696 float b
, iv
[MAX_COMP
]; /* interpolation vector */
698 Fx64 hi
; /* high quadword */
699 unsigned long lohi
, lolo
; /* low quadword: hi dword, lo dword */
703 int minColL
= 0, maxColL
= 0;
704 int minColR
= 0, maxColR
= 0;
705 int sumL
= 0, sumR
= 0;
707 /* Our solution here is to find the darkest and brightest colors in
708 * the 4x4 tile and use those as the two representative colors.
709 * There are probably better algorithms to use (histogram-based).
711 minSum
= 1000; /* big enough */
712 maxSum
= -1; /* small enough */
713 for (k
= 0; k
< N_TEXELS
/ 2; k
++) {
715 for (i
= 0; i
< n_comp
; i
++) {
728 minSum
= 1000; /* big enough */
729 maxSum
= -1; /* small enough */
730 for (; k
< N_TEXELS
; k
++) {
732 for (i
= 0; i
< n_comp
; i
++) {
746 /* choose the common vector (yuck!) */
750 float err
= 1e9
; /* big enough */
751 float tv
[2 * 2][MAX_COMP
]; /* 2 extrema for each sub-block */
752 for (i
= 0; i
< n_comp
; i
++) {
753 tv
[0][i
] = input
[minColL
][i
];
754 tv
[1][i
] = input
[maxColL
][i
];
755 tv
[2][i
] = input
[minColR
][i
];
756 tv
[3][i
] = input
[maxColR
][i
];
758 for (j1
= 0; j1
< 2; j1
++) {
759 for (j2
= 2; j2
< 4; j2
++) {
761 for (i
= 0; i
< n_comp
; i
++) {
762 e
+= (tv
[j1
][i
] - tv
[j2
][i
]) * (tv
[j1
][i
] - tv
[j2
][i
]);
771 for (i
= 0; i
< n_comp
; i
++) {
772 vec
[0][i
] = tv
[1 - v1
][i
];
773 vec
[1][i
] = (tv
[v1
][i
] * sumL
+ tv
[v2
][i
] * sumR
) / (sumL
+ sumR
);
774 vec
[2][i
] = tv
[5 - v2
][i
];
780 if (minColL
!= maxColL
) {
781 /* compute interpolation vector */
785 for (i
= 0; i
< n_comp
; i
++) {
786 iv
[i
] = vec
[1][i
] - vec
[0][i
];
789 rd2
= (float)n_vect
/ d2
;
791 for (i
= 0; i
< n_comp
; i
++) {
792 b
-= iv
[i
] * vec
[0][i
];
799 for (k
= N_TEXELS
/ 2 - 1; k
>= 0; k
--) {
801 /* interpolate color */
803 for (i
= 0; i
< n_comp
; i
++) {
804 dot
+= input
[k
][i
] * iv
[i
];
806 texel
= (int)(dot
+ b
);
809 } else if (texel
> n_vect
) {
820 /* right microtile */
822 if (minColR
!= maxColR
) {
823 /* compute interpolation vector */
827 for (i
= 0; i
< n_comp
; i
++) {
828 iv
[i
] = vec
[1][i
] - vec
[2][i
];
831 rd2
= (float)n_vect
/ d2
;
833 for (i
= 0; i
< n_comp
; i
++) {
834 b
-= iv
[i
] * vec
[2][i
];
841 for (k
= N_TEXELS
- 1; k
>= N_TEXELS
/ 2; k
--) {
843 /* interpolate color */
845 for (i
= 0; i
< n_comp
; i
++) {
846 dot
+= input
[k
][i
] * iv
[i
];
848 texel
= (int)(dot
+ b
);
851 } else if (texel
> n_vect
) {
862 FX64_MOV32(hi
, 7); /* alpha = "011" + lerp = 1 */
863 for (j
= n_vect
- 1; j
>= 0; j
--) {
866 FX64_OR32(hi
, (unsigned int)(vec
[j
][ACOMP
] / 8.0));
868 for (j
= n_vect
- 1; j
>= 0; j
--) {
869 for (i
= 0; i
< n_comp
- 1; i
++) {
872 FX64_OR32(hi
, (unsigned int)(vec
[j
][i
] / 8.0));
875 ((Fx64
*)cc
)[1] = hi
;
880 fxt1_quantize_HI (unsigned long *cc
,
881 unsigned char input
[N_TEXELS
][MAX_COMP
],
882 unsigned char reord
[N_TEXELS
][MAX_COMP
], int n
)
884 const int n_vect
= 6; /* highest vector number */
885 const int n_comp
= 3; /* 3 components: R, G, B */
886 float b
= 0.0; /* phoudoin: silent compiler! */
887 float iv
[MAX_COMP
]; /* interpolation vector */
889 unsigned long hihi
; /* high quadword: hi dword */
891 int minSum
= 1000; /* big enough */
892 int maxSum
= -1; /* small enough */
893 int minCol
= 0; /* phoudoin: silent compiler! */
894 int maxCol
= 0; /* phoudoin: silent compiler! */
896 /* Our solution here is to find the darkest and brightest colors in
897 * the 8x4 tile and use those as the two representative colors.
898 * There are probably better algorithms to use (histogram-based).
900 for (k
= 0; k
< n
; k
++) {
902 for (i
= 0; i
< n_comp
; i
++) {
915 hihi
= 0; /* cc-hi = "00" */
916 for (i
= 0; i
< n_comp
; i
++) {
919 hihi
|= reord
[maxCol
][i
] >> 3;
921 for (i
= 0; i
< n_comp
; i
++) {
924 hihi
|= reord
[minCol
][i
] >> 3;
927 cc
[0] = cc
[1] = cc
[2] = 0;
929 /* compute interpolation vector */
930 if (minCol
!= maxCol
) {
934 for (i
= 0; i
< n_comp
; i
++) {
935 iv
[i
] = reord
[maxCol
][i
] - reord
[minCol
][i
];
938 rd2
= (float)n_vect
/ d2
;
940 for (i
= 0; i
< n_comp
; i
++) {
941 b
-= iv
[i
] * reord
[minCol
][i
];
948 for (k
= N_TEXELS
- 1; k
>= 0; k
--) {
950 unsigned long *kk
= (unsigned long *)((unsigned long)cc
+ t
/ 8);
951 int texel
= n_vect
+ 1; /* transparent black */
953 if (!ISTBLACK(input
[k
])) {
954 if (minCol
!= maxCol
) {
955 /* interpolate color */
957 for (i
= 0; i
< n_comp
; i
++) {
958 dot
+= input
[k
][i
] * iv
[i
];
960 texel
= (int)(dot
+ b
);
963 } else if (texel
> n_vect
) {
967 kk
[0] |= texel
<< (t
& 7);
971 kk
[0] |= texel
<< (t
& 7);
978 fxt1_quantize_MIXED1 (unsigned long *cc
,
979 unsigned char input
[N_TEXELS
][MAX_COMP
])
981 const int n_vect
= 2; /* highest vector number in each microtile */
982 const int n_comp
= 3; /* 3 components: R, G, B */
983 unsigned char vec
[2 * 2][MAX_COMP
]; /* 2 extrema for each sub-block */
984 float b
, iv
[MAX_COMP
]; /* interpolation vector */
986 Fx64 hi
; /* high quadword */
987 unsigned long lohi
, lolo
; /* low quadword: hi dword, lo dword */
991 int minColL
= 0, maxColL
= -1;
992 int minColR
= 0, maxColR
= -1;
994 /* Our solution here is to find the darkest and brightest colors in
995 * the 4x4 tile and use those as the two representative colors.
996 * There are probably better algorithms to use (histogram-based).
998 minSum
= 1000; /* big enough */
999 maxSum
= -1; /* small enough */
1000 for (k
= 0; k
< N_TEXELS
/ 2; k
++) {
1001 if (!ISTBLACK(input
[k
])) {
1003 for (i
= 0; i
< n_comp
; i
++) {
1016 minSum
= 1000; /* big enough */
1017 maxSum
= -1; /* small enough */
1018 for (; k
< N_TEXELS
; k
++) {
1019 if (!ISTBLACK(input
[k
])) {
1021 for (i
= 0; i
< n_comp
; i
++) {
1035 /* left microtile */
1036 if (maxColL
== -1) {
1037 /* all transparent black */
1039 for (i
= 0; i
< n_comp
; i
++) {
1045 for (i
= 0; i
< n_comp
; i
++) {
1046 vec
[0][i
] = input
[minColL
][i
];
1047 vec
[1][i
] = input
[maxColL
][i
];
1049 if (minColL
!= maxColL
) {
1050 /* compute interpolation vector */
1054 for (i
= 0; i
< n_comp
; i
++) {
1055 iv
[i
] = vec
[1][i
] - vec
[0][i
];
1056 d2
+= iv
[i
] * iv
[i
];
1058 rd2
= (float)n_vect
/ d2
;
1060 for (i
= 0; i
< n_comp
; i
++) {
1061 b
-= iv
[i
] * vec
[0][i
];
1068 for (k
= N_TEXELS
/ 2 - 1; k
>= 0; k
--) {
1069 int texel
= n_vect
+ 1; /* transparent black */
1070 if (!ISTBLACK(input
[k
])) {
1071 /* interpolate color */
1073 for (i
= 0; i
< n_comp
; i
++) {
1074 dot
+= input
[k
][i
] * iv
[i
];
1076 texel
= (int)(dot
+ b
);
1079 } else if (texel
> n_vect
) {
1091 /* right microtile */
1092 if (maxColR
== -1) {
1093 /* all transparent black */
1095 for (i
= 0; i
< n_comp
; i
++) {
1101 for (i
= 0; i
< n_comp
; i
++) {
1102 vec
[2][i
] = input
[minColR
][i
];
1103 vec
[3][i
] = input
[maxColR
][i
];
1105 if (minColR
!= maxColR
) {
1106 /* compute interpolation vector */
1110 for (i
= 0; i
< n_comp
; i
++) {
1111 iv
[i
] = vec
[3][i
] - vec
[2][i
];
1112 d2
+= iv
[i
] * iv
[i
];
1114 rd2
= (float)n_vect
/ d2
;
1116 for (i
= 0; i
< n_comp
; i
++) {
1117 b
-= iv
[i
] * vec
[2][i
];
1124 for (k
= N_TEXELS
- 1; k
>= N_TEXELS
/ 2; k
--) {
1125 int texel
= n_vect
+ 1; /* transparent black */
1126 if (!ISTBLACK(input
[k
])) {
1127 /* interpolate color */
1129 for (i
= 0; i
< n_comp
; i
++) {
1130 dot
+= input
[k
][i
] * iv
[i
];
1132 texel
= (int)(dot
+ b
);
1135 } else if (texel
> n_vect
) {
1147 FX64_MOV32(hi
, 9 | (vec
[3][GCOMP
] & 4) | ((vec
[1][GCOMP
] >> 1) & 2)); /* chroma = "1" */
1148 for (j
= 2 * 2 - 1; j
>= 0; j
--) {
1149 for (i
= 0; i
< n_comp
; i
++) {
1152 FX64_OR32(hi
, vec
[j
][i
] >> 3);
1155 ((Fx64
*)cc
)[1] = hi
;
1160 fxt1_quantize_MIXED0 (unsigned long *cc
,
1161 unsigned char input
[N_TEXELS
][MAX_COMP
])
1163 const int n_vect
= 3; /* highest vector number in each microtile */
1164 const int n_comp
= 3; /* 3 components: R, G, B */
1165 unsigned char vec
[2 * 2][MAX_COMP
]; /* 2 extrema for each sub-block */
1166 float b
, iv
[MAX_COMP
]; /* interpolation vector */
1168 Fx64 hi
; /* high quadword */
1169 unsigned long lohi
, lolo
; /* low quadword: hi dword, lo dword */
1171 int minColL
= 0, maxColL
= 0;
1172 int minColR
= 0, maxColR
= 0;
1177 /* Our solution here is to find the darkest and brightest colors in
1178 * the 4x4 tile and use those as the two representative colors.
1179 * There are probably better algorithms to use (histogram-based).
1181 minSum
= 1000; /* big enough */
1182 maxSum
= -1; /* small enough */
1183 for (k
= 0; k
< N_TEXELS
/ 2; k
++) {
1185 for (i
= 0; i
< n_comp
; i
++) {
1197 minSum
= 1000; /* big enough */
1198 maxSum
= -1; /* small enough */
1199 for (; k
< N_TEXELS
; k
++) {
1201 for (i
= 0; i
< n_comp
; i
++) {
1216 int maxVarL
= fxt1_variance(NULL
, input
, n_comp
, N_TEXELS
/ 2);
1217 int maxVarR
= fxt1_variance(NULL
, &input
[N_TEXELS
/ 2], n_comp
, N_TEXELS
/ 2);
1219 /* Scan the channel with max variance for lo & hi
1220 * and use those as the two representative colors.
1222 minVal
= 1000; /* big enough */
1223 maxVal
= -1; /* small enough */
1224 for (k
= 0; k
< N_TEXELS
/ 2; k
++) {
1225 int t
= input
[k
][maxVarL
];
1235 minVal
= 1000; /* big enough */
1236 maxVal
= -1; /* small enough */
1237 for (; k
< N_TEXELS
; k
++) {
1238 int t
= input
[k
][maxVarR
];
1250 /* left microtile */
1252 for (i
= 0; i
< n_comp
; i
++) {
1253 vec
[0][i
] = input
[minColL
][i
];
1254 vec
[1][i
] = input
[maxColL
][i
];
1256 if (minColL
!= maxColL
) {
1257 /* compute interpolation vector */
1261 for (i
= 0; i
< n_comp
; i
++) {
1262 iv
[i
] = vec
[1][i
] - vec
[0][i
];
1263 d2
+= iv
[i
] * iv
[i
];
1265 rd2
= (float)n_vect
/ d2
;
1267 for (i
= 0; i
< n_comp
; i
++) {
1268 b
-= iv
[i
] * vec
[0][i
];
1275 for (k
= N_TEXELS
/ 2 - 1; k
>= 0; k
--) {
1277 /* interpolate color */
1279 for (i
= 0; i
< n_comp
; i
++) {
1280 dot
+= input
[k
][i
] * iv
[i
];
1282 texel
= (int)(dot
+ b
);
1285 } else if (texel
> n_vect
) {
1293 /* funky encoding for LSB of green */
1294 if ((int)((lolo
>> 1) & 1) != (((vec
[1][GCOMP
] ^ vec
[0][GCOMP
]) >> 2) & 1)) {
1295 for (i
= 0; i
< n_comp
; i
++) {
1296 vec
[1][i
] = input
[minColL
][i
];
1297 vec
[0][i
] = input
[maxColL
][i
];
1305 /* right microtile */
1307 for (i
= 0; i
< n_comp
; i
++) {
1308 vec
[2][i
] = input
[minColR
][i
];
1309 vec
[3][i
] = input
[maxColR
][i
];
1311 if (minColR
!= maxColR
) {
1312 /* compute interpolation vector */
1316 for (i
= 0; i
< n_comp
; i
++) {
1317 iv
[i
] = vec
[3][i
] - vec
[2][i
];
1318 d2
+= iv
[i
] * iv
[i
];
1320 rd2
= (float)n_vect
/ d2
;
1322 for (i
= 0; i
< n_comp
; i
++) {
1323 b
-= iv
[i
] * vec
[2][i
];
1330 for (k
= N_TEXELS
- 1; k
>= N_TEXELS
/ 2; k
--) {
1332 /* interpolate color */
1334 for (i
= 0; i
< n_comp
; i
++) {
1335 dot
+= input
[k
][i
] * iv
[i
];
1337 texel
= (int)(dot
+ b
);
1340 } else if (texel
> n_vect
) {
1348 /* funky encoding for LSB of green */
1349 if ((int)((lohi
>> 1) & 1) != (((vec
[3][GCOMP
] ^ vec
[2][GCOMP
]) >> 2) & 1)) {
1350 for (i
= 0; i
< n_comp
; i
++) {
1351 vec
[3][i
] = input
[minColR
][i
];
1352 vec
[2][i
] = input
[maxColR
][i
];
1360 FX64_MOV32(hi
, 8 | (vec
[3][GCOMP
] & 4) | ((vec
[1][GCOMP
] >> 1) & 2)); /* chroma = "1" */
1361 for (j
= 2 * 2 - 1; j
>= 0; j
--) {
1362 for (i
= 0; i
< n_comp
; i
++) {
1365 FX64_OR32(hi
, vec
[j
][i
] >> 3);
1368 ((Fx64
*)cc
)[1] = hi
;
1373 fxt1_quantize (unsigned long *cc
, const unsigned char *lines
[], int comps
)
1376 unsigned char reord
[N_TEXELS
][MAX_COMP
];
1378 unsigned char input
[N_TEXELS
][MAX_COMP
];
1381 memset(input
, -1, sizeof(input
));
1383 /* 8 texels each line */
1384 for (l
= 0; l
< 4; l
++) {
1385 for (k
= 0; k
< 4; k
++) {
1386 for (i
= 0; i
< comps
; i
++) {
1387 input
[k
+ l
* 4][i
] = *lines
[l
]++;
1390 for (; k
< 8; k
++) {
1391 for (i
= 0; i
< comps
; i
++) {
1392 input
[k
+ l
* 4 + 12][i
] = *lines
[l
]++;
1398 * 00, 01, 02, 03, 08, 09, 0a, 0b
1399 * 10, 11, 12, 13, 18, 19, 1a, 1b
1400 * 04, 05, 06, 07, 0c, 0d, 0e, 0f
1401 * 14, 15, 16, 17, 1c, 1d, 1e, 1f
1405 * stupidity flows forth from this
1410 /* skip all transparent black texels */
1412 for (k
= 0; k
< N_TEXELS
; k
++) {
1413 /* test all components against 0 */
1414 if (!ISTBLACK(input
[k
])) {
1415 /* texel is not transparent black */
1416 COPY_4UBV(reord
[l
], input
[k
]);
1417 if (reord
[l
][ACOMP
] < (255 - ALPHA_TS
)) {
1418 /* non-opaque texel */
1428 fxt1_quantize_ALPHA0(cc
, input
, reord
, l
);
1429 } else if (l
== 0) {
1430 cc
[0] = cc
[1] = cc
[2] = -1;
1432 } else if (l
< N_TEXELS
) {
1433 fxt1_quantize_HI(cc
, input
, reord
, l
);
1435 fxt1_quantize_CHROMA(cc
, input
);
1437 (void)fxt1_quantize_ALPHA1
;
1438 (void)fxt1_quantize_MIXED1
;
1439 (void)fxt1_quantize_MIXED0
;
1442 fxt1_quantize_ALPHA1(cc
, input
);
1443 } else if (l
== 0) {
1444 cc
[0] = cc
[1] = cc
[2] = -1;
1446 } else if (l
< N_TEXELS
) {
1447 fxt1_quantize_MIXED1(cc
, input
);
1449 fxt1_quantize_MIXED0(cc
, input
);
1451 (void)fxt1_quantize_ALPHA0
;
1452 (void)fxt1_quantize_HI
;
1453 (void)fxt1_quantize_CHROMA
;
1459 fxt1_encode (GLcontext
*ctx
,
1460 unsigned int width
, unsigned int height
,
1462 const void *source
, int srcRowStride
,
1463 void *dest
, int destRowStride
)
1465 const int comps
= (srcFormat
== GL_RGB
) ? 3 : 4;
1467 const unsigned char *data
;
1468 unsigned long *encoded
= dest
;
1469 GLubyte
*newSource
= NULL
;
1474 * Rescale image if width is less than 8 or height is less than 4.
1476 if (width
< 8 || height
< 4) {
1477 GLint newWidth
= (width
+ 7) & ~7;
1478 GLint newHeight
= (height
+ 3) & ~3;
1479 newSource
= MALLOC(comps
* newWidth
* newHeight
* sizeof(GLchan
));
1480 _mesa_upscale_teximage2d(width
, height
, newWidth
, newHeight
,
1481 comps
, source
, srcRowStride
, newSource
);
1485 srcRowStride
= comps
* newWidth
;
1489 destRowStride
= (destRowStride
- width
* 2) / 4;
1490 for (y
= 0; y
< height
; y
+= 4) {
1491 unsigned int offs
= 0 + (y
+ 0) * srcRowStride
;
1492 for (x
= 0; x
< width
; x
+= 8) {
1493 const unsigned char *lines
[4];
1494 lines
[0] = &data
[offs
];
1495 lines
[1] = lines
[0] + srcRowStride
;
1496 lines
[2] = lines
[1] + srcRowStride
;
1497 lines
[3] = lines
[2] + srcRowStride
;
1499 fxt1_quantize(encoded
, lines
, comps
);
1500 /* 128 bits per 8x4 block = 4bpp */
1503 encoded
+= destRowStride
;
1506 if (newSource
!= NULL
) {
1514 /***************************************************************************\
1517 * The decoder is based on GL_3DFX_texture_compression_FXT1
1518 * specification and serves as a concept for the encoder.
1519 \***************************************************************************/
1522 /* lookup table for scaling 5 bit colors up to 8 bits */
1523 static unsigned char _rgb_scale_5
[] = {
1524 0, 8, 16, 25, 33, 41, 49, 58,
1525 66, 74, 82, 90, 99, 107, 115, 123,
1526 132, 140, 148, 156, 165, 173, 181, 189,
1527 197, 206, 214, 222, 230, 239, 247, 255
1530 /* lookup table for scaling 6 bit colors up to 8 bits */
1531 static unsigned char _rgb_scale_6
[] = {
1532 0, 4, 8, 12, 16, 20, 24, 28,
1533 32, 36, 40, 45, 49, 53, 57, 61,
1534 65, 69, 73, 77, 81, 85, 89, 93,
1535 97, 101, 105, 109, 113, 117, 121, 125,
1536 130, 134, 138, 142, 146, 150, 154, 158,
1537 162, 166, 170, 174, 178, 182, 186, 190,
1538 194, 198, 202, 206, 210, 215, 219, 223,
1539 227, 231, 235, 239, 243, 247, 251, 255
1543 #define CC_SEL(cc, which) ((cc)[(which) / 32] >> ((which) & 31))
1544 #define UP5(c) _rgb_scale_5[(c) & 31]
1545 #define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)]
1546 #define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n)
1547 #define ZERO_4UBV(v) *((unsigned long *)(v)) = 0
1551 fxt1_decode_1HI (unsigned char *code
, int t
, unsigned char *rgba
)
1553 const unsigned long *cc
;
1556 cc
= (unsigned long *)(code
+ t
/ 8);
1557 t
= (cc
[0] >> (t
& 7)) & 7;
1562 cc
= (unsigned long *)(code
+ 12);
1564 rgba
[BCOMP
] = UP5(CC_SEL(cc
, 0));
1565 rgba
[GCOMP
] = UP5(CC_SEL(cc
, 5));
1566 rgba
[RCOMP
] = UP5(CC_SEL(cc
, 10));
1567 } else if (t
== 6) {
1568 rgba
[BCOMP
] = UP5(CC_SEL(cc
, 15));
1569 rgba
[GCOMP
] = UP5(CC_SEL(cc
, 20));
1570 rgba
[RCOMP
] = UP5(CC_SEL(cc
, 25));
1572 rgba
[BCOMP
] = LERP(6, t
, UP5(CC_SEL(cc
, 0)), UP5(CC_SEL(cc
, 15)));
1573 rgba
[GCOMP
] = LERP(6, t
, UP5(CC_SEL(cc
, 5)), UP5(CC_SEL(cc
, 20)));
1574 rgba
[RCOMP
] = LERP(6, t
, UP5(CC_SEL(cc
, 10)), UP5(CC_SEL(cc
, 25)));
1582 fxt1_decode_1CHROMA (unsigned char *code
, int t
, unsigned char *rgba
)
1584 const unsigned long *cc
;
1587 cc
= (unsigned long *)code
;
1592 t
= (cc
[0] >> (t
* 2)) & 3;
1595 cc
= (unsigned long *)(code
+ 8 + t
/ 8);
1596 kk
= cc
[0] >> (t
& 7);
1597 rgba
[BCOMP
] = UP5(kk
);
1598 rgba
[GCOMP
] = UP5(kk
>> 5);
1599 rgba
[RCOMP
] = UP5(kk
>> 10);
1605 fxt1_decode_1MIXED (unsigned char *code
, int t
, unsigned char *rgba
)
1607 const unsigned long *cc
;
1608 unsigned int col
[2][3];
1611 cc
= (unsigned long *)code
;
1614 t
= (cc
[1] >> (t
* 2)) & 3;
1616 col
[0][BCOMP
] = (*(unsigned long *)(code
+ 11)) >> 6;
1617 col
[0][GCOMP
] = CC_SEL(cc
, 99);
1618 col
[0][RCOMP
] = CC_SEL(cc
, 104);
1620 col
[1][BCOMP
] = CC_SEL(cc
, 109);
1621 col
[1][GCOMP
] = CC_SEL(cc
, 114);
1622 col
[1][RCOMP
] = CC_SEL(cc
, 119);
1623 glsb
= CC_SEL(cc
, 126);
1624 selb
= CC_SEL(cc
, 33);
1626 t
= (cc
[0] >> (t
* 2)) & 3;
1628 col
[0][BCOMP
] = CC_SEL(cc
, 64);
1629 col
[0][GCOMP
] = CC_SEL(cc
, 69);
1630 col
[0][RCOMP
] = CC_SEL(cc
, 74);
1632 col
[1][BCOMP
] = CC_SEL(cc
, 79);
1633 col
[1][GCOMP
] = CC_SEL(cc
, 84);
1634 col
[1][RCOMP
] = CC_SEL(cc
, 89);
1635 glsb
= CC_SEL(cc
, 125);
1636 selb
= CC_SEL(cc
, 1);
1639 if (CC_SEL(cc
, 124) & 1) {
1646 rgba
[BCOMP
] = UP5(col
[0][BCOMP
]);
1647 rgba
[GCOMP
] = UP5(col
[0][GCOMP
]);
1648 rgba
[RCOMP
] = UP5(col
[0][RCOMP
]);
1649 } else if (t
== 2) {
1650 rgba
[BCOMP
] = UP5(col
[1][BCOMP
]);
1651 rgba
[GCOMP
] = UP6(col
[1][GCOMP
], glsb
);
1652 rgba
[RCOMP
] = UP5(col
[1][RCOMP
]);
1654 rgba
[BCOMP
] = (UP5(col
[0][BCOMP
]) + UP5(col
[1][BCOMP
])) / 2;
1655 rgba
[GCOMP
] = (UP5(col
[0][GCOMP
]) + UP6(col
[1][GCOMP
], glsb
)) / 2;
1656 rgba
[RCOMP
] = (UP5(col
[0][RCOMP
]) + UP5(col
[1][RCOMP
])) / 2;
1664 rgba
[BCOMP
] = UP5(col
[0][BCOMP
]);
1665 rgba
[GCOMP
] = UP6(col
[0][GCOMP
], glsb
^ selb
);
1666 rgba
[RCOMP
] = UP5(col
[0][RCOMP
]);
1667 } else if (t
== 3) {
1668 rgba
[BCOMP
] = UP5(col
[1][BCOMP
]);
1669 rgba
[GCOMP
] = UP6(col
[1][GCOMP
], glsb
);
1670 rgba
[RCOMP
] = UP5(col
[1][RCOMP
]);
1672 rgba
[BCOMP
] = LERP(3, t
, UP5(col
[0][BCOMP
]), UP5(col
[1][BCOMP
]));
1673 rgba
[GCOMP
] = LERP(3, t
, UP6(col
[0][GCOMP
], glsb
^ selb
),
1674 UP6(col
[1][GCOMP
], glsb
));
1675 rgba
[RCOMP
] = LERP(3, t
, UP5(col
[0][RCOMP
]), UP5(col
[1][RCOMP
]));
1683 fxt1_decode_1ALPHA (unsigned char *code
, int t
, unsigned char *rgba
)
1685 const unsigned long *cc
;
1687 cc
= (unsigned long *)code
;
1688 if (CC_SEL(cc
, 124) & 1) {
1690 unsigned int col0
[4];
1694 t
= (cc
[1] >> (t
* 2)) & 3;
1696 col0
[BCOMP
] = (*(unsigned long *)(code
+ 11)) >> 6;
1697 col0
[GCOMP
] = CC_SEL(cc
, 99);
1698 col0
[RCOMP
] = CC_SEL(cc
, 104);
1699 col0
[ACOMP
] = CC_SEL(cc
, 119);
1701 t
= (cc
[0] >> (t
* 2)) & 3;
1703 col0
[BCOMP
] = CC_SEL(cc
, 64);
1704 col0
[GCOMP
] = CC_SEL(cc
, 69);
1705 col0
[RCOMP
] = CC_SEL(cc
, 74);
1706 col0
[ACOMP
] = CC_SEL(cc
, 109);
1710 rgba
[BCOMP
] = UP5(col0
[BCOMP
]);
1711 rgba
[GCOMP
] = UP5(col0
[GCOMP
]);
1712 rgba
[RCOMP
] = UP5(col0
[RCOMP
]);
1713 rgba
[ACOMP
] = UP5(col0
[ACOMP
]);
1714 } else if (t
== 3) {
1715 rgba
[BCOMP
] = UP5(CC_SEL(cc
, 79));
1716 rgba
[GCOMP
] = UP5(CC_SEL(cc
, 84));
1717 rgba
[RCOMP
] = UP5(CC_SEL(cc
, 89));
1718 rgba
[ACOMP
] = UP5(CC_SEL(cc
, 114));
1720 rgba
[BCOMP
] = LERP(3, t
, UP5(col0
[BCOMP
]), UP5(CC_SEL(cc
, 79)));
1721 rgba
[GCOMP
] = LERP(3, t
, UP5(col0
[GCOMP
]), UP5(CC_SEL(cc
, 84)));
1722 rgba
[RCOMP
] = LERP(3, t
, UP5(col0
[RCOMP
]), UP5(CC_SEL(cc
, 89)));
1723 rgba
[ACOMP
] = LERP(3, t
, UP5(col0
[ACOMP
]), UP5(CC_SEL(cc
, 114)));
1732 t
= (cc
[0] >> (t
* 2)) & 3;
1738 cc
= (unsigned long *)code
;
1739 rgba
[ACOMP
] = UP5(cc
[3] >> (t
* 5 + 13));
1741 cc
= (unsigned long *)(code
+ 8 + t
/ 8);
1742 kk
= cc
[0] >> (t
& 7);
1743 rgba
[BCOMP
] = UP5(kk
);
1744 rgba
[GCOMP
] = UP5(kk
>> 5);
1745 rgba
[RCOMP
] = UP5(kk
>> 10);
1752 fxt1_decode_1 (const void *texture
, int width
,
1753 int i
, int j
, unsigned char *rgba
)
1755 static void (*decode_1
[]) (unsigned char *, int, unsigned char *) = {
1756 fxt1_decode_1HI
, /* cc-high = "00?" */
1757 fxt1_decode_1HI
, /* cc-high = "00?" */
1758 fxt1_decode_1CHROMA
, /* cc-chroma = "010" */
1759 fxt1_decode_1ALPHA
, /* alpha = "011" */
1760 fxt1_decode_1MIXED
, /* mixed = "1??" */
1761 fxt1_decode_1MIXED
, /* mixed = "1??" */
1762 fxt1_decode_1MIXED
, /* mixed = "1??" */
1763 fxt1_decode_1MIXED
/* mixed = "1??" */
1766 unsigned char *code
= (unsigned char *)texture
+
1767 ((j
/ 4) * (width
/ 8) + (i
/ 8)) * 16;
1768 int mode
= CC_SEL((unsigned long *)code
, 125);
1776 decode_1
[mode
](code
, t
, rgba
);