added _mesa_unconvert_teximage()
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 27 Mar 2000 18:56:26 +0000 (18:56 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 27 Mar 2000 18:56:26 +0000 (18:56 +0000)
src/mesa/main/texutil.c
src/mesa/main/texutil.h

index 3023113c1737c2f651af0c0caea7ce782401b5ed..a9c1f365ea76223bcbd087d53ff9fcd79e2f20b4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texutil.c,v 1.1 2000/03/24 20:54:21 brianp Exp $ */
+/* $Id: texutil.c,v 1.2 2000/03/27 18:56:26 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -29,6 +29,7 @@
 #include "all.h"
 #else
 #include "glheader.h"
+#include "context.h"
 #include "image.h"
 #include "mem.h"
 #include "texutil.h"
@@ -535,3 +536,285 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
    }
    return GL_TRUE;
 }
+
+
+/*
+ * Used to convert 16-bit texels into GLubyte color components.
+ */
+static GLubyte R5G6B5toRed[0xffff];
+static GLubyte R5G6B5toGreen[0xffff];
+static GLubyte R5G6B5toBlue[0xffff];
+
+static GLubyte A4R4G4B4toRed[0xffff];
+static GLubyte A4R4G4B4toGreen[0xffff];
+static GLubyte A4R4G4B4toBlue[0xffff];
+static GLubyte A4R4G4B4toAlpha[0xffff];
+
+static GLubyte A1R5G5B5toRed[0xffff];
+static GLubyte A1R5G5B5toGreen[0xffff];
+static GLubyte A1R5G5B5toBlue[0xffff];
+static GLubyte A1R5G5B5toAlpha[0xffff];
+
+static void
+generate_lookup_tables(void)
+{
+   GLint i;
+   for (i = 0; i <= 0xffff; i++) {
+      GLint r = (i >> 8) & 0xf8;
+      GLint g = (i >> 3) & 0xfc;
+      GLint b = (i << 3) & 0xf8;
+      r = r * 255 / 0xf8;
+      g = g * 255 / 0xfc;
+      b = b * 255 / 0xf8;
+      R5G6B5toRed[i]   = r;
+      R5G6B5toGreen[i] = g;
+      R5G6B5toBlue[i]  = b;
+   }
+
+   for (i = 0; i <= 0xffff; i++) {
+      GLint r = (i >>  8) & 0xf;
+      GLint g = (i >>  4) & 0xf;
+      GLint b = (i      ) & 0xf;
+      GLint a = (i >> 12) & 0xf;
+      r = r * 255 / 0xf;
+      g = g * 255 / 0xf;
+      b = b * 255 / 0xf;
+      a = a * 255 / 0xf;
+      A4R4G4B4toRed[i]   = r;
+      A4R4G4B4toGreen[i] = g;
+      A4R4G4B4toBlue[i]  = b;
+      A4R4G4B4toAlpha[i] = b;
+   }
+
+   for (i = 0; i <= 0xffff; i++) {
+      GLint r = (i >> 10) & 0xf8;
+      GLint g = (i >>  5) & 0xf8;
+      GLint b = (i      ) & 0xf8;
+      GLint a = (i >> 15) & 0x1;
+      r = r * 255 / 0xf8;
+      g = g * 255 / 0xf8;
+      b = b * 255 / 0xf8;
+      a = a * 255;
+      A1R5G5B5toRed[i]   = r;
+      A1R5G5B5toGreen[i] = g;
+      A1R5G5B5toBlue[i]  = b;
+      A1R5G5B5toAlpha[i] = b;
+   }
+}
+
+
+
+/*
+ * Convert a texture image from an internal format to one of Mesa's
+ * core internal formats.  This is likely to be used by glGetTexImage
+ * and for fetching texture images when falling back to software rendering.
+ *
+ * Notes:
+ *   This function will do power of two image down-scaling to accomodate
+ *   drivers with limited texture image aspect ratios.
+ *   The implicit dest data type is GL_UNSIGNED_BYTE.
+ */
+void
+_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
+                         GLint srcWidth, GLint srcHeight,
+                         const GLvoid *srcImage,
+                         GLsizei dstWidth, GLsizei dstHeight,
+                         GLenum dstFormat, GLubyte *dstImage)
+{
+   static GLboolean firstCall = GL_TRUE;
+   const GLint wScale = srcWidth / dstWidth;   /* must be power of two */
+   const GLint hScale = srcHeight / dstHeight; /* must be power of two */
+   ASSERT(srcWidth >= dstWidth);
+   ASSERT(srcHeight >= dstHeight);
+   ASSERT(dstImage);
+   ASSERT(srcImage);
+
+   if (firstCall) {
+      generate_lookup_tables();
+      firstCall = GL_FALSE;
+   }
+
+   switch (srcFormat) {
+      case MESA_I8:
+      case MESA_L8:
+      case MESA_A8:
+      case MESA_C8:
+#ifdef DEBUG
+         if (srcFormat == MESA_I8) {
+            ASSERT(dstFormat == GL_INTENSITY);
+         }
+         else if (srcFormat == MESA_L8) {
+            ASSERT(dstFormat == GL_LUMINANCE);
+         }
+         else if (srcFormat == MESA_A8) {
+            ASSERT(dstFormat == GL_ALPHA);
+         }
+         else if (srcFormat == MESA_C8) {
+            ASSERT(dstFormat == GL_COLOR_INDEX);
+         }
+#endif
+         if (wScale == 1 && hScale == 1) {
+            /* easy! */
+            MEMCPY(dstImage, srcImage, dstWidth * dstHeight * sizeof(GLubyte));
+         }
+         else {
+            /* rescale */
+            const GLubyte *src8 = (const GLubyte *) srcImage;
+            GLint row, col;
+            for (row = 0; row < dstHeight; row++) {
+               GLint srcRow = row * hScale;
+               for (col = 0; col < dstWidth; col++) {
+                  GLint srcCol = col * wScale;
+                  *dstImage++ = src8[srcRow * srcWidth + srcCol];
+               }
+            }
+         }
+         break;
+      case MESA_L8_A8:
+         ASSERT(dstFormat == GL_LUMINANCE_ALPHA);
+         if (wScale == 1 && hScale == 1) {
+            GLint i, n = dstWidth * dstHeight;
+            const GLushort *texel = (const GLushort *) srcImage;
+            for (i = 0; i < n; i++) {
+               const GLushort tex = *texel++;
+               *dstImage++ = (tex >> 8);   /* luminance */
+               *dstImage++ = (tex & 0xff); /* alpha */
+            }
+         }
+         else {
+            /* rescale */
+            const GLushort *src16 = (const GLushort *) srcImage;
+            GLint row, col;
+            for (row = 0; row < dstHeight; row++) {
+               GLint srcRow = row * hScale;
+               for (col = 0; col < dstWidth; col++) {
+                  GLint srcCol = col * wScale;
+                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
+                  *dstImage++ = (tex >> 8);   /* luminance */
+                  *dstImage++ = (tex & 0xff); /* alpha */
+               }
+            }
+         }
+         break;
+      case MESA_R5_G6_B5:
+         ASSERT(dstFormat == GL_RGB);
+         if (wScale == 1 && hScale == 1) {
+            GLint i, n = dstWidth * dstHeight;
+            const GLushort *texel = (const GLushort *) srcImage;
+            for (i = 0; i < n; i++) {
+               const GLushort tex = *texel++;
+               *dstImage++ = R5G6B5toRed[tex];
+               *dstImage++ = R5G6B5toGreen[tex];
+               *dstImage++ = R5G6B5toBlue[tex];
+            }
+         }
+         else {
+            /* rescale */
+            const GLushort *src16 = (const GLushort *) srcImage;
+            GLint row, col;
+            for (row = 0; row < dstHeight; row++) {
+               GLint srcRow = row * hScale;
+               for (col = 0; col < dstWidth; col++) {
+                  GLint srcCol = col * wScale;
+                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
+                  *dstImage++ = R5G6B5toRed[tex];
+                  *dstImage++ = R5G6B5toGreen[tex];
+                  *dstImage++ = R5G6B5toBlue[tex];
+               }
+            }
+         }
+         break;
+      case MESA_A4_R4_G4_B4:
+         ASSERT(dstFormat == GL_RGBA);
+         if (wScale == 1 && hScale == 1) {
+            GLint i, n = dstWidth * dstHeight;
+            const GLushort *texel = (const GLushort *) srcImage;
+            for (i = 0; i < n; i++) {
+               const GLushort tex = *texel++;
+               *dstImage++ = A4R4G4B4toRed[tex];
+               *dstImage++ = A4R4G4B4toGreen[tex];
+               *dstImage++ = A4R4G4B4toBlue[tex];
+               *dstImage++ = A4R4G4B4toAlpha[tex];
+            }
+         }
+         else {
+            /* rescale */
+            const GLushort *src16 = (const GLushort *) srcImage;
+            GLint row, col;
+            for (row = 0; row < dstHeight; row++) {
+               GLint srcRow = row * hScale;
+               for (col = 0; col < dstWidth; col++) {
+                  GLint srcCol = col * wScale;
+                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
+                  *dstImage++ = A4R4G4B4toRed[tex];
+                  *dstImage++ = A4R4G4B4toGreen[tex];
+                  *dstImage++ = A4R4G4B4toBlue[tex];
+                  *dstImage++ = A4R4G4B4toAlpha[tex];
+               }
+            }
+         }
+         break;
+      case MESA_A1_R5_G5_B5:
+         ASSERT(dstFormat == GL_RGBA);
+         if (wScale == 1 && hScale == 1) {
+            GLint i, n = dstWidth * dstHeight;
+            const GLushort *texel = (const GLushort *) srcImage;
+            for (i = 0; i < n; i++) {
+               const GLushort tex = *texel++;
+               *dstImage++ = A1R5G5B5toRed[tex];
+               *dstImage++ = A1R5G5B5toGreen[tex];
+               *dstImage++ = A1R5G5B5toBlue[tex];
+               *dstImage++ = A1R5G5B5toAlpha[tex];
+            }
+         }
+         else {
+            /* rescale */
+            const GLushort *src16 = (const GLushort *) srcImage;
+            GLint row, col;
+            for (row = 0; row < dstHeight; row++) {
+               GLint srcRow = row * hScale;
+               for (col = 0; col < dstWidth; col++) {
+                  GLint srcCol = col * wScale;
+                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
+                  *dstImage++ = A1R5G5B5toRed[tex];
+                  *dstImage++ = A1R5G5B5toGreen[tex];
+                  *dstImage++ = A1R5G5B5toBlue[tex];
+                  *dstImage++ = A1R5G5B5toAlpha[tex];
+               }
+            }
+         }
+         break;
+      case MESA_A8_R8_G8_B8:
+         ASSERT(dstFormat == GL_RGBA);
+         if (wScale == 1 && hScale == 1) {
+            GLint i, n = dstWidth * dstHeight;
+            const GLushort *texel = (const GLushort *) srcImage;
+            for (i = 0; i < n; i++) {
+               const GLuint tex = *texel++;
+               *dstImage++ = (tex >> 16) & 0xff; /* R */
+               *dstImage++ = (tex >>  8) & 0xff; /* G */
+               *dstImage++ = (tex      ) & 0xff; /* B */
+               *dstImage++ = (tex >> 24) & 0xff; /* A */
+            }
+         }
+         else {
+            /* rescale */
+            const GLushort *src16 = (const GLushort *) srcImage;
+            GLint row, col;
+            for (row = 0; row < dstHeight; row++) {
+               GLint srcRow = row * hScale;
+               for (col = 0; col < dstWidth; col++) {
+                  GLint srcCol = col * wScale;
+                  const GLuint tex = src16[srcRow * srcWidth + srcCol];
+                  *dstImage++ = (tex >> 16) & 0xff; /* R */
+                  *dstImage++ = (tex >>  8) & 0xff; /* G */
+                  *dstImage++ = (tex      ) & 0xff; /* B */
+                  *dstImage++ = (tex >> 24) & 0xff; /* A */
+               }
+            }
+         }
+         break;
+      default:
+         gl_problem(NULL, "bad srcFormat in _mesa_uncovert_teximage()");
+   }
+}
index afc6833c4497931d1ecbebd8d1f542ebf41c2d12..0e180af2b77469f40a149e6a649682081b4ba891 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texutil.h,v 1.1 2000/03/24 20:54:21 brianp Exp $ */
+/* $Id: texutil.h,v 1.2 2000/03/27 18:56:26 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -58,5 +58,13 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
                        const struct gl_pixelstore_attrib *packing);
 
 
+extern void
+_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
+                         GLint srcWidth, GLint srcHeight,
+                         const GLvoid *srcImage,
+                         GLsizei dstWidth, GLsizei dstHeight,
+                         GLenum dstFormat, GLubyte *dstImage);
+
+
 #endif