Overhaul of texture image handling.
[mesa.git] / src / mesa / main / texutil.c
index c3fca545f852f7f3b72d7c170576fda25ea8cf64..428af0384aa8dfcbebcffbfa48e37238dcf9ea74 100644 (file)
@@ -1,20 +1,21 @@
+/* $Id: texutil.c,v 1.11 2000/12/26 05:09:29 keithw Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.3
- * 
+ * Version:  3.4
+ *
  * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * to deal in the Software without restriction, including without limitation
  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  * and/or sell copies of the Software, and to permit persons to whom the
  * Software is furnished to do so, subject to the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice shall be included
  * in all copies or substantial portions of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
@@ -32,7 +33,7 @@
 #include "image.h"
 #include "mem.h"
 #include "texutil.h"
-#include "types.h"
+#include "mtypes.h"
 #endif
 
 
  *   GL_RGBA             GL_UNSIGNED_BYTE                 MESA_A4_R4_G4_B4
  *   GL_BGRA             GL_UNSIGNED_SHORT_4_4_4_4_REV    MESA_A4_R4_G4_B4
  *   GL_BGRA             GL_UNSIGHED_SHORT_1_5_5_5_REV    MESA_A1_R5_G5_B5
+ *   GL_RGBA             GL_UNSIGNED_BYTE                 MESA_A1_R5_G5_B5
  *   GL_BGRA             GL_UNSIGNED_INT_8_8_8_8_REV      MESA_A8_R8_G8_B8
+ *   GL_RGBA             GL_UNSIGNED_BYTE                 MESA_A8_R8_G8_B8
+ *   GL_RGB              GL_UNSIGNED_BYTE                 MESA_A8_R8_G8_B8
  *   more to be added for new drivers...
  *
  * Notes:
@@ -123,13 +127,18 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
             /* store as 8-bit texels */
             if (wScale == 1 && hScale == 1) {
                /* no scaling needed - fast case */
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                GLubyte *dst = (GLubyte *) dstImage;
                GLint row;
                for (row = 0; row < dstHeight; row++) {
+                 GLuint i;
+                 for (i = 0 ; i < dstWidth ; i++)
+                    fprintf(stderr, "%02x ", src[i]);
+                 fprintf(stderr, "\n");
                   MEMCPY(dst, src, dstWidth * sizeof(GLubyte));
                   dst += dstRowStride;
                   src += srcStride;
@@ -141,8 +150,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                             srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      dst[col] = src[col / wScale];
@@ -160,8 +170,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          else {
             /* store as 16-bit texels */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                GLushort *dst = (GLushort *) dstImage;
@@ -182,8 +193,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row, col;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                   for (col = 0; col < dstWidth; col++) {
@@ -203,8 +215,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                GLushort *dst = (GLushort *) dstImage;
@@ -221,8 +234,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLushort *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLushort *src = (const GLushort *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      dst[col] = src[col / wScale];
@@ -234,8 +248,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
 #ifdef DO_32BIT_STORES
@@ -286,8 +301,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      GLint col3 = (col / wScale) * 3;
@@ -305,8 +321,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case (used by Quake3) */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
 #ifdef DO_32BIT_STORES
@@ -357,8 +374,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -384,8 +402,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                GLushort *dst = (GLushort *) dstImage;
@@ -402,8 +421,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLushort *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLushort *src = (const GLushort *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      dst[col] = src[col / wScale];
@@ -415,8 +435,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
 #ifdef DO_32BIT_STORES
@@ -473,8 +494,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -499,11 +521,12 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
 
       case MESA_A1_R5_G5_B5:
          /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
-         if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
+         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                GLushort *dst = (GLushort *) dstImage;
@@ -520,8 +543,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLushort *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLushort *src = (const GLushort *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      dst[col] = src[col / wScale];
@@ -533,8 +557,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
                GLushort *dst = (GLushort *) dstImage;
@@ -561,8 +586,9 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -586,15 +612,17 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          break;
 
       case MESA_A8_R8_G8_B8:
+      case MESA_FF_R8_G8_B8:
          /* 32-bit texels */
          if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV){
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
-               GLuint *dst = dstImage;
+               GLuint *dst = (GLuint *) dstImage;
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   MEMCPY(dst, src, dstWidth * sizeof(GLuint));
@@ -604,12 +632,13 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
             }
             else {
                /* must rescale image */
-               GLuint *dst = dstImage;
+               GLuint *dst = (GLuint *) dstImage;
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLuint *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLuint *src = (const GLuint *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      dst[col] = src[col / wScale];
@@ -621,11 +650,12 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  srcWidth, srcFormat, srcType);
-               GLuint *dst = dstImage;
+               GLuint *dst = (GLuint *) dstImage;
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint col, col4;
@@ -642,12 +672,13 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
             }
             else {
                /* must rescale image */
-               GLuint *dst = dstImage;
+               GLuint *dst = (GLuint *) dstImage;
                GLint row;
                for (row = 0; row < dstHeight; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < dstWidth; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -661,13 +692,65 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                }
             }
          }
+         else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
+            /* general case */
+            if (wScale == 1 && hScale == 1) {
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
+               const GLint srcStride = _mesa_image_row_stride(packing,
+                                                 srcWidth, srcFormat, srcType);
+               GLuint *dst = (GLuint *) dstImage;
+               GLint row;
+               for (row = 0; row < dstHeight; row++) {
+                  GLint col, col3;
+                  for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
+                     GLubyte r = src[col3 + 0];
+                     GLubyte g = src[col3 + 1];
+                     GLubyte b = src[col3 + 2];
+                     GLubyte a = 255;
+                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
+                  }
+                  src += srcStride;
+                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
+               }
+            }
+            else {
+               /* must rescale image */
+               GLuint *dst = (GLuint *) dstImage;
+               GLint row;
+               for (row = 0; row < dstHeight; row++) {
+                  GLint srcRow = row / hScale;
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  GLint col;
+                  for (col = 0; col < dstWidth; col++) {
+                     GLint col3 = (col / wScale) * 3;
+                     GLubyte r = src[col3 + 0];
+                     GLubyte g = src[col3 + 1];
+                     GLubyte b = src[col3 + 2];
+                     GLubyte a = 255;
+                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
+                  }
+                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
+               }
+            }
+         }
          else {
             /* can't handle this source format/type combination */
             return GL_FALSE;
          }
+         if (dstFormat == MESA_FF_R8_G8_B8) {
+            /* set alpha bytes to 0xff */
+            GLint i;
+            GLubyte *dst = (GLubyte *) dstImage;
+            for (i = 0; i < dstWidth * dstHeight; i++) {
+               dst[i * 4 + 3] = 0xff;
+            }
+         }
          break;
 
-
       default:
          /* unexpected internal format! */
          return GL_FALSE;
@@ -681,11 +764,11 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
  * Replace a subregion of a texture image with new data.
  * Input:
  *   dstFormat - destination image format
- *   dstXoffset, dstYoffset - destination for new subregion
- *   dstWidth, dstHeight - total size of dest image
+ *   dstXoffset, dstYoffset - destination for new subregion (in texels)
+ *   dstWidth, dstHeight - total size of dest image (in texels)
  *   dstImage - pointer to dest image
- *   dstRowStride - bytes to jump between image rows
- *   width, height - size of region to copy/replace
+ *   dstRowStride - bytes to jump between image rows (in bytes)
+ *   width, height - size of region to copy/replace (in texels)
  *   srcWidth, srcHeight - size of the corresponding gl_texture_image
  *   srcFormat, srcType - source image format and datatype
  *   srcImage - source image
@@ -723,7 +806,7 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
    dstYoffset *= hScale;
 
    /* XXX hscale != 1 and wscale != 1 not tested!!!! */
-   
+
    switch (dstFormat) {
       case MESA_I8:
       case MESA_L8:
@@ -741,8 +824,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
             /* store as 8-bit texels */
             if (wScale == 1 && hScale == 1) {
                /* no scaling needed - fast case */
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                   width, srcFormat, srcType);
                GLubyte *dst = (GLubyte *) dstImage
@@ -761,8 +845,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      dst[col] = src[col / wScale];
@@ -780,8 +865,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          else {
             /* store as 16-bit texels */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -804,8 +890,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row, col;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                   for (col = 0; col < width; col++) {
@@ -825,8 +912,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -845,8 +933,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLushort *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLushort *src = (const GLushort *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      dst[col] = src[col / wScale];
@@ -858,8 +947,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -886,8 +976,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      GLint col3 = (col / wScale) * 3;
@@ -905,8 +996,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case (used by Quake3) */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -933,8 +1025,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -960,8 +1053,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -980,8 +1074,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLushort *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLushort *src = (const GLushort *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      dst[col] = src[col / wScale];
@@ -993,8 +1088,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -1023,8 +1119,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -1049,11 +1146,12 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
 
       case MESA_A1_R5_G5_B5:
          /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
-         if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
+         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -1072,8 +1170,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLushort *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLushort *src = (const GLushort *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      dst[col] = src[col / wScale];
@@ -1085,8 +1184,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLushort *dst = (GLushort *) ((GLubyte *) dstImage
@@ -1115,8 +1215,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      GLint col4 = (col / wScale) * 4;
@@ -1140,12 +1241,14 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
          break;
 
       case MESA_A8_R8_G8_B8:
+      case MESA_FF_R8_G8_B8:
          /* 32-bit texels */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV){
+         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) {
             /* special, optimized case */
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLuint *dst = (GLuint *) ((GLubyte *) dstImage
@@ -1164,8 +1267,9 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLuint *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLuint *src = (const GLuint *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      dst[col] = src[col / wScale];
@@ -1173,12 +1277,27 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                   dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
                }
             }
+            if (dstFormat == MESA_FF_R8_G8_B8) {
+               /* set alpha bytes to 0xff */
+               GLint row, col;
+               GLubyte *dst = (GLubyte *) dstImage
+                              + dstYoffset * dstRowStride + dstXoffset * 4;
+               assert(wScale == 1 && hScale == 1); /* XXX not done */
+               for (row = 0; row < height; row++) {
+                  for (col = 0; col < width; col++) {
+                     dst[col * 4 + 3] = 0xff;
+                  }
+                  dst = dst + dstRowStride;
+               }
+            }
          }
          else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
             /* general case */
+            const GLubyte aMask = (dstFormat==MESA_FF_R8_G8_B8) ? 0xff : 0x00;
             if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = _mesa_image_address(packing, srcImage,
-                             srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
+               const GLubyte *src = (const GLubyte *)
+                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
+                                      srcFormat, srcType, 0, 0, 0);
                const GLint srcStride = _mesa_image_row_stride(packing,
                                                  width, srcFormat, srcType);
                GLuint *dst = (GLuint *) ((GLubyte *) dstImage
@@ -1190,7 +1309,7 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                      GLubyte r = src[col4 + 0];
                      GLubyte g = src[col4 + 1];
                      GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
+                     GLubyte a = src[col4 + 3] | aMask;
                      dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
                   }
                   src += srcStride;
@@ -1204,15 +1323,16 @@ _mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
                GLint row;
                for (row = 0; row < height; row++) {
                   GLint srcRow = row / hScale;
-                  const GLubyte *src = _mesa_image_address(packing, srcImage,
-                        srcWidth, srcHeight, srcFormat, srcType, 0, srcRow, 0);
+                  const GLubyte *src = (const GLubyte *)
+                     _mesa_image_address(packing, srcImage, srcWidth,
+                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
                   GLint col;
                   for (col = 0; col < width; col++) {
                      GLint col4 = (col / wScale) * 4;
                      GLubyte r = src[col4 + 0];
                      GLubyte g = src[col4 + 1];
                      GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
+                     GLubyte a = src[col4 + 3] | aMask;
                      dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
                   }
                   dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
@@ -1281,7 +1401,7 @@ generate_lookup_tables(void)
       A4R4G4B4toRed[i]   = r;
       A4R4G4B4toGreen[i] = g;
       A4R4G4B4toBlue[i]  = b;
-      A4R4G4B4toAlpha[i] = b;
+      A4R4G4B4toAlpha[i] = a;
    }
 
    for (i = 0; i <= 0xffff; i++) {
@@ -1296,7 +1416,7 @@ generate_lookup_tables(void)
       A1R5G5B5toRed[i]   = r;
       A1R5G5B5toGreen[i] = g;
       A1R5G5B5toBlue[i]  = b;
-      A1R5G5B5toAlpha[i] = b;
+      A1R5G5B5toAlpha[i] = a;
    }
 }
 
@@ -1491,6 +1611,7 @@ _mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
          }
          break;
       case MESA_A8_R8_G8_B8:
+      case MESA_FF_R8_G8_B8:
          ASSERT(dstFormat == GL_RGBA);
          if (wScale == 1 && hScale == 1) {
             GLint i, n = dstWidth * dstHeight;
@@ -1546,6 +1667,7 @@ _mesa_set_teximage_component_sizes(MesaIntTexFormat mesaFormat,
       { MESA_A4_R4_G4_B4,  4, 4, 4, 4, 0, 0, 0 },
       { MESA_A1_R5_G5_B5,  5, 5, 5, 1, 0, 0, 0 },
       { MESA_A8_R8_G8_B8,  8, 8, 8, 8, 0, 0, 0 },
+      { MESA_FF_R8_G8_B8,  8, 8, 8, 8, 0, 0, 0 },
       { -1,                0, 0, 0, 0, 0, 0, 0 }
    };
    GLint i;