replace color table FloatTable boolean with Type enum
[mesa.git] / src / mesa / main / texutil.c
index 47d320cf076e582af8f027e5f6009a8ef4b30b2e..40309d154c5d5f9eafa5866f71f17c66728e17e8 100644 (file)
@@ -1,10 +1,9 @@
-/* $Id: texutil.c,v 1.29 2002/06/05 16:48:54 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  4.0.3
+ * Version:  5.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  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"),
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *    Gareth Hughes <gareth@valinux.com>
+ *    Gareth Hughes
  */
 
-#ifdef PC_HEADER
-#include "all.h"
-#else
+/*
+ * Description:
+ * Functions for texture image conversion.  This takes care of converting
+ * typical GL_RGBA/GLubyte textures into hardware-specific formats.
+ * We can handle non-standard row strides and pixel unpacking parameters.
+ */
+
+
 #include "glheader.h"
+#include "colormac.h"
 #include "context.h"
 #include "enums.h"
 #include "image.h"
+#include "imports.h"
 #include "macros.h"
-#include "mem.h"
 #include "mtypes.h"
 #include "texformat.h"
 #include "texutil.h"
-#endif
+
 
 #define DEBUG_TEXUTIL 0
 
 
-#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+#ifdef MESA_BIG_ENDIAN
 #define APPEND16( a, b )       ( (a) << 16 | (b) )
 #else
 #define APPEND16( a, b )       ( (a) | (b) << 16 )
 #endif
 
 
-struct gl_texture_convert {
+struct convert_info {
    GLint xoffset, yoffset, zoffset;    /* Subimage offset */
    GLint width, height, depth;         /* Subimage region */
 
@@ -67,15 +72,16 @@ struct gl_texture_convert {
    GLint index;
 };
 
-typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
+typedef GLboolean (*convert_func)( const struct convert_info *convert );
 
+/* bitvalues for convert->index */
 #define CONVERT_STRIDE_BIT     0x1
 #define CONVERT_UNPACKING_BIT  0x2
 
 
 
 /* =============================================================
- * RGBA8888 textures:
+ * Convert to RGBA8888 textures:
  */
 
 #define DST_TYPE               GLuint
@@ -118,7 +124,7 @@ typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
 
 #define CONVERT_RGBA8888( name )                                       \
 static GLboolean                                                       \
-convert_##name##_rgba8888( struct gl_texture_convert *convert )                \
+convert_##name##_rgba8888( const struct convert_info *convert )                \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -154,7 +160,7 @@ CONVERT_RGBA8888( texsubimage3d )
 
 
 /* =============================================================
- * ARGB8888 textures:
+ * Convert to ARGB8888 textures:
  */
 
 #define DST_TYPE               GLuint
@@ -197,7 +203,7 @@ CONVERT_RGBA8888( texsubimage3d )
 
 #define CONVERT_ARGB8888( name )                                       \
 static GLboolean                                                       \
-convert_##name##_argb8888( struct gl_texture_convert *convert )                \
+convert_##name##_argb8888( const struct convert_info *convert )                \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -232,11 +238,11 @@ CONVERT_ARGB8888( texsubimage3d )
 
 
 /* =============================================================
- * RGB888 textures:
+ * Convert to RGB888 textures:
  */
 
 static GLboolean
-convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
+convert_texsubimage2d_rgb888( const struct convert_info *convert )
 {
    /* This is a placeholder for now...
     */
@@ -244,7 +250,7 @@ convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
 }
 
 static GLboolean
-convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
+convert_texsubimage3d_rgb888( const struct convert_info *convert )
 {
    /* This is a placeholder for now...
     */
@@ -254,7 +260,7 @@ convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
 
 
 /* =============================================================
- * RGB565 textures:
+ * Convert to RGB565 textures:
  */
 
 #define DST_TYPE               GLushort
@@ -301,7 +307,7 @@ convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
 
 #define CONVERT_RGB565( name )                                         \
 static GLboolean                                                       \
-convert_##name##_rgb565( struct gl_texture_convert *convert )          \
+convert_##name##_rgb565( const struct convert_info *convert )          \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -336,7 +342,7 @@ CONVERT_RGB565( texsubimage3d )
 
 
 /* =============================================================
- * ARGB4444 textures:
+ * Convert to ARGB4444 textures:
  */
 
 #define DST_TYPE               GLushort
@@ -369,7 +375,7 @@ CONVERT_RGB565( texsubimage3d )
 
 #define CONVERT_ARGB4444( name )                                       \
 static GLboolean                                                       \
-convert_##name##_argb4444( struct gl_texture_convert *convert )                \
+convert_##name##_argb4444( const struct convert_info *convert )                \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -399,7 +405,7 @@ CONVERT_ARGB4444( texsubimage3d )
 
 
 /* =============================================================
- * ARGB1555 textures:
+ * Convert to ARGB1555 textures:
  */
 
 #define DST_TYPE               GLushort
@@ -417,7 +423,7 @@ CONVERT_ARGB4444( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+#ifdef MESA_BIG_ENDIAN
 
 #define CONVERT_TEXEL( dst, src )                                      \
        { const GLushort s = *(GLushort *)src;                          \
@@ -463,7 +469,7 @@ CONVERT_ARGB4444( texsubimage3d )
 
 #define CONVERT_ARGB1555( name )                                       \
 static GLboolean                                                       \
-convert_##name##_argb1555( struct gl_texture_convert *convert )                \
+convert_##name##_argb1555( const struct convert_info *convert )                \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -559,7 +565,7 @@ CONVERT_ARGB1555( texsubimage3d )
 
 #define CONVERT_AL88( name )                                           \
 static GLboolean                                                       \
-convert_##name##_al88( struct gl_texture_convert *convert )            \
+convert_##name##_al88( const struct convert_info *convert )            \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -599,11 +605,11 @@ CONVERT_AL88( texsubimage3d )
 
 
 /* =============================================================
- * RGB332 textures:
+ * Convert to RGB332 textures:
  */
 
 static GLboolean
-convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
+convert_texsubimage2d_rgb332( const struct convert_info *convert )
 {
    /* This is a placeholder for now...
     */
@@ -611,7 +617,7 @@ convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
 }
 
 static GLboolean
-convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
+convert_texsubimage3d_rgb332( const struct convert_info *convert )
 {
    /* This is a placeholder for now...
     */
@@ -639,7 +645,7 @@ convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
 
 #define CONVERT_CI8( name )                                            \
 static GLboolean                                                       \
-convert_##name##_ci8( struct gl_texture_convert *convert )             \
+convert_##name##_ci8( const struct convert_info *convert )             \
 {                                                                      \
    convert_func *tab;                                                  \
    GLint index = convert->index;                                       \
@@ -665,12 +671,88 @@ CONVERT_CI8( texsubimage2d )
 CONVERT_CI8( texsubimage3d )
 
 
+/* =============================================================
+ * convert to YCBCR textures:
+ */
+
+#define DST_TYPE               GLushort
+#define DST_TEXELS_PER_DWORD   2
+
+#define CONVERT_TEXEL( dst, src ) \
+   dst = (src[0] << 8) | src[1];
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_ycbcr_direct
+#include "texutil_tmp.h"
+
+
+#define CONVERT_YCBCR( name )                                          \
+static GLboolean                                                       \
+convert_##name##_ycbcr( const struct convert_info *convert )           \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if (convert->format != GL_YCBCR_MESA) {                             \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+   tab = name##_tab_ycbcr_direct;                                      \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_YCBCR( texsubimage2d )
+CONVERT_YCBCR( texsubimage3d )
+
+
+/* =============================================================
+ * convert to YCBCR_REV textures:
+ */
+
+#define DST_TYPE               GLushort
+#define DST_TEXELS_PER_DWORD   2
+
+#define CONVERT_TEXEL( dst, src ) \
+   dst = (src[1] << 8) | src[0];
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_ycbcr_rev_direct
+#include "texutil_tmp.h"
+
+
+#define CONVERT_YCBCR_REV( name )                                      \
+static GLboolean                                                       \
+convert_##name##_ycbcr_rev( const struct convert_info *convert )       \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if (convert->format != GL_YCBCR_MESA) {                             \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+   tab = name##_tab_ycbcr_rev_direct;                                  \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_YCBCR_REV( texsubimage2d )
+CONVERT_YCBCR_REV( texsubimage3d )
+
+
 
 /* =============================================================
  * Global entry points
  */
 
-static convert_func gl_convert_texsubimage2d_tab[] = {
+static convert_func convert_texsubimage2d_tab[] = {
    convert_texsubimage2d_rgba8888,
    convert_texsubimage2d_argb8888,
    convert_texsubimage2d_rgb888,
@@ -683,9 +765,11 @@ static convert_func gl_convert_texsubimage2d_tab[] = {
    convert_texsubimage2d_ci8,
    convert_texsubimage2d_ci8,
    convert_texsubimage2d_ci8,
+   convert_texsubimage2d_ycbcr,
+   convert_texsubimage2d_ycbcr_rev,
 };
 
-static convert_func gl_convert_texsubimage3d_tab[] = {
+static convert_func convert_texsubimage3d_tab[] = {
    convert_texsubimage3d_rgba8888,
    convert_texsubimage3d_argb8888,
    convert_texsubimage3d_rgb888,
@@ -698,6 +782,8 @@ static convert_func gl_convert_texsubimage3d_tab[] = {
    convert_texsubimage3d_ci8,
    convert_texsubimage3d_ci8,
    convert_texsubimage3d_ci8,
+   convert_texsubimage3d_ycbcr,
+   convert_texsubimage3d_ycbcr_rev,
 };
 
 
@@ -735,14 +821,14 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
                             const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
-   struct gl_texture_convert convert;
+   struct convert_info convert;
 
    ASSERT( unpacking );
    ASSERT( srcImage );
    ASSERT( dstImage );
 
    ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
-   ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+   ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
 
    /* Make it easier to pass all the parameters around.
     */
@@ -761,7 +847,9 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
    if ( convert_needs_unpacking( unpacking, format, type ) )
       convert.index |= CONVERT_UNPACKING_BIT;
 
-   return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+   ASSERT(convert.index < 4);
+
+   return convert_texsubimage2d_tab[mesaFormat]( &convert );
 }
 
 
@@ -780,7 +868,7 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
  * with the _mesa_transfer_teximage() function.  That function will also
  * do image transfer operations such as scale/bias and convolution.
  *
- * Input:
+ * \param
  *   mesaFormat - one of the MESA_FORMAT_* values from texformat.h
  *   xoffset, yoffset - position in dest image to put data
  *   width, height - incoming image size, also size of dest region.
@@ -791,22 +879,22 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
  *   destImage - pointer to dest image
  */
 GLboolean
-_mesa_convert_texsubimage2d( GLint mesaFormat,
+_mesa_convert_texsubimage2d( GLint mesaFormat,  /* dest */
                             GLint xoffset, GLint yoffset,
                             GLint width, GLint height,
                             GLint destImageWidth,
-                            GLenum format, GLenum type,
+                            GLenum format, GLenum type,  /* source */
                             const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
-   struct gl_texture_convert convert;
+   struct convert_info convert;
 
    ASSERT( unpacking );
    ASSERT( srcImage );
    ASSERT( dstImage );
 
    ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
-   ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+   ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
 
    /* Make it easier to pass all the parameters around.
     */
@@ -829,26 +917,26 @@ _mesa_convert_texsubimage2d( GLint mesaFormat,
    if ( width != destImageWidth )
       convert.index |= CONVERT_STRIDE_BIT;
 
-   return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+   return convert_texsubimage2d_tab[mesaFormat]( &convert );
 }
 
 GLboolean
-_mesa_convert_texsubimage3d( GLint mesaFormat,
+_mesa_convert_texsubimage3d( GLint mesaFormat,  /* dest */
                             GLint xoffset, GLint yoffset, GLint zoffset,
                             GLint width, GLint height, GLint depth,
                             GLint dstImageWidth, GLint dstImageHeight,
-                            GLenum format, GLenum type,
+                            GLenum format, GLenum type,  /* source */
                             const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
-   struct gl_texture_convert convert;
+   struct convert_info convert;
 
    ASSERT( unpacking );
    ASSERT( srcImage );
    ASSERT( dstImage );
 
    ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
-   ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+   ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
 
    /* Make it easier to pass all the parameters around.
     */
@@ -874,7 +962,7 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
    if ( width != dstImageWidth || height != dstImageHeight )
       convert.index |= CONVERT_STRIDE_BIT;
 
-   return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
+   return convert_texsubimage3d_tab[mesaFormat]( &convert );
 }
 
 
@@ -905,9 +993,9 @@ do {                                                                        \
    const TYPE *src = (const TYPE *)srcImage;                           \
    TYPE *dst = (TYPE *)dstImage;                                       \
                                                                        \
-   if ( srcHeight <= dstHeight ) {                                     \
+   if ( srcHeight < dstHeight ) {                                      \
       const GLint hScale = dstHeight / srcHeight;                      \
-      if ( srcWidth <= dstWidth ) {                                    \
+      if ( srcWidth < dstWidth ) {                                     \
         const GLint wScale = dstWidth / srcWidth;                      \
         INNER_LOOP( TYPE, /, / );                                      \
       }                                                                        \
@@ -918,7 +1006,7 @@ do {                                                                       \
    }                                                                   \
    else {                                                              \
       const GLint hScale = srcHeight / dstHeight;                      \
-      if ( srcWidth <= dstWidth ) {                                    \
+      if ( srcWidth < dstWidth ) {                                     \
         const GLint wScale = dstWidth / srcWidth;                      \
         INNER_LOOP( TYPE, *, / );                                      \
       }                                                                        \