added GL_SGIX/SGIS_pixel_texture
[mesa.git] / src / mesa / main / colortab.c
index 7d167e1bea781355b3d6a206e6dc29b7088d7a77..b94dbde8fd747bc0249f9d474050b73001f70a8f 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: colortab.c,v 1.2 1999/10/08 09:27:10 keithw Exp $ */
+/* $Id: colortab.c,v 1.10 2000/03/21 01:03:40 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
+ * Version:  3.3
  * 
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * 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"),
  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-/* $XFree86: xc/lib/GL/mesa/src/colortab.c,v 1.2 1999/04/04 00:20:21 dawes Exp $ */
-
-
-
 
 
 #ifdef PC_HEADER
 #include "all.h"
 #else
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
+#include "glheader.h"
 #include "colortab.h"
 #include "context.h"
+#include "image.h"
 #include "macros.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
 #endif
 
 
@@ -48,7 +40,8 @@
 /*
  * Return GL_TRUE if k is a power of two, else return GL_FALSE.
  */
-static GLboolean power_of_two( GLint k )
+static GLboolean
+power_of_two( GLint k )
 {
    GLint i, m = 1;
    for (i=0; i<32; i++) {
@@ -60,7 +53,8 @@ static GLboolean power_of_two( GLint k )
 }
 
 
-static GLint decode_internal_format( GLint format )
+static GLint
+decode_internal_format( GLint format )
 {
    switch (format) {
       case GL_ALPHA:
@@ -117,81 +111,95 @@ static GLint decode_internal_format( GLint format )
 }
 
 
-void gl_ColorTable( GLcontext *ctx, GLenum target,
-                    GLenum internalFormat, struct gl_image *table )
+void 
+_mesa_ColorTable( GLenum target, GLenum internalFormat,
+                  GLsizei width, GLenum format, GLenum type,
+                  const GLvoid *table )
 {
+   GET_CURRENT_CONTEXT(ctx);
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
    struct gl_texture_object *texObj;
+   struct gl_color_table *palette;
    GLboolean proxy = GL_FALSE;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorTable");
 
-   if (decode_internal_format(internalFormat) < 0) {
-      gl_error( ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)" );
-      return;
-   }
-
    switch (target) {
       case GL_TEXTURE_1D:
          texObj = texUnit->CurrentD[1];
+         palette = &texObj->Palette;
          break;
       case GL_TEXTURE_2D:
          texObj = texUnit->CurrentD[2];
+         palette = &texObj->Palette;
          break;
-      case GL_TEXTURE_3D_EXT:
+      case GL_TEXTURE_3D:
          texObj = texUnit->CurrentD[3];
+         palette = &texObj->Palette;
          break;
       case GL_PROXY_TEXTURE_1D:
          texObj = ctx->Texture.Proxy1D;
+         palette = &texObj->Palette;
          proxy = GL_TRUE;
          break;
       case GL_PROXY_TEXTURE_2D:
          texObj = ctx->Texture.Proxy2D;
+         palette = &texObj->Palette;
          proxy = GL_TRUE;
          break;
-      case GL_PROXY_TEXTURE_3D_EXT:
+      case GL_PROXY_TEXTURE_3D:
          texObj = ctx->Texture.Proxy3D;
+         palette = &texObj->Palette;
          proxy = GL_TRUE;
          break;
       case GL_SHARED_TEXTURE_PALETTE_EXT:
          texObj = NULL;
+         palette = &ctx->Texture.Palette;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glColorTableEXT(target)");
+         gl_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
          return;
    }
 
-   /* internalformat = just like glTexImage */
+   assert(palette);
+
+   if (!_mesa_is_legal_format_and_type(format, type)) {
+      gl_error(ctx, GL_INVALID_ENUM, "glColorTable(format or type)");
+      return;
+   }
+
+   if (decode_internal_format(internalFormat) < 0) {
+      gl_error( ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)" );
+      return;
+   }
 
-   if (table->Width < 1 || table->Width > MAX_TEXTURE_PALETTE_SIZE
-       || !power_of_two(table->Width)) {
-      gl_error(ctx, GL_INVALID_VALUE, "glColorTableEXT(width)");
+   if (width < 1 || width > MAX_TEXTURE_PALETTE_SIZE || !power_of_two(width)) {
+      gl_error(ctx, GL_INVALID_VALUE, "glColorTable(width)");
       if (proxy) {
-         texObj->PaletteSize = 0;
-         texObj->PaletteIntFormat = (GLenum) 0;
-         texObj->PaletteFormat = (GLenum) 0;
+         palette->Size = 0;
+         palette->IntFormat = (GLenum) 0;
+         palette->Format = (GLenum) 0;
       }
       return;
    }
 
+   palette->Size = width;
+   palette->IntFormat = internalFormat;
+   palette->Format = (GLenum) decode_internal_format(internalFormat);
+   if (!proxy) {
+      _mesa_unpack_ubyte_color_span(ctx, width, palette->Format,
+                                    palette->Table,  /* dest */
+                                    format, type, table,
+                                    &ctx->Unpack, GL_FALSE);
+   }
    if (texObj) {
       /* per-texture object palette */
-      texObj->PaletteSize = table->Width;
-      texObj->PaletteIntFormat = internalFormat;
-      texObj->PaletteFormat = (GLenum) decode_internal_format(internalFormat);
-      if (!proxy) {
-         MEMCPY(texObj->Palette, table->Data, table->Width*table->Components);
-         if (ctx->Driver.UpdateTexturePalette) {
-            (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
-         }
+      if (ctx->Driver.UpdateTexturePalette) {
+         (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
       }
    }
    else {
       /* shared texture palette */
-      ctx->Texture.PaletteSize = table->Width;
-      ctx->Texture.PaletteIntFormat = internalFormat;
-      ctx->Texture.PaletteFormat = (GLenum) decode_internal_format(internalFormat);
-      MEMCPY(ctx->Texture.Palette, table->Data, table->Width*table->Components);
       if (ctx->Driver.UpdateTexturePalette) {
          (*ctx->Driver.UpdateTexturePalette)( ctx, NULL );
       }
@@ -200,38 +208,171 @@ void gl_ColorTable( GLcontext *ctx, GLenum target,
 
 
 
-void gl_ColorSubTable( GLcontext *ctx, GLenum target,
-                       GLsizei start, struct gl_image *data )
+void
+_mesa_ColorSubTable( GLenum target, GLsizei start,
+                     GLsizei count, GLenum format, GLenum type,
+                     const GLvoid *table )
 {
-   /* XXX TODO */
-   gl_problem(ctx, "glColorSubTableEXT not implemented");
-   (void) target;
-   (void) start;
-   (void) data;
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_texture_object *texObj;
+   struct gl_color_table *palette;
+   GLint comps;
+   GLubyte *dest;
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorSubTable");
+
+   switch (target) {
+      case GL_TEXTURE_1D:
+         texObj = texUnit->CurrentD[1];
+         palette = &texObj->Palette;
+         break;
+      case GL_TEXTURE_2D:
+         texObj = texUnit->CurrentD[2];
+         palette = &texObj->Palette;
+         break;
+      case GL_TEXTURE_3D:
+         texObj = texUnit->CurrentD[3];
+         palette = &texObj->Palette;
+         break;
+      case GL_SHARED_TEXTURE_PALETTE_EXT:
+         texObj = NULL;
+         palette = &ctx->Texture.Palette;
+         break;
+      default:
+         gl_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
+         return;
+   }
+
+   assert(palette);
+
+   if (!_mesa_is_legal_format_and_type(format, type)) {
+      gl_error(ctx, GL_INVALID_ENUM, "glColorSubTable(format or type)");
+      return;
+   }
+
+   if (count < 1) {
+      gl_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
+      return;
+   }
+
+   comps = _mesa_components_in_format(format);
+   assert(comps > 0);  /* error should be caught sooner */
+
+   if (start + count > palette->Size) {
+      gl_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
+      return;
+   }
+   dest = palette->Table + start * comps * sizeof(GLubyte);
+   _mesa_unpack_ubyte_color_span(ctx, count, palette->Format, dest,
+                                 format, type, table,
+                                 &ctx->Unpack, GL_FALSE);
+
+   if (texObj) {
+      /* per-texture object palette */
+      if (ctx->Driver.UpdateTexturePalette) {
+         (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
+      }
+   }
+   else {
+      /* shared texture palette */
+      if (ctx->Driver.UpdateTexturePalette) {
+         (*ctx->Driver.UpdateTexturePalette)( ctx, NULL );
+      }
+   }
 }
 
 
 
-void gl_GetColorTable( GLcontext *ctx, GLenum target, GLenum format,
-                       GLenum type, GLvoid *table )
+void
+_mesa_GetColorTable( GLenum target, GLenum format,
+                     GLenum type, GLvoid *table )
 {
-   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetBooleanv");
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+   struct gl_color_table *palette;
+   GLubyte rgba[MAX_TEXTURE_PALETTE_SIZE][4];
+   GLint i;
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetColorTable");
 
    switch (target) {
       case GL_TEXTURE_1D:
+         palette = &texUnit->CurrentD[1]->Palette;
          break;
       case GL_TEXTURE_2D:
+         palette = &texUnit->CurrentD[2]->Palette;
          break;
-      case GL_TEXTURE_3D_EXT:
+      case GL_TEXTURE_3D:
+         palette = &texUnit->CurrentD[3]->Palette;
          break;
       case GL_SHARED_TEXTURE_PALETTE_EXT:
+         palette = &ctx->Texture.Palette;
          break;
       default:
-         gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableEXT(target)");
+         gl_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
          return;
    }
 
-   gl_problem(ctx, "glGetColorTableEXT not implemented!");
+   assert(palette);
+
+   switch (palette->Format) {
+      case GL_ALPHA:
+         for (i = 0; i < palette->Size; i++) {
+            rgba[i][RCOMP] = 0;
+            rgba[i][GCOMP] = 0;
+            rgba[i][BCOMP] = 0;
+            rgba[i][ACOMP] = palette->Table[i];
+         }
+         break;
+      case GL_LUMINANCE:
+         for (i = 0; i < palette->Size; i++) {
+            rgba[i][RCOMP] = palette->Table[i];
+            rgba[i][GCOMP] = palette->Table[i];
+            rgba[i][BCOMP] = palette->Table[i];
+            rgba[i][ACOMP] = 255;
+         }
+         break;
+      case GL_LUMINANCE_ALPHA:
+         for (i = 0; i < palette->Size; i++) {
+            rgba[i][RCOMP] = palette->Table[i*2+0];
+            rgba[i][GCOMP] = palette->Table[i*2+0];
+            rgba[i][BCOMP] = palette->Table[i*2+0];
+            rgba[i][ACOMP] = palette->Table[i*2+1];
+         }
+         break;
+      case GL_INTENSITY:
+         for (i = 0; i < palette->Size; i++) {
+            rgba[i][RCOMP] = palette->Table[i];
+            rgba[i][GCOMP] = palette->Table[i];
+            rgba[i][BCOMP] = palette->Table[i];
+            rgba[i][ACOMP] = 255;
+         }
+         break;
+      case GL_RGB:
+         for (i = 0; i < palette->Size; i++) {
+            rgba[i][RCOMP] = palette->Table[i*3+0];
+            rgba[i][GCOMP] = palette->Table[i*3+1];
+            rgba[i][BCOMP] = palette->Table[i*3+2];
+            rgba[i][ACOMP] = 255;
+         }
+         break;
+      case GL_RGBA:
+         for (i = 0; i < palette->Size; i++) {
+            rgba[i][RCOMP] = palette->Table[i*4+0];
+            rgba[i][GCOMP] = palette->Table[i*4+1];
+            rgba[i][BCOMP] = palette->Table[i*4+2];
+            rgba[i][ACOMP] = palette->Table[i*4+3];
+         }
+         break;
+      default:
+         gl_problem(ctx, "bad palette format in glGetColorTable");
+         return;
+   }
+
+   _mesa_pack_rgba_span(ctx, palette->Size, (const GLubyte (*)[]) rgba,
+                        format, type, table, &ctx->Pack, GL_FALSE);
+
    (void) format;
    (void) type;
    (void) table;
@@ -239,37 +380,46 @@ void gl_GetColorTable( GLcontext *ctx, GLenum target, GLenum format,
 
 
 
-void gl_GetColorTableParameterfv( GLcontext *ctx, GLenum target,
-                                  GLenum pname, GLfloat *params )
+void
+_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
 {
    GLint iparams[10];
-
-   gl_GetColorTableParameteriv( ctx, target, pname, iparams );
+   _mesa_GetColorTableParameteriv( target, pname, iparams );
    *params = (GLfloat) iparams[0];
 }
 
 
 
-void gl_GetColorTableParameteriv( GLcontext *ctx, GLenum target,
-                                  GLenum pname, GLint *params )
+void
+_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
 {
+   GET_CURRENT_CONTEXT(ctx);
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   struct gl_texture_object *texObj;
+   struct gl_color_table *palette;
 
    ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetColorTableParameter");
 
    switch (target) {
       case GL_TEXTURE_1D:
-         texObj = texUnit->CurrentD[1];
+         palette = &texUnit->CurrentD[1]->Palette;
          break;
       case GL_TEXTURE_2D:
-         texObj = texUnit->CurrentD[2];
+         palette = &texUnit->CurrentD[2]->Palette;
          break;
-      case GL_TEXTURE_3D_EXT:
-         texObj = texUnit->CurrentD[3];
+      case GL_TEXTURE_3D:
+         palette = &texUnit->CurrentD[3]->Palette;
+         break;
+      case GL_PROXY_TEXTURE_1D:
+         palette = &ctx->Texture.Proxy1D->Palette;
+         break;
+      case GL_PROXY_TEXTURE_2D:
+         palette = &ctx->Texture.Proxy2D->Palette;
+         break;
+      case GL_PROXY_TEXTURE_3D:
+         palette = &ctx->Texture.Proxy3D->Palette;
          break;
       case GL_SHARED_TEXTURE_PALETTE_EXT:
-         texObj = NULL;
+         palette = &ctx->Texture.Palette;
          break;
       default:
          gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
@@ -277,34 +427,28 @@ void gl_GetColorTableParameteriv( GLcontext *ctx, GLenum target,
    }
 
    switch (pname) {
-      case GL_COLOR_TABLE_FORMAT_EXT:
-         if (texObj)
-            *params = texObj->PaletteIntFormat;
-         else
-            *params = ctx->Texture.PaletteIntFormat;
-         break;
-      case GL_COLOR_TABLE_WIDTH_EXT:
-         if (texObj)
-            *params = texObj->PaletteSize;
-         else
-            *params = ctx->Texture.PaletteSize;
-         break;
-      case GL_COLOR_TABLE_RED_SIZE_EXT:
+      case GL_COLOR_TABLE_FORMAT:
+         *params = palette->IntFormat;
+         break;
+      case GL_COLOR_TABLE_WIDTH:
+         *params = palette->Size;
+         break;
+      case GL_COLOR_TABLE_RED_SIZE:
          *params = 8;
          break;
-      case GL_COLOR_TABLE_GREEN_SIZE_EXT:
+      case GL_COLOR_TABLE_GREEN_SIZE:
          *params = 8;
          break;
-      case GL_COLOR_TABLE_BLUE_SIZE_EXT:
+      case GL_COLOR_TABLE_BLUE_SIZE:
          *params = 8;
          break;
-      case GL_COLOR_TABLE_ALPHA_SIZE_EXT:
+      case GL_COLOR_TABLE_ALPHA_SIZE:
          *params = 8;
          break;
-      case GL_COLOR_TABLE_LUMINANCE_SIZE_EXT:
+      case GL_COLOR_TABLE_LUMINANCE_SIZE:
          *params = 8;
          break;
-      case GL_COLOR_TABLE_INTENSITY_SIZE_EXT:
+      case GL_COLOR_TABLE_INTENSITY_SIZE:
          *params = 8;
          break;
       default: