18f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul/*
28f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * Mesa 3-D graphics library
3a1a0e51043cc6feea7811113139cb5b6d753403eBrian Paul * Version:  7.1
48f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul *
5a1a0e51043cc6feea7811113139cb5b6d753403eBrian Paul * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
68f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul *
78f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * copy of this software and associated documentation files (the "Software"),
98f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * to deal in the Software without restriction, including without limitation
108f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * Software is furnished to do so, subject to the following conditions:
138f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul *
148f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * The above copyright notice and this permission notice shall be included
158f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * in all copies or substantial portions of the Software.
168f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul *
178f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul */
248f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
258f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
268f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul/**
278f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul * \file texcompress_fxt1.c
285ebbabc5ccd03afe59299b8ce52ca862334fd252Ian Romanick * GL_3DFX_texture_compression_FXT1 support.
298f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul */
308f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
318f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
328f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul#include "glheader.h"
338f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul#include "imports.h"
348f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul#include "colormac.h"
358f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul#include "image.h"
363fdd9fa556e9ba48244cb2b3966d3bfb0b84731bVinson Lee#include "macros.h"
37db61b9ce39bccc43140357652ceb78baaf2aea44Vinson Lee#include "mfeatures.h"
380ce6a2935c85118ca20f5dfc5911a39c481dc791Brian Paul#include "mipmap.h"
398f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul#include "texcompress.h"
407116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paul#include "texcompress_fxt1.h"
418f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul#include "texstore.h"
42a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul#include "swrast/s_context.h"
438f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
448f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
4520e20fc5afa7525e247fd607e04d9adfffe730b4Chia-I Wu#if FEATURE_texture_fxt1
4620e20fc5afa7525e247fd607e04d9adfffe730b4Chia-I Wu
4720e20fc5afa7525e247fd607e04d9adfffe730b4Chia-I Wu
48392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paulstatic void
4925b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_encode (GLuint width, GLuint height, GLint comps,
5025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul             const void *source, GLint srcRowStride,
5125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul             void *dest, GLint destRowStride);
5225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul
5394ae2b4f25ba142da6b7c16a376156473f0d43e7Brian Paulvoid
5425b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_decode_1 (const void *texture, GLint stride,
55960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul               GLint i, GLint j, GLubyte *rgba);
56c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
57c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
58c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca/**
594fc344790d0fefa3c38c63cadc4ee6a52633b006Brian Paul * Store user's image in rgb_fxt1 format.
60c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca */
617116ae857c6ef3809c712e96b28bd69d92b3cd33Brian PaulGLboolean
627116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paul_mesa_texstore_rgb_fxt1(TEXSTORE_PARAMS)
638f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul{
64960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   const GLubyte *pixels;
65c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   GLint srcRowStride;
66c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   GLubyte *dst;
67663f61a3e177a443c36f414a16a9d5f94e74135dBrian Paul   const GLubyte *tempImage = NULL;
68c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
691f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul   ASSERT(dstFormat == MESA_FORMAT_RGB_FXT1);
70c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
716db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (srcFormat != GL_RGB ||
72960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul       srcType != GL_UNSIGNED_BYTE ||
73c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca       ctx->_ImageTransferState ||
74d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul       srcPacking->RowLength != srcWidth ||
75c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca       srcPacking->SwapBytes) {
76960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      /* convert image to RGB/GLubyte */
77663f61a3e177a443c36f414a16a9d5f94e74135dBrian Paul      tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
78c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             baseInternalFormat,
791f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul                                             _mesa_get_format_base_format(dstFormat),
80c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             srcWidth, srcHeight, srcDepth,
81c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             srcFormat, srcType, srcAddr,
82c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             srcPacking);
83c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      if (!tempImage)
84c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca         return GL_FALSE; /* out of memory */
85c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      pixels = tempImage;
866db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      srcRowStride = 3 * srcWidth;
87c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      srcFormat = GL_RGB;
88c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   }
89c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   else {
90d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
91d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul                                     srcFormat, srcType, 0, 0);
92d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul
93c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
94960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul                                            srcType) / sizeof(GLubyte);
95c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   }
96c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
97d69d287068e0a6b5e2f3c13b1f55335a9b6ce03bBrian Paul   dst = dstSlices[0];
98c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
993d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   fxt1_encode(srcWidth, srcHeight, 3, pixels, srcRowStride,
1006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca               dst, dstRowStride);
101c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
102c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   if (tempImage)
10332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free((void*) tempImage);
104c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
105c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   return GL_TRUE;
1068f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul}
1078f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1088f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
109c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca/**
1104fc344790d0fefa3c38c63cadc4ee6a52633b006Brian Paul * Store user's image in rgba_fxt1 format.
111c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca */
1127116ae857c6ef3809c712e96b28bd69d92b3cd33Brian PaulGLboolean
1137116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paul_mesa_texstore_rgba_fxt1(TEXSTORE_PARAMS)
1148f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul{
115960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   const GLubyte *pixels;
116c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   GLint srcRowStride;
117c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   GLubyte *dst;
118663f61a3e177a443c36f414a16a9d5f94e74135dBrian Paul   const GLubyte *tempImage = NULL;
119c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
1201f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul   ASSERT(dstFormat == MESA_FORMAT_RGBA_FXT1);
121c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
122c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   if (srcFormat != GL_RGBA ||
123960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul       srcType != GL_UNSIGNED_BYTE ||
124c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca       ctx->_ImageTransferState ||
125c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca       srcPacking->SwapBytes) {
126960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      /* convert image to RGBA/GLubyte */
127663f61a3e177a443c36f414a16a9d5f94e74135dBrian Paul      tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
128c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             baseInternalFormat,
1291f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul                                             _mesa_get_format_base_format(dstFormat),
130c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             srcWidth, srcHeight, srcDepth,
131c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             srcFormat, srcType, srcAddr,
132c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca                                             srcPacking);
133c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      if (!tempImage)
134c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca         return GL_FALSE; /* out of memory */
135c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      pixels = tempImage;
136c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      srcRowStride = 4 * srcWidth;
137c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      srcFormat = GL_RGBA;
138c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   }
139c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   else {
140d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
141d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul                                     srcFormat, srcType, 0, 0);
142d7477ad0a38a178d1e03f8064ee8245b46e24f1eBrian Paul
143c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
144960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul                                            srcType) / sizeof(GLubyte);
145c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   }
1468f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
147d69d287068e0a6b5e2f3c13b1f55335a9b6ce03bBrian Paul   dst = dstSlices[0];
148c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
1493d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   fxt1_encode(srcWidth, srcHeight, 4, pixels, srcRowStride,
1506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca               dst, dstRowStride);
151c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
152c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   if (tempImage)
15332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free((void*) tempImage);
154c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca
155c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca   return GL_TRUE;
156c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca}
1578f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1588f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1597116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paulvoid
160a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul_mesa_fetch_texel_2d_f_rgba_fxt1( const struct swrast_texture_image *texImage,
1617116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paul                                  GLint i, GLint j, GLint k, GLfloat *texel )
1628f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul{
163960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   /* just sample as GLubyte and convert to float here */
164960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   GLubyte rgba[4];
165a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) k;
166bd3c10c0f0c60ab3421c2da2eab814edc2296cb0Brian Paul   fxt1_decode_1(texImage->Map, texImage->RowStride, i, j, rgba);
167960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]);
168960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]);
169960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]);
170960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[ACOMP] = UBYTE_TO_FLOAT(rgba[ACOMP]);
1718f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul}
1728f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1738f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1747116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paulvoid
175a1661dc8957a35899d653e9fffd97f166c56be56Brian Paul_mesa_fetch_texel_2d_f_rgb_fxt1( const struct swrast_texture_image *texImage,
1767116ae857c6ef3809c712e96b28bd69d92b3cd33Brian Paul                                 GLint i, GLint j, GLint k, GLfloat *texel )
1778f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul{
178960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   /* just sample as GLubyte and convert to float here */
179960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   GLubyte rgba[4];
180a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) k;
181bd3c10c0f0c60ab3421c2da2eab814edc2296cb0Brian Paul   fxt1_decode_1(texImage->Map, texImage->RowStride, i, j, rgba);
182960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[RCOMP] = UBYTE_TO_FLOAT(rgba[RCOMP]);
183960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[GCOMP] = UBYTE_TO_FLOAT(rgba[GCOMP]);
184960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   texel[BCOMP] = UBYTE_TO_FLOAT(rgba[BCOMP]);
18525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   texel[ACOMP] = 1.0F;
1868f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul}
1878f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1888f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1898f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
1906db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca/***************************************************************************\
1916db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca * FXT1 encoder
1926db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca *
1936db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca * The encoder was built by reversing the decoder,
1946db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca * and is vaguely based on Texus2 by 3dfx. Note that this code
1953d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca * is merely a proof of concept, since it is highly UNoptimized;
1963d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca * moreover, it is sub-optimal due to initial conditions passed
1973d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca * to Lloyd's algorithm (the interpolation modes are even worse).
1986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca\***************************************************************************/
1996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
2006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
201e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#define MAX_COMP 4 /* ever needed maximum number of components in texel */
2026db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca#define MAX_VECT 4 /* ever needed maximum number of base vectors to find */
2036db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca#define N_TEXELS 32 /* number of texels in a block (always 32) */
2046db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca#define LL_N_REP 50 /* number of iterations in lloyd's vq */
205e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#define LL_RMS_D 10 /* fault tolerance (maximum delta) */
206e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#define LL_RMS_E 255 /* fault tolerance (maximum error) */
207e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */
20825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul#define ISTBLACK(v) (*((GLuint *)(v)) == 0)
2096db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
2106db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
21125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul/*
21225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul * Define a 64-bit unsigned integer type and macros
21325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul */
214a148025d94505bca08f9baa1689048032bb60e2cJosé Fonseca#if 1
2153ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2163ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca#define FX64_NATIVE 1
2173ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
218a148025d94505bca08f9baa1689048032bb60e2cJosé Fonsecatypedef uint64_t Fx64;
2193ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2207a42f1562d74e631616e03aed20190a27c22859bDaniel Borca#define FX64_MOV32(a, b) a = b
2217a42f1562d74e631616e03aed20190a27c22859bDaniel Borca#define FX64_OR32(a, b)  a |= b
2227a42f1562d74e631616e03aed20190a27c22859bDaniel Borca#define FX64_SHL(a, c)   a <<= c
2233ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
224a148025d94505bca08f9baa1689048032bb60e2cJosé Fonseca#else
2253ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2263ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca#define FX64_NATIVE 0
2273ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2283ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borcatypedef struct {
22925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint lo, hi;
2303ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca} Fx64;
2313ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2323ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca#define FX64_MOV32(a, b) a.lo = b
2333ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca#define FX64_OR32(a, b)  a.lo |= b
2343ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2353ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca#define FX64_SHL(a, c)                                 \
2363ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   do {                                                \
2373ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca       if ((c) >= 32) {                                \
2383ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca          a.hi = a.lo << ((c) - 32);                   \
2393ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca          a.lo = 0;                                    \
2403ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca       } else {                                        \
2413ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca          a.hi = (a.hi << (c)) | (a.lo >> (32 - (c))); \
2423ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca          a.lo <<= (c);                                \
2433ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca       }                                               \
2443ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   } while (0)
2453ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
246a148025d94505bca08f9baa1689048032bb60e2cJosé Fonseca#endif
2473ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
2483ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca
249c049d4bc897f92fd25ed961f1acedaa9d33cc5afDaniel Borca#define F(i) (GLfloat)1 /* can be used to obtain an oblong metric: 0.30 / 0.59 / 0.11 */
2503d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca#define SAFECDOT 1 /* for paranoids */
2513d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca
2523d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca#define MAKEIVEC(NV, NC, IV, B, V0, V1)  \
2533d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   do {                                  \
2543d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      /* compute interpolation vector */ \
25525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat d2 = 0.0F;                 \
25625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat rd2;                       \
2573d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca                                         \
2583d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      for (i = 0; i < NC; i++) {         \
2593d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         IV[i] = (V1[i] - V0[i]) * F(i); \
2603d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         d2 += IV[i] * IV[i];            \
2613d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      }                                  \
26225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      rd2 = (GLfloat)NV / d2;            \
2633d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      B = 0;                             \
2643d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      for (i = 0; i < NC; i++) {         \
2653d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         IV[i] *= F(i);                  \
2663d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         B -= IV[i] * V0[i];             \
2673d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         IV[i] *= rd2;                   \
2683d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      }                                  \
2693d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      B = B * rd2 + 0.5f;                \
2703d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   } while (0)
2713d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca
2723d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca#define CALCCDOT(TEXEL, NV, NC, IV, B, V)\
2733d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   do {                                  \
27425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat dot = 0.0F;                \
2753d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      for (i = 0; i < NC; i++) {         \
2763d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         dot += V[i] * IV[i];            \
2773d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      }                                  \
27825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      TEXEL = (GLint)(dot + B);          \
2793d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      if (SAFECDOT) {                    \
2803d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         if (TEXEL < 0) {                \
2813d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca            TEXEL = 0;                   \
2823d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         } else if (TEXEL > NV) {        \
2833d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca            TEXEL = NV;                  \
2843d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         }                               \
2853d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      }                                  \
2863d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   } while (0)
2873d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca
2883d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca
28925b67e64049c291bd4e845c076d450653ba45f8dBrian Paulstatic GLint
29025b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_bestcol (GLfloat vec[][MAX_COMP], GLint nv,
29125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul              GLubyte input[MAX_COMP], GLint nc)
2926db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
29325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, best = -1;
29425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat err = 1e9; /* big enough */
2956db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
2966db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (j = 0; j < nv; j++) {
29725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat e = 0.0F;
2986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (i = 0; i < nc; i++) {
2996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]);
3006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
3016db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (e < err) {
3026db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         err = e;
3036db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         best = j;
3046db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
3056db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
3066db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
3076db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   return best;
3086db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
3096db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
3106db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
31125b67e64049c291bd4e845c076d450653ba45f8dBrian Paulstatic GLint
31225b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_worst (GLfloat vec[MAX_COMP],
31325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
3146db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
31525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, k, worst = -1;
31625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat err = -1.0F; /* small enough */
3176db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
3186db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (k = 0; k < n; k++) {
31925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat e = 0.0F;
3206db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (i = 0; i < nc; i++) {
3216db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]);
3226db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
3236db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (e > err) {
3246db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         err = e;
3256db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         worst = k;
3266db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
3276db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
3286db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
3296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   return worst;
3306db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
3316db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
3326db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
33325b67e64049c291bd4e845c076d450653ba45f8dBrian Paulstatic GLint
33425b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_variance (GLdouble variance[MAX_COMP],
33525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul               GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
336e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca{
33725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, k, best = 0;
33825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint sx, sx2;
33925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLdouble var, maxvar = -1; /* small enough */
34025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLdouble teenth = 1.0 / n;
341e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
342e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (i = 0; i < nc; i++) {
343e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      sx = sx2 = 0;
344e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (k = 0; k < n; k++) {
34525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint t = input[k][i];
346e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         sx += t;
347e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         sx2 += t * t;
348e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
349e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      var = sx2 * teenth - sx * sx * teenth * teenth;
350e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxvar < var) {
351e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxvar = var;
352e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         best = i;
353e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
354e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (variance) {
355e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         variance[i] = var;
356e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
357e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
358e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
359e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   return best;
360e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca}
361e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
362e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
36325b67e64049c291bd4e845c076d450653ba45f8dBrian Paulstatic GLint
36425b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_choose (GLfloat vec[][MAX_COMP], GLint nv,
36525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul             GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
366e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca{
367e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#if 0
368e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Choose colors from a grid.
369e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
37025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j;
371e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
372e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = 0; j < nv; j++) {
37325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint m = j * (n - 1) / (nv - 1);
374e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < nc; i++) {
375e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[j][i] = input[m][i];
376e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
377e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
378e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#else
379e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Our solution here is to find the darkest and brightest colors in
380e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * the 8x4 tile and use those as the two representative colors.
381e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * There are probably better algorithms to use (histogram-based).
382e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
38325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k;
38425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minSum = 2000; /* big enough */
38525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxSum = -1; /* small enough */
38625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minCol = 0; /* phoudoin: silent compiler! */
38725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxCol = 0; /* phoudoin: silent compiler! */
388e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
389e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   struct {
39025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint flag;
39125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint key;
39225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint freq;
39325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint idx;
394e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } hist[N_TEXELS];
39525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint lenh = 0;
396e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
39726f8fad1456fdc2b352cea9d3b4c32cb5f6ae947Kenneth Graunke   memset(hist, 0, sizeof(hist));
398e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
399e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (k = 0; k < n; k++) {
40025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint l;
40125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint key = 0;
40225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint sum = 0;
403e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < nc; i++) {
404e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         key <<= 8;
405e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         key |= input[k][i];
406e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         sum += input[k][i];
407e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
408e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (l = 0; l < n; l++) {
409e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (!hist[l].flag) {
410e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            /* alloc new slot */
411e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            hist[l].flag = !0;
412e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            hist[l].key = key;
413e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            hist[l].freq = 1;
414e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            hist[l].idx = k;
415e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            lenh = l + 1;
416e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            break;
417e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         } else if (hist[l].key == key) {
418e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            hist[l].freq++;
419e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            break;
420e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
421e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
422e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minSum > sum) {
423e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minSum = sum;
424e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minCol = k;
425e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
426e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxSum < sum) {
427e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxSum = sum;
428e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxCol = k;
429e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
430e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
431e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
432e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (lenh <= nv) {
433e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (j = 0; j < lenh; j++) {
434e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (i = 0; i < nc; i++) {
43525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            vec[j][i] = (GLfloat)input[hist[j].idx][i];
436e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
437e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
438e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (; j < nv; j++) {
439e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (i = 0; i < nc; i++) {
440e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            vec[j][i] = vec[0][i];
441e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
442e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
443e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      return 0;
444e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
445e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
446e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = 0; j < nv; j++) {
447e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < nc; i++) {
448c049d4bc897f92fd25ed961f1acedaa9d33cc5afDaniel Borca         vec[j][i] = ((nv - 1 - j) * input[minCol][i] + j * input[maxCol][i] + (nv - 1) / 2) / (GLfloat)(nv - 1);
449e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
450e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
451e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#endif
452e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
453e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   return !0;
454e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca}
455e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
456e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
45725b67e64049c291bd4e845c076d450653ba45f8dBrian Paulstatic GLint
45825b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_lloyd (GLfloat vec[][MAX_COMP], GLint nv,
45925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n)
4606db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
4616db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* Use the generalized lloyd's algorithm for VQ:
4626db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *     find 4 color vectors.
4636db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *
4646db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *     for each sample color
4656db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *         sort to nearest vector.
4666db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *
467fab1f07d6ad01463897ae792f4b33738afb07369Jeff Smith    *     replace each vector with the centroid of its matching colors.
4686db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *
4696db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *     repeat until RMS doesn't improve.
4706db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *
4716db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *     if a color vector has no samples, or becomes the same as another
4726db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *     vector, replace it with the color which is farthest from a sample.
4736db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    *
474e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * vec[][MAX_COMP]           initial vectors and resulting colors
4756db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    * nv                        number of resulting colors required
4766db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    * input[N_TEXELS][MAX_COMP] input texels
4776db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    * nc                        number of components in input / vec
4786db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    * n                         number of input samples
4796db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    */
4806db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
48125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint sum[MAX_VECT][MAX_COMP]; /* used to accumulate closest texels */
48225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint cnt[MAX_VECT]; /* how many times a certain vector was chosen */
48325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat error, lasterror = 1e9;
4846db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
48525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k, rep;
4866db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
4876db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* the quantizer */
4886db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (rep = 0; rep < LL_N_REP; rep++) {
4896db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* reset sums & counters */
4906db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (j = 0; j < nv; j++) {
4916db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         for (i = 0; i < nc; i++) {
4926db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            sum[j][i] = 0;
4936db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
4946db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         cnt[j] = 0;
4956db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
4966db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      error = 0;
4976db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
4986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* scan whole block */
4996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (k = 0; k < n; k++) {
500e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#if 1
50125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint best = -1;
50225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLfloat err = 1e9; /* big enough */
503e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* determine best vector */
504e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (j = 0; j < nv; j++) {
50525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLfloat e = (vec[j][0] - input[k][0]) * (vec[j][0] - input[k][0]) +
506e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca                      (vec[j][1] - input[k][1]) * (vec[j][1] - input[k][1]) +
507e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca                      (vec[j][2] - input[k][2]) * (vec[j][2] - input[k][2]);
508e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            if (nc == 4) {
509e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca               e += (vec[j][3] - input[k][3]) * (vec[j][3] - input[k][3]);
510e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            }
511e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            if (e < err) {
512e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca               err = e;
513e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca               best = j;
514e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            }
515e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
516e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#else
51725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint best = fxt1_bestcol(vec, nv, input[k], nc, &err);
518e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#endif
519abcb6b6d01c253627363a05205291630b5247018Vinson Lee         assert(best >= 0);
5206db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* add in closest color */
5216db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         for (i = 0; i < nc; i++) {
5226db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            sum[best][i] += input[k][i];
5236db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
5246db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* mark this vector as used */
5256db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         cnt[best]++;
5266db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* accumulate error */
527e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         error += err;
5286db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
5296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
530e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* check RMS */
531e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if ((error < LL_RMS_E) ||
532e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca          ((error < lasterror) && ((lasterror - error) < LL_RMS_D))) {
533e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         return !0; /* good match */
5346db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
535e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lasterror = error;
5366db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5376db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* move each vector to the barycenter of its closest colors */
5386db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (j = 0; j < nv; j++) {
5396db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         if (cnt[j]) {
54025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLfloat div = 1.0F / cnt[j];
5416db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            for (i = 0; i < nc; i++) {
5426db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca               vec[j][i] = div * sum[j][i];
5436db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            }
5446db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         } else {
5456db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            /* this vec has no samples or is identical with a previous vec */
54625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLint worst = fxt1_worst(vec[j], input, nc, n);
5476db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            for (i = 0; i < nc; i++) {
5486db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca               vec[j][i] = input[worst][i];
5496db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            }
5506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
5516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
5526db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
553e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
554e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   return 0; /* could not converge fast enough */
5556db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
5566db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5576db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5586db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
55925b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize_CHROMA (GLuint *cc,
56025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                      GLubyte input[N_TEXELS][MAX_COMP])
5616db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
56225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_vect = 4; /* 4 base vectors to find */
56325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_comp = 3; /* 3 components: R, G, B */
56425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat vec[MAX_VECT][MAX_COMP];
56525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k;
5663ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   Fx64 hi; /* high quadword */
56725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
5686db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
569e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (fxt1_choose(vec, n_vect, input, n_comp, N_TEXELS) != 0) {
570e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      fxt1_lloyd(vec, n_vect, input, n_comp, N_TEXELS);
571e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
5726db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5733ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   FX64_MOV32(hi, 4); /* cc-chroma = "010" + unused bit */
574e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = n_vect - 1; j >= 0; j--) {
5756db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (i = 0; i < n_comp; i++) {
5766db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* add in colors */
5773ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_SHL(hi, 5);
57825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
5796db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
5806db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
5813ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   ((Fx64 *)cc)[1] = hi;
5826db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5836db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   lohi = lolo = 0;
5846db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* right microtile */
5856db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (k = N_TEXELS - 1; k >= N_TEXELS/2; k--) {
5866db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      lohi <<= 2;
587e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lohi |= fxt1_bestcol(vec, n_vect, input[k], n_comp);
5886db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
5896db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* left microtile */
5906db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (; k >= 0; k--) {
5916db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      lolo <<= 2;
592e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lolo |= fxt1_bestcol(vec, n_vect, input[k], n_comp);
5936db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
5946db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   cc[1] = lohi;
5956db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   cc[0] = lolo;
5966db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
5976db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
5996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
60025b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize_ALPHA0 (GLuint *cc,
60125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                      GLubyte input[N_TEXELS][MAX_COMP],
60225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                      GLubyte reord[N_TEXELS][MAX_COMP], GLint n)
6036db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
60425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_vect = 3; /* 3 base vectors to find */
60525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_comp = 4; /* 4 components: R, G, B, A */
60625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat vec[MAX_VECT][MAX_COMP];
60725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k;
6083ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   Fx64 hi; /* high quadword */
60925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
6106db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
6116db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* the last vector indicates zero */
6126db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (i = 0; i < n_comp; i++) {
6136db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      vec[n_vect][i] = 0;
6146db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
6156db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
6166db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* the first n texels in reord are guaranteed to be non-zero */
617e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (fxt1_choose(vec, n_vect, reord, n_comp, n) != 0) {
618e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      fxt1_lloyd(vec, n_vect, reord, n_comp, n);
619e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
6206db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
6213ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   FX64_MOV32(hi, 6); /* alpha = "011" + lerp = 0 */
622e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = n_vect - 1; j >= 0; j--) {
6236db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* add in alphas */
6243ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca      FX64_SHL(hi, 5);
62525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      FX64_OR32(hi, (GLuint)(vec[j][ACOMP] / 8.0F));
6266db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
627e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = n_vect - 1; j >= 0; j--) {
6286db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (i = 0; i < n_comp - 1; i++) {
6296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* add in colors */
6303ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_SHL(hi, 5);
63125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
6326db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
6336db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
6343ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   ((Fx64 *)cc)[1] = hi;
6356db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
6366db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   lohi = lolo = 0;
6376db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* right microtile */
6386db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (k = N_TEXELS - 1; k >= N_TEXELS/2; k--) {
6396db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      lohi <<= 2;
640e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lohi |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp);
6416db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
6426db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* left microtile */
6436db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (; k >= 0; k--) {
6446db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      lolo <<= 2;
645e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lolo |= fxt1_bestcol(vec, n_vect + 1, input[k], n_comp);
6466db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
6476db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   cc[1] = lohi;
6486db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   cc[0] = lolo;
6496db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
6506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
6516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
6526db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
65325b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize_ALPHA1 (GLuint *cc,
65425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                      GLubyte input[N_TEXELS][MAX_COMP])
655e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca{
65625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_vect = 3; /* highest vector number in each microtile */
65725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_comp = 4; /* 4 components: R, G, B, A */
65825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat vec[1 + 1 + 1][MAX_COMP]; /* 1.5 extrema for each sub-block */
65925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat b, iv[MAX_COMP]; /* interpolation vector */
66025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k;
6613ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   Fx64 hi; /* high quadword */
66225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
663e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
66425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minSum;
66525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxSum;
66625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minColL = 0, maxColL = 0;
66725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minColR = 0, maxColR = 0;
66825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint sumL = 0, sumR = 0;
669b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao   GLint nn_comp;
670e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Our solution here is to find the darkest and brightest colors in
671e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * the 4x4 tile and use those as the two representative colors.
672e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * There are probably better algorithms to use (histogram-based).
673e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
674b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao   nn_comp = n_comp;
675b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao   while ((minColL == maxColL) && nn_comp) {
676b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       minSum = 2000; /* big enough */
677b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       maxSum = -1; /* small enough */
678b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       for (k = 0; k < N_TEXELS / 2; k++) {
679b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           GLint sum = 0;
680b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           for (i = 0; i < nn_comp; i++) {
681b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               sum += input[k][i];
682b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           }
683b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           if (minSum > sum) {
684b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               minSum = sum;
685b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               minColL = k;
686b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           }
687b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           if (maxSum < sum) {
688b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               maxSum = sum;
689b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               maxColL = k;
690b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           }
691b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           sumL += sum;
692b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       }
693b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao
694b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       nn_comp--;
695e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
696b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao
697b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao   nn_comp = n_comp;
698b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao   while ((minColR == maxColR) && nn_comp) {
699b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       minSum = 2000; /* big enough */
700b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       maxSum = -1; /* small enough */
701b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       for (k = N_TEXELS / 2; k < N_TEXELS; k++) {
702b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           GLint sum = 0;
703b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           for (i = 0; i < nn_comp; i++) {
704b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               sum += input[k][i];
705b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           }
706b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           if (minSum > sum) {
707b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               minSum = sum;
708b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               minColR = k;
709b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           }
710b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           if (maxSum < sum) {
711b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               maxSum = sum;
712b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao               maxColR = k;
713b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           }
714b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao           sumR += sum;
715b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       }
716b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao
717b6fe1bdd4da806895f90f3f5be4fb364d6f1f64aXiang, Haihao       nn_comp--;
718e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
719e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
720e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* choose the common vector (yuck!) */
72125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   {
72225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint j1, j2;
72325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint v1 = 0, v2 = 0;
72425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat err = 1e9; /* big enough */
72525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLfloat tv[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
72625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      for (i = 0; i < n_comp; i++) {
72725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         tv[0][i] = input[minColL][i];
72825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         tv[1][i] = input[maxColL][i];
72925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         tv[2][i] = input[minColR][i];
73025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         tv[3][i] = input[maxColR][i];
73125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      }
73225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      for (j1 = 0; j1 < 2; j1++) {
73325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         for (j2 = 2; j2 < 4; j2++) {
7342f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca            GLfloat e = 0.0F;
7352f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca            for (i = 0; i < n_comp; i++) {
7362f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca               e += (tv[j1][i] - tv[j2][i]) * (tv[j1][i] - tv[j2][i]);
7372f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca            }
7382f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca            if (e < err) {
7392f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca               err = e;
7402f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca               v1 = j1;
7412f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca               v2 = j2;
7422f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca            }
74325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         }
74425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      }
74525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      for (i = 0; i < n_comp; i++) {
74625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         vec[0][i] = tv[1 - v1][i];
74725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         vec[1][i] = (tv[v1][i] * sumL + tv[v2][i] * sumR) / (sumL + sumR);
74825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         vec[2][i] = tv[5 - v2][i];
749e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
750e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
751e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
752e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* left microtile */
753e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   cc[0] = 0;
754e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (minColL != maxColL) {
755e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* compute interpolation vector */
7563d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
757e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
758e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in texels */
759e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lolo = 0;
760e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
76125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint texel;
762e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* interpolate color */
7633d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
764e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texel */
765e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lolo <<= 2;
766e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lolo |= texel;
767e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
768e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
769e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[0] = lolo;
770e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
771e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
772e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* right microtile */
773e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   cc[1] = 0;
774e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (minColR != maxColR) {
775e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* compute interpolation vector */
7763d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]);
777e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
778e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in texels */
779e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lohi = 0;
780e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
78125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint texel;
782e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* interpolate color */
7833d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
784e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texel */
785e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lohi <<= 2;
786e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lohi |= texel;
787e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
788e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
789e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[1] = lohi;
790e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
791e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
7923ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   FX64_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */
793e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = n_vect - 1; j >= 0; j--) {
794e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in alphas */
7953ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca      FX64_SHL(hi, 5);
79625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      FX64_OR32(hi, (GLuint)(vec[j][ACOMP] / 8.0F));
797e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
798e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = n_vect - 1; j >= 0; j--) {
799e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp - 1; i++) {
800e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in colors */
8013ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_SHL(hi, 5);
80225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
803e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
804e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
8053ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   ((Fx64 *)cc)[1] = hi;
806e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca}
807e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
808e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
809e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borcastatic void
81025b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize_HI (GLuint *cc,
81125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                  GLubyte input[N_TEXELS][MAX_COMP],
81225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                  GLubyte reord[N_TEXELS][MAX_COMP], GLint n)
813e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca{
81425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_vect = 6; /* highest vector number */
81525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_comp = 3; /* 3 components: R, G, B */
81625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat b = 0.0F;       /* phoudoin: silent compiler! */
81725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat iv[MAX_COMP];   /* interpolation vector */
81825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, k;
81925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint hihi; /* high quadword: hi dword */
82025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul
82125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minSum = 2000; /* big enough */
82225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxSum = -1; /* small enough */
82325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minCol = 0; /* phoudoin: silent compiler! */
82425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxCol = 0; /* phoudoin: silent compiler! */
825e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
826e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Our solution here is to find the darkest and brightest colors in
827e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * the 8x4 tile and use those as the two representative colors.
828e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * There are probably better algorithms to use (histogram-based).
829e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
830e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (k = 0; k < n; k++) {
83125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint sum = 0;
832e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
833e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         sum += reord[k][i];
834e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
835e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minSum > sum) {
836e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minSum = sum;
837e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minCol = k;
838e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
839e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxSum < sum) {
840e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxSum = sum;
841e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxCol = k;
842e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
843e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
844e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
845e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   hihi = 0; /* cc-hi = "00" */
846e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (i = 0; i < n_comp; i++) {
847e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in colors */
848e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      hihi <<= 5;
849e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      hihi |= reord[maxCol][i] >> 3;
850e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
851e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (i = 0; i < n_comp; i++) {
852e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in colors */
853e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      hihi <<= 5;
854e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      hihi |= reord[minCol][i] >> 3;
855e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
856e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   cc[3] = hihi;
857e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   cc[0] = cc[1] = cc[2] = 0;
858e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
859e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* compute interpolation vector */
860e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (minCol != maxCol) {
8613d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]);
862e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
863e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
864e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* add in texels */
865e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (k = N_TEXELS - 1; k >= 0; k--) {
86625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint t = k * 3;
8676f3d16c64aee2ef0eb94aa0e4ab1ce53fd4a5579Brian Paul      GLuint *kk = (GLuint *)((char *)cc + t / 8);
86825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint texel = n_vect + 1; /* transparent black */
869e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
870e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (!ISTBLACK(input[k])) {
871e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (minCol != maxCol) {
872e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            /* interpolate color */
8733d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca            CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
874e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            /* add in texel */
875e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            kk[0] |= texel << (t & 7);
876e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
877e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      } else {
878e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texel */
879e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         kk[0] |= texel << (t & 7);
880e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
881e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
882e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca}
883e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
884e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
885e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borcastatic void
88625b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize_MIXED1 (GLuint *cc,
88725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                      GLubyte input[N_TEXELS][MAX_COMP])
888e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca{
88925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_vect = 2; /* highest vector number in each microtile */
89025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_comp = 3; /* 3 components: R, G, B */
89125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLubyte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
89225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat b, iv[MAX_COMP]; /* interpolation vector */
89325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k;
8943ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   Fx64 hi; /* high quadword */
89525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
896e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
89725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minSum;
89825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxSum;
89925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minColL = 0, maxColL = -1;
90025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minColR = 0, maxColR = -1;
901e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
902e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Our solution here is to find the darkest and brightest colors in
903e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * the 4x4 tile and use those as the two representative colors.
904e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * There are probably better algorithms to use (histogram-based).
905e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
9063d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   minSum = 2000; /* big enough */
907e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   maxSum = -1; /* small enough */
908e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (k = 0; k < N_TEXELS / 2; k++) {
909e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (!ISTBLACK(input[k])) {
91025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint sum = 0;
911e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (i = 0; i < n_comp; i++) {
912e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            sum += input[k][i];
913e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
914e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (minSum > sum) {
915e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            minSum = sum;
916e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            minColL = k;
917e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
918e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (maxSum < sum) {
919e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            maxSum = sum;
920e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            maxColL = k;
921e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
922e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
923e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
9243d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   minSum = 2000; /* big enough */
925e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   maxSum = -1; /* small enough */
926e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (; k < N_TEXELS; k++) {
927e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (!ISTBLACK(input[k])) {
92825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint sum = 0;
929e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (i = 0; i < n_comp; i++) {
930e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            sum += input[k][i];
931e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
932e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (minSum > sum) {
933e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            minSum = sum;
934e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            minColR = k;
935e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
936e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (maxSum < sum) {
937e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            maxSum = sum;
938e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            maxColR = k;
939e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
940e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
941e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
942e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
943e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* left microtile */
944e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (maxColL == -1) {
945e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* all transparent black */
9466f3d16c64aee2ef0eb94aa0e4ab1ce53fd4a5579Brian Paul      cc[0] = ~0u;
947e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
948e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[0][i] = 0;
949e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[1][i] = 0;
950e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
951e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else {
952e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[0] = 0;
953e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
954e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[0][i] = input[minColL][i];
955e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[1][i] = input[maxColL][i];
956e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
957e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minColL != maxColL) {
958e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* compute interpolation vector */
9593d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
960e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
961e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texels */
962e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lolo = 0;
963e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
96425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLint texel = n_vect + 1; /* transparent black */
965e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            if (!ISTBLACK(input[k])) {
966e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca               /* interpolate color */
9673d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca               CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
968e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            }
969e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            /* add in texel */
970e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            lolo <<= 2;
971e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            lolo |= texel;
972e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
973e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         cc[0] = lolo;
974e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
975e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
976e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
977e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* right microtile */
978e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (maxColR == -1) {
979e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* all transparent black */
9806f3d16c64aee2ef0eb94aa0e4ab1ce53fd4a5579Brian Paul      cc[1] = ~0u;
981e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
982e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[2][i] = 0;
983e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[3][i] = 0;
984e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
985e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else {
986e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[1] = 0;
987e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
988e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[2][i] = input[minColR][i];
989e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         vec[3][i] = input[maxColR][i];
990e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
991e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minColR != maxColR) {
992e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* compute interpolation vector */
9933d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
994e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
995e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texels */
996e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lohi = 0;
997e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
99825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul            GLint texel = n_vect + 1; /* transparent black */
999e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            if (!ISTBLACK(input[k])) {
1000e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca               /* interpolate color */
10013d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca               CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
1002e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            }
1003e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            /* add in texel */
1004e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            lohi <<= 2;
1005e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            lohi |= texel;
1006e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
1007e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         cc[1] = lohi;
1008e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1009e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1010e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
10113ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   FX64_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
1012e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = 2 * 2 - 1; j >= 0; j--) {
1013e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
1014e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in colors */
10153ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_SHL(hi, 5);
10163ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_OR32(hi, vec[j][i] >> 3);
1017e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1018e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
10193ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   ((Fx64 *)cc)[1] = hi;
1020e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca}
1021e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1022e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1023e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borcastatic void
102425b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize_MIXED0 (GLuint *cc,
102525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul                      GLubyte input[N_TEXELS][MAX_COMP])
1026e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca{
102725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_vect = 3; /* highest vector number in each microtile */
102825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLint n_comp = 3; /* 3 components: R, G, B */
102925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLubyte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
103025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLfloat b, iv[MAX_COMP]; /* interpolation vector */
103125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, j, k;
10323ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   Fx64 hi; /* high quadword */
103325b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
1034e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
103525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minColL = 0, maxColL = 0;
103625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minColR = 0, maxColR = 0;
1037e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#if 0
103825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minSum;
103925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxSum;
1040e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1041e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Our solution here is to find the darkest and brightest colors in
1042e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * the 4x4 tile and use those as the two representative colors.
1043e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * There are probably better algorithms to use (histogram-based).
1044e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
10453d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   minSum = 2000; /* big enough */
1046e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   maxSum = -1; /* small enough */
1047e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (k = 0; k < N_TEXELS / 2; k++) {
104825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint sum = 0;
1049e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
1050e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         sum += input[k][i];
1051e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1052e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minSum > sum) {
1053e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minSum = sum;
1054e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minColL = k;
1055e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1056e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxSum < sum) {
1057e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxSum = sum;
1058e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxColL = k;
1059e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1060e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
10613d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   minSum = 2000; /* big enough */
1062e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   maxSum = -1; /* small enough */
1063e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (; k < N_TEXELS; k++) {
106425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint sum = 0;
1065e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
1066e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         sum += input[k][i];
1067e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1068e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minSum > sum) {
1069e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minSum = sum;
1070e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minColR = k;
1071e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1072e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxSum < sum) {
1073e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxSum = sum;
1074e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxColR = k;
1075e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1076e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1077e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#else
107825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint minVal;
107925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxVal;
108025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2);
108125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2);
1082e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1083e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* Scan the channel with max variance for lo & hi
1084e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * and use those as the two representative colors.
1085e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
10863d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   minVal = 2000; /* big enough */
1087e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   maxVal = -1; /* small enough */
1088e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (k = 0; k < N_TEXELS / 2; k++) {
108925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint t = input[k][maxVarL];
1090e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minVal > t) {
1091e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minVal = t;
1092e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minColL = k;
1093e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1094e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxVal < t) {
1095e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxVal = t;
1096e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxColL = k;
1097e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1098e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
10993d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   minVal = 2000; /* big enough */
1100e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   maxVal = -1; /* small enough */
1101e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (; k < N_TEXELS; k++) {
110225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint t = input[k][maxVarR];
1103e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (minVal > t) {
1104e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minVal = t;
1105e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         minColR = k;
1106e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1107e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      if (maxVal < t) {
1108e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxVal = t;
1109e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         maxColR = k;
1110e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1111e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1112e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#endif
1113e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1114e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* left microtile */
1115e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   cc[0] = 0;
1116e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (i = 0; i < n_comp; i++) {
1117e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      vec[0][i] = input[minColL][i];
1118e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      vec[1][i] = input[maxColL][i];
1119e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1120e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (minColL != maxColL) {
1121e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* compute interpolation vector */
11223d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
1123e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1124e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in texels */
1125e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lolo = 0;
1126e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
112725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint texel;
1128e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* interpolate color */
11293d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
1130e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texel */
1131e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lolo <<= 2;
1132e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lolo |= texel;
1133e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1134e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1135e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* funky encoding for LSB of green */
113625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      if ((GLint)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) {
1137e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (i = 0; i < n_comp; i++) {
1138e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            vec[1][i] = input[minColL][i];
1139e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            vec[0][i] = input[maxColL][i];
1140e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
1141e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lolo = ~lolo;
1142e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1143e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1144e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[0] = lolo;
1145e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1146e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1147e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   /* right microtile */
1148e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   cc[1] = 0;
1149e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (i = 0; i < n_comp; i++) {
1150e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      vec[2][i] = input[minColR][i];
1151e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      vec[3][i] = input[maxColR][i];
1152e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1153e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (minColR != maxColR) {
1154e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* compute interpolation vector */
11553d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
1156e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1157e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* add in texels */
1158e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      lohi = 0;
1159e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
116025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLint texel;
1161e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* interpolate color */
11623d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
1163e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in texel */
1164e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lohi <<= 2;
1165e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lohi |= texel;
1166e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1167e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1168e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      /* funky encoding for LSB of green */
116925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      if ((GLint)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) {
1170e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         for (i = 0; i < n_comp; i++) {
1171e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            vec[3][i] = input[minColR][i];
1172e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            vec[2][i] = input[maxColR][i];
1173e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         }
1174e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lohi = ~lohi;
1175e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1176e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1177e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[1] = lohi;
1178e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1179e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
11803ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   FX64_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
1181e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   for (j = 2 * 2 - 1; j >= 0; j--) {
1182e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (i = 0; i < n_comp; i++) {
1183e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         /* add in colors */
11843ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_SHL(hi, 5);
11853ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca         FX64_OR32(hi, vec[j][i] >> 3);
1186e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      }
1187e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
11883ea9cf0d5ceb9c1451e9919e5252cbb2d0423fc7Daniel Borca   ((Fx64 *)cc)[1] = hi;
1189e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca}
1190e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1191e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
1192e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borcastatic void
119325b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_quantize (GLuint *cc, const GLubyte *lines[], GLint comps)
1194c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca{
119525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint trualpha;
119625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLubyte reord[N_TEXELS][MAX_COMP];
11976db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
119825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLubyte input[N_TEXELS][MAX_COMP];
119925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint i, k, l;
12006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
12013d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   if (comps == 3) {
12023d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca      /* make the whole block opaque */
120326f8fad1456fdc2b352cea9d3b4c32cb5f6ae947Kenneth Graunke      memset(input, -1, sizeof(input));
12043d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   }
1205e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
12066db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* 8 texels each line */
12076db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (l = 0; l < 4; l++) {
12086db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (k = 0; k < 4; k++) {
12096db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         for (i = 0; i < comps; i++) {
12106db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            input[k + l * 4][i] = *lines[l]++;
12116db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
12126db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
1213e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      for (; k < 8; k++) {
12146db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         for (i = 0; i < comps; i++) {
1215e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            input[k + l * 4 + 12][i] = *lines[l]++;
12166db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
12176db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
12186db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
12196db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
12207a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   /* block layout:
1221e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * 00, 01, 02, 03, 08, 09, 0a, 0b
1222e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * 10, 11, 12, 13, 18, 19, 1a, 1b
1223e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * 04, 05, 06, 07, 0c, 0d, 0e, 0f
1224e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    * 14, 15, 16, 17, 1c, 1d, 1e, 1f
1225e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca    */
1226e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca
12276db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   /* [dBorca]
12286db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    * stupidity flows forth from this
12296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca    */
1230e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   l = N_TEXELS;
1231e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   trualpha = 0;
12326db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (comps == 4) {
12336db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* skip all transparent black texels */
12346db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      l = 0;
12356db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (k = 0; k < N_TEXELS; k++) {
12366db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* test all components against 0 */
1237e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         if (!ISTBLACK(input[k])) {
12386db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            /* texel is not transparent black */
1239e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            COPY_4UBV(reord[l], input[k]);
1240e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca            if (reord[l][ACOMP] < (255 - ALPHA_TS)) {
12416db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca               /* non-opaque texel */
12426db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca               trualpha = !0;
12436db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            }
12446db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca            l++;
12456db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
12466db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
12476db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
12486db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
1249e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#if 0
12506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (trualpha) {
12516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_quantize_ALPHA0(cc, input, reord, l);
1252e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else if (l == 0) {
1253e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[0] = cc[1] = cc[2] = -1;
1254e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[3] = 0;
1255e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else if (l < N_TEXELS) {
1256e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      fxt1_quantize_HI(cc, input, reord, l);
12576db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   } else {
12586db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_quantize_CHROMA(cc, input);
12596db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
12607a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   (void)fxt1_quantize_ALPHA1;
12617a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   (void)fxt1_quantize_MIXED1;
12627a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   (void)fxt1_quantize_MIXED0;
1263e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#else
1264e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (trualpha) {
1265e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      fxt1_quantize_ALPHA1(cc, input);
1266e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else if (l == 0) {
12676f3d16c64aee2ef0eb94aa0e4ab1ce53fd4a5579Brian Paul      cc[0] = cc[1] = cc[2] = ~0u;
1268e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      cc[3] = 0;
1269e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else if (l < N_TEXELS) {
1270e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      fxt1_quantize_MIXED1(cc, input);
1271e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   } else {
1272e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca      fxt1_quantize_MIXED0(cc, input);
1273e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
12747a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   (void)fxt1_quantize_ALPHA0;
12757a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   (void)fxt1_quantize_HI;
12767a42f1562d74e631616e03aed20190a27c22859bDaniel Borca   (void)fxt1_quantize_CHROMA;
1277e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca#endif
12786db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
12796db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
12806db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
1281ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul
1282ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul/**
1283ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul * Upscale an image by replication, not (typical) stretching.
1284ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul * We use this when the image width or height is less than a
1285ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul * certain size (4, 8) and we need to upscale an image.
1286ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul */
1287ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paulstatic void
1288ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paulupscale_teximage2d(GLsizei inWidth, GLsizei inHeight,
1289ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul                   GLsizei outWidth, GLsizei outHeight,
1290960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul                   GLint comps, const GLubyte *src, GLint srcRowStride,
1291960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul                   GLubyte *dest )
1292ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul{
1293ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   GLint i, j, k;
1294ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul
1295ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   ASSERT(outWidth >= inWidth);
1296ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   ASSERT(outHeight >= inHeight);
1297ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul#if 0
1298ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
1299ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   ASSERT((outWidth & 3) == 0);
1300ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   ASSERT((outHeight & 3) == 0);
1301ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul#endif
1302ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul
1303ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   for (i = 0; i < outHeight; i++) {
1304ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul      const GLint ii = i % inHeight;
1305ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul      for (j = 0; j < outWidth; j++) {
1306ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul         const GLint jj = j % inWidth;
1307ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul         for (k = 0; k < comps; k++) {
1308ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul            dest[(i * outWidth + j) * comps + k]
1309ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul               = src[ii * srcRowStride + jj * comps + k];
1310ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul         }
1311ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul      }
1312ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul   }
1313ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul}
1314ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul
1315ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul
1316392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paulstatic void
131725b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_encode (GLuint width, GLuint height, GLint comps,
131825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul             const void *source, GLint srcRowStride,
131925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul             void *dest, GLint destRowStride)
13206db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
132125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint x, y;
132225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLubyte *data;
13232f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   GLuint *encoded = (GLuint *)dest;
1324392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul   void *newSource = NULL;
1325392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul
1326392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul   assert(comps == 3 || comps == 4);
13276db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
13283d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   /* Replicate image if width is not M8 or height is not M4 */
13293d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca   if ((width & 7) | (height & 3)) {
133025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint newWidth = (width + 7) & ~7;
133125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLint newHeight = (height + 3) & ~3;
1332960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      newSource = malloc(comps * newWidth * newHeight * sizeof(GLubyte));
1333392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      if (!newSource) {
1334392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         GET_CURRENT_CONTEXT(ctx);
1335392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture compression");
1336392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         goto cleanUp;
1337392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      }
1338ece8d6f25cac9c7ca0237cde3ebdb90e86c6118aBrian Paul      upscale_teximage2d(width, height, newWidth, newHeight,
1339960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul                         comps, (const GLubyte *) source,
1340960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul                         srcRowStride, (GLubyte *) newSource);
13416db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      source = newSource;
13426db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      width = newWidth;
13436db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      height = newHeight;
13446db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      srcRowStride = comps * newWidth;
13456db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
13466db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
134725b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   data = (const GLubyte *) source;
13486db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   destRowStride = (destRowStride - width * 2) / 4;
13496db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   for (y = 0; y < height; y += 4) {
135025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLuint offs = 0 + (y + 0) * srcRowStride;
13516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      for (x = 0; x < width; x += 8) {
135225b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         const GLubyte *lines[4];
1353e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lines[0] = &data[offs];
1354e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lines[1] = lines[0] + srcRowStride;
1355e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lines[2] = lines[1] + srcRowStride;
1356e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         lines[3] = lines[2] + srcRowStride;
1357e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca         offs += 8 * comps;
13586db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         fxt1_quantize(encoded, lines, comps);
13593d2b4bfa95c6a1d8c481f0ee2a18585c4d0627daDaniel Borca         /* 128 bits per 8x4 block */
13606db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         encoded += 4;
13616db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
13626db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      encoded += destRowStride;
13636db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
13646db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
1365392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul cleanUp:
1366e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   if (newSource != NULL) {
136732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(newSource);
1368e35282cc13acc61d1a789ab729ae6a0ea72aa17bDaniel Borca   }
1369c35dcfcf0adb335a28fdb1503447655dbb809927Daniel Borca}
13706db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
13716db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
13726db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca/***************************************************************************\
13736db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca * FXT1 decoder
13746db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca *
13756db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca * The decoder is based on GL_3DFX_texture_compression_FXT1
13766db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca * specification and serves as a concept for the encoder.
13776db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca\***************************************************************************/
13786db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
13796db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
13806db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca/* lookup table for scaling 5 bit colors up to 8 bits */
13812f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borcastatic const GLubyte _rgb_scale_5[] = {
13826db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   0,   8,   16,  25,  33,  41,  49,  58,
13836db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   66,  74,  82,  90,  99,  107, 115, 123,
13846db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   132, 140, 148, 156, 165, 173, 181, 189,
13856db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   197, 206, 214, 222, 230, 239, 247, 255
13866db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca};
13876db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
13886db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca/* lookup table for scaling 6 bit colors up to 8 bits */
13892f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borcastatic const GLubyte _rgb_scale_6[] = {
13906db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   0,   4,   8,   12,  16,  20,  24,  28,
13916db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   32,  36,  40,  45,  49,  53,  57,  61,
13926db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   65,  69,  73,  77,  81,  85,  89,  93,
13936db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   97,  101, 105, 109, 113, 117, 121, 125,
13946db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   130, 134, 138, 142, 146, 150, 154, 158,
13956db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   162, 166, 170, 174, 178, 182, 186, 190,
13966db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   194, 198, 202, 206, 210, 215, 219, 223,
13976db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   227, 231, 235, 239, 243, 247, 251, 255
13986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca};
13996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
140125b67e64049c291bd4e845c076d450653ba45f8dBrian Paul#define CC_SEL(cc, which) (((GLuint *)(cc))[(which) / 32] >> ((which) & 31))
14026db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca#define UP5(c) _rgb_scale_5[(c) & 31]
14036db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca#define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)]
14046db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca#define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n)
14056db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14066db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14076db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
1408960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paulfxt1_decode_1HI (const GLubyte *code, GLint t, GLubyte *rgba)
14096db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
141025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLuint *cc;
14116db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14126db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   t *= 3;
14132f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   cc = (const GLuint *)(code + t / 8);
14146db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   t = (cc[0] >> (t & 7)) & 7;
14156db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14166db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (t == 7) {
1417392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      rgba[RCOMP] = rgba[GCOMP] = rgba[BCOMP] = rgba[ACOMP] = 0;
14186db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   } else {
1419392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      GLubyte r, g, b;
14202f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca      cc = (const GLuint *)(code + 12);
14216db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t == 0) {
1422392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(CC_SEL(cc, 0));
1423392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP5(CC_SEL(cc, 5));
1424392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(CC_SEL(cc, 10));
14256db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else if (t == 6) {
1426392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(CC_SEL(cc, 15));
1427392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP5(CC_SEL(cc, 20));
1428392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(CC_SEL(cc, 25));
14296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else {
1430392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15)));
1431392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20)));
1432392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25)));
1433392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      }
1434960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[RCOMP] = r;
1435960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[GCOMP] = g;
1436960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[BCOMP] = b;
1437960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[ACOMP] = 255;
14386db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
14396db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
14406db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14416db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14426db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
1443960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paulfxt1_decode_1CHROMA (const GLubyte *code, GLint t, GLubyte *rgba)
14446db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
144525b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLuint *cc;
144625b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint kk;
14476db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14482f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   cc = (const GLuint *)code;
14496db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (t & 16) {
14506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      cc++;
14516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      t &= 15;
14526db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
14536db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   t = (cc[0] >> (t * 2)) & 3;
14546db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14556db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   t *= 15;
14562f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   cc = (const GLuint *)(code + 8 + t / 8);
14576db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   kk = cc[0] >> (t & 7);
1458960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[BCOMP] = UP5(kk);
1459960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[GCOMP] = UP5(kk >> 5);
1460960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[RCOMP] = UP5(kk >> 10);
1461960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[ACOMP] = 255;
14626db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
14636db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14646db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14656db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
1466960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paulfxt1_decode_1MIXED (const GLubyte *code, GLint t, GLubyte *rgba)
14676db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
146825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLuint *cc;
146925b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLuint col[2][3];
147025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint glsb, selb;
14716db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
14722f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   cc = (const GLuint *)code;
14736db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (t & 16) {
14746db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      t &= 15;
14756db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      t = (cc[1] >> (t * 2)) & 3;
14766db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* col 2 */
14772f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca      col[0][BCOMP] = (*(const GLuint *)(code + 11)) >> 6;
14786db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[0][GCOMP] = CC_SEL(cc, 99);
14796db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[0][RCOMP] = CC_SEL(cc, 104);
14806db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* col 3 */
14816db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[1][BCOMP] = CC_SEL(cc, 109);
14826db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[1][GCOMP] = CC_SEL(cc, 114);
14836db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[1][RCOMP] = CC_SEL(cc, 119);
14846db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      glsb = CC_SEL(cc, 126);
14856db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      selb = CC_SEL(cc, 33);
14866db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   } else {
14876db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      t = (cc[0] >> (t * 2)) & 3;
14886db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* col 0 */
14896db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[0][BCOMP] = CC_SEL(cc, 64);
14906db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[0][GCOMP] = CC_SEL(cc, 69);
14916db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[0][RCOMP] = CC_SEL(cc, 74);
14926db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* col 1 */
14936db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[1][BCOMP] = CC_SEL(cc, 79);
14946db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[1][GCOMP] = CC_SEL(cc, 84);
14956db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      col[1][RCOMP] = CC_SEL(cc, 89);
14966db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      glsb = CC_SEL(cc, 125);
14976db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      selb = CC_SEL(cc, 1);
14986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
14996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (CC_SEL(cc, 124) & 1) {
15016db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* alpha[0] == 1 */
15026db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15036db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t == 3) {
1504392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         /* zero */
1505392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         rgba[RCOMP] = rgba[BCOMP] = rgba[GCOMP] = rgba[ACOMP] = 0;
15066db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else {
1507392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         GLubyte r, g, b;
15086db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         if (t == 0) {
1509392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            b = UP5(col[0][BCOMP]);
1510392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            g = UP5(col[0][GCOMP]);
1511392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            r = UP5(col[0][RCOMP]);
15126db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         } else if (t == 2) {
1513392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            b = UP5(col[1][BCOMP]);
1514392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            g = UP6(col[1][GCOMP], glsb);
1515392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            r = UP5(col[1][RCOMP]);
15166db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         } else {
1517392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            b = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2;
1518392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            g = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2;
1519392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul            r = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2;
15206db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         }
1521960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul         rgba[RCOMP] = r;
1522960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul         rgba[GCOMP] = g;
1523960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul         rgba[BCOMP] = b;
1524960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul         rgba[ACOMP] = 255;
15256db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
15266db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   } else {
15276db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* alpha[0] == 0 */
1528392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      GLubyte r, g, b;
15296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t == 0) {
1530392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(col[0][BCOMP]);
1531392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP6(col[0][GCOMP], glsb ^ selb);
1532392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(col[0][RCOMP]);
15336db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else if (t == 3) {
1534392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(col[1][BCOMP]);
1535392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP6(col[1][GCOMP], glsb);
1536392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(col[1][RCOMP]);
15376db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else {
1538392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP]));
1539392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb),
1540392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul                        UP6(col[1][GCOMP], glsb));
1541392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP]));
1542392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul      }
1543960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[RCOMP] = r;
1544960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[GCOMP] = g;
1545960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[BCOMP] = b;
1546960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul      rgba[ACOMP] = 255;
15476db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
15486db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
15496db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borcastatic void
1552960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paulfxt1_decode_1ALPHA (const GLubyte *code, GLint t, GLubyte *rgba)
15536db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
155425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   const GLuint *cc;
1555392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul   GLubyte r, g, b, a;
15566db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15572f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   cc = (const GLuint *)code;
15586db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (CC_SEL(cc, 124) & 1) {
15596db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* lerp == 1 */
156025b67e64049c291bd4e845c076d450653ba45f8dBrian Paul      GLuint col0[4];
15616db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15626db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t & 16) {
15636db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         t &= 15;
15646db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         t = (cc[1] >> (t * 2)) & 3;
15656db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* col 2 */
15662f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca         col0[BCOMP] = (*(const GLuint *)(code + 11)) >> 6;
15676db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[GCOMP] = CC_SEL(cc, 99);
15686db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[RCOMP] = CC_SEL(cc, 104);
15696db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[ACOMP] = CC_SEL(cc, 119);
15706db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else {
15716db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         t = (cc[0] >> (t * 2)) & 3;
15726db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         /* col 0 */
15736db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[BCOMP] = CC_SEL(cc, 64);
15746db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[GCOMP] = CC_SEL(cc, 69);
15756db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[RCOMP] = CC_SEL(cc, 74);
15766db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         col0[ACOMP] = CC_SEL(cc, 109);
15776db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
15786db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15796db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t == 0) {
1580392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(col0[BCOMP]);
1581392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP5(col0[GCOMP]);
1582392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(col0[RCOMP]);
1583392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         a = UP5(col0[ACOMP]);
15846db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else if (t == 3) {
1585392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(CC_SEL(cc, 79));
1586392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP5(CC_SEL(cc, 84));
1587392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(CC_SEL(cc, 89));
1588392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         a = UP5(CC_SEL(cc, 114));
15896db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else {
1590392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79)));
1591392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84)));
1592392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89)));
1593392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         a = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114)));
15946db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
15956db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   } else {
15966db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      /* lerp == 0 */
15976db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
15986db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t & 16) {
15996db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         cc++;
16006db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         t &= 15;
16016db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
16026db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      t = (cc[0] >> (t * 2)) & 3;
16036db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
16046db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      if (t == 3) {
1605392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         /* zero */
160617d6fff30c6696b1624e1c019d31f22332c74622Brian Paul         r = g = b = a = 0;
16076db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      } else {
160825b67e64049c291bd4e845c076d450653ba45f8dBrian Paul         GLuint kk;
16092f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca         cc = (const GLuint *)code;
1610392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         a = UP5(cc[3] >> (t * 5 + 13));
16116db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         t *= 15;
16122f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca         cc = (const GLuint *)(code + 8 + t / 8);
16136db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca         kk = cc[0] >> (t & 7);
1614392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         b = UP5(kk);
1615392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         g = UP5(kk >> 5);
1616392c93e3987a11b00548fab7ed2b8ca1f969c8efBrian Paul         r = UP5(kk >> 10);
16176db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      }
16186db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
1619960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[RCOMP] = r;
1620960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[GCOMP] = g;
1621960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[BCOMP] = b;
1622960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   rgba[ACOMP] = a;
16236db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
16246db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
16256db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
162694ae2b4f25ba142da6b7c16a376156473f0d43e7Brian Paulvoid
162725b67e64049c291bd4e845c076d450653ba45f8dBrian Paulfxt1_decode_1 (const void *texture, GLint stride, /* in pixels */
1628960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul               GLint i, GLint j, GLubyte *rgba)
16296db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca{
1630960694fd2dbf1b40af2c4125145e42b3914f4b9fBrian Paul   static void (*decode_1[]) (const GLubyte *, GLint, GLubyte *) = {
16316db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1HI,     /* cc-high   = "00?" */
16326db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1HI,     /* cc-high   = "00?" */
16336db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1CHROMA, /* cc-chroma = "010" */
16346db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1ALPHA,  /* alpha     = "011" */
16356db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1MIXED,  /* mixed     = "1??" */
16366db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1MIXED,  /* mixed     = "1??" */
16376db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1MIXED,  /* mixed     = "1??" */
16386db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      fxt1_decode_1MIXED   /* mixed     = "1??" */
16396db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   };
16406db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
16412f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   const GLubyte *code = (const GLubyte *)texture +
164203501e7a29138e030b43746dcc71781b9652a113Daniel Borca                         ((j / 4) * (stride / 8) + (i / 8)) * 16;
16432f99f6558cd59fed6cbea3c6c8b08f53d74f6533Daniel Borca   GLint mode = CC_SEL(code, 125);
164425b67e64049c291bd4e845c076d450653ba45f8dBrian Paul   GLint t = i & 7;
16456db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
16466db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   if (t & 4) {
16476db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca      t += 12;
16486db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   }
16496db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   t += (j & 3) * 4;
16506db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca
16516db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca   decode_1[mode](code, t, rgba);
16526db87bc889ce33a1483ae2299e7e534c6fe235d6Daniel Borca}
165320e20fc5afa7525e247fd607e04d9adfffe730b4Chia-I Wu
165420e20fc5afa7525e247fd607e04d9adfffe730b4Chia-I Wu
165520e20fc5afa7525e247fd607e04d9adfffe730b4Chia-I Wu#endif /* FEATURE_texture_fxt1 */
1656