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