17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg *
4c1f859d4Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
57117f1b4Smrg *
67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
87117f1b4Smrg * to deal in the Software without restriction, including without limitation
97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
117117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
127117f1b4Smrg *
137117f1b4Smrg * The above copyright notice and this permission notice shall be included
147117f1b4Smrg * in all copies or substantial portions of the Software.
157117f1b4Smrg *
167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
267117f1b4Smrg/**
277117f1b4Smrg * \file texcompress_fxt1.c
283464ebd5Sriastradh * GL_3DFX_texture_compression_FXT1 support.
297117f1b4Smrg */
307117f1b4Smrg
317117f1b4Smrg
3201e04c3fSmrg#include "errors.h"
337117f1b4Smrg#include "glheader.h"
347ec681f3Smrg
357117f1b4Smrg#include "image.h"
363464ebd5Sriastradh#include "macros.h"
377117f1b4Smrg#include "mipmap.h"
387117f1b4Smrg#include "texcompress.h"
394a49301eSmrg#include "texcompress_fxt1.h"
407117f1b4Smrg#include "texstore.h"
4101e04c3fSmrg#include "mtypes.h"
427ec681f3Smrg#include "util/format/u_format_fxt1.h"
437117f1b4Smrg
447117f1b4Smrg/**
457ec681f3Smrg * Compress the user's image to either FXT1_RGB or FXT1_RGBA.
467117f1b4Smrg */
474a49301eSmrgGLboolean
487ec681f3Smrg_mesa_texstore_fxt1(TEXSTORE_PARAMS)
497117f1b4Smrg{
507ec681f3Smrg   const uint8_t *pixels;
517ec681f3Smrg   int32_t srcRowStride;
527ec681f3Smrg   uint8_t *dst;
537ec681f3Smrg   const uint8_t *tempImage = NULL;
547117f1b4Smrg
557ec681f3Smrg   assert(dstFormat == MESA_FORMAT_RGB_FXT1 || dstFormat == MESA_FORMAT_RGBA_FXT1);
567117f1b4Smrg
577117f1b4Smrg   if (srcFormat != GL_RGBA ||
58af69d88dSmrg       srcType != GL_UNSIGNED_BYTE ||
597117f1b4Smrg       ctx->_ImageTransferState ||
607117f1b4Smrg       srcPacking->SwapBytes) {
617ec681f3Smrg      /* convert image to RGBA/uint8_t */
627ec681f3Smrg      uint8_t *tempImageSlices[1];
637ec681f3Smrg      int rgbaRowStride = 4 * srcWidth * sizeof(uint8_t);
647ec681f3Smrg      tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(uint8_t));
657117f1b4Smrg      if (!tempImage)
667117f1b4Smrg         return GL_FALSE; /* out of memory */
677ec681f3Smrg      tempImageSlices[0] = (uint8_t *) tempImage;
6801e04c3fSmrg      _mesa_texstore(ctx, dims,
6901e04c3fSmrg                     baseInternalFormat,
707ec681f3Smrg                     MESA_FORMAT_RGBA_UNORM8,
7101e04c3fSmrg                     rgbaRowStride, tempImageSlices,
7201e04c3fSmrg                     srcWidth, srcHeight, srcDepth,
7301e04c3fSmrg                     srcFormat, srcType, srcAddr,
7401e04c3fSmrg                     srcPacking);
757117f1b4Smrg      pixels = tempImage;
767117f1b4Smrg      srcRowStride = 4 * srcWidth;
777117f1b4Smrg      srcFormat = GL_RGBA;
787117f1b4Smrg   }
797117f1b4Smrg   else {
80af69d88dSmrg      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
81af69d88dSmrg                                     srcFormat, srcType, 0, 0);
82af69d88dSmrg
837117f1b4Smrg      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
847ec681f3Smrg                                            srcType) / sizeof(uint8_t);
857117f1b4Smrg   }
867117f1b4Smrg
87af69d88dSmrg   dst = dstSlices[0];
887117f1b4Smrg
897ec681f3Smrg   if (dstFormat == MESA_FORMAT_RGB_FXT1)
907ec681f3Smrg      util_format_fxt1_rgb_pack_rgba_8unorm(dst, dstRowStride, pixels, srcRowStride, srcWidth, srcHeight);
917ec681f3Smrg   else
927ec681f3Smrg      util_format_fxt1_rgba_pack_rgba_8unorm(dst, dstRowStride, pixels, srcRowStride, srcWidth, srcHeight);
937117f1b4Smrg
94af69d88dSmrg   free((void*) tempImage);
957117f1b4Smrg
967117f1b4Smrg   return GL_TRUE;
977117f1b4Smrg}
987117f1b4Smrg
99af69d88dSmrgstatic void
1007ec681f3Smrgfetch_rgb_fxt1(const uint8_t *map,
1017ec681f3Smrg               int32_t rowStride, int32_t i, int32_t j, float *texel)
102af69d88dSmrg{
1037ec681f3Smrg   map += rowStride * (i / 8);
1047ec681f3Smrg   map += 16 * (j / 4);
1057ec681f3Smrg   util_format_fxt1_rgb_fetch_rgba(texel, map, i & 7, j & 3);
106af69d88dSmrg}
107af69d88dSmrg
108af69d88dSmrg
109af69d88dSmrgstatic void
1107ec681f3Smrgfetch_rgba_fxt1(const uint8_t *map,
1117ec681f3Smrg                int32_t rowStride, int32_t i, int32_t j, float *texel)
112af69d88dSmrg{
1137ec681f3Smrg   map += rowStride * (i / 8);
1147ec681f3Smrg   map += 16 * (j / 4);
1157ec681f3Smrg   util_format_fxt1_rgba_fetch_rgba(texel, map, i & 7, j & 3);
116af69d88dSmrg}
117af69d88dSmrg
118af69d88dSmrg
119af69d88dSmrgcompressed_fetch_func
120af69d88dSmrg_mesa_get_fxt_fetch_func(mesa_format format)
121af69d88dSmrg{
122af69d88dSmrg   switch (format) {
123af69d88dSmrg   case MESA_FORMAT_RGB_FXT1:
124af69d88dSmrg      return fetch_rgb_fxt1;
125af69d88dSmrg   case MESA_FORMAT_RGBA_FXT1:
126af69d88dSmrg      return fetch_rgba_fxt1;
127af69d88dSmrg   default:
128af69d88dSmrg      return NULL;
129af69d88dSmrg   }
130af69d88dSmrg}
131