Header file clean-up:
[mesa.git] / src / mesa / main / texutil.c
index 22733c88586b6fc8025d68717312d37ad1958500..94c052facae45b48751a51ec31d88daf818127c6 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: texutil.c,v 1.18 2001/03/22 06:23:56 gareth Exp $ */
+/* $Id: texutil.c,v 1.33 2002/10/24 23:57:21 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  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"),
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#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 "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 DBG 0
+
+#define DEBUG_TEXUTIL 0
 
 
-struct gl_texture_convert {
+#ifdef MESA_BIG_ENDIAN
+#define APPEND16( a, b )       ( (a) << 16 | (b) )
+#else
+#define APPEND16( a, b )       ( (a) | (b) << 16 )
+#endif
+
+
+struct convert_info {
    GLint xoffset, yoffset, zoffset;    /* Subimage offset */
    GLint width, height, depth;         /* Subimage region */
 
@@ -52,7 +64,7 @@ struct gl_texture_convert {
                                         /* Needed for subimage replacement */
    GLenum format, type;                 /* Source (user) format and type */
 
-   const struct gl_pixelstore_attrib *packing;
+   const struct gl_pixelstore_attrib *unpacking;
 
    const GLvoid *srcImage;
    GLvoid *dstImage;
@@ -60,22 +72,23 @@ 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_PACKING_BIT    0x2
+#define CONVERT_UNPACKING_BIT  0x2
 
 
 
-/* ================================================================
- * RGBA8888 textures:
+/* =============================================================
+ * Convert to RGBA8888 textures:
  */
 
 #define DST_TYPE               GLuint
 #define DST_TEXELS_PER_DWORD   1
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
 
 #define CONVERT_DIRECT
 
@@ -86,10 +99,10 @@ typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], src[3] )
 
-#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+#define CONVERT_TEXEL_DWORD( dst, src )                CONVERT_TEXEL( dst, src )
 
 #define SRC_TEXEL_BYTES                4
 
@@ -98,10 +111,10 @@ typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], 0xff )
 
-#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+#define CONVERT_TEXEL_DWORD( dst, src )                CONVERT_TEXEL( dst, src )
 
 #define SRC_TEXEL_BYTES                3
 
@@ -111,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;                                       \
@@ -146,15 +159,15 @@ CONVERT_RGBA8888( texsubimage3d )
 
 
 
-/* ================================================================
- * ARGB8888 textures:
+/* =============================================================
+ * Convert to ARGB8888 textures:
  */
 
 #define DST_TYPE               GLuint
 #define DST_TEXELS_PER_DWORD   1
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
 
 #define CONVERT_DIRECT
 
@@ -165,10 +178,10 @@ CONVERT_RGBA8888( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_8888_LE( src[3], src[0], src[1], src[2] )
 
-#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+#define CONVERT_TEXEL_DWORD( dst, src )                CONVERT_TEXEL( dst, src )
 
 #define SRC_TEXEL_BYTES                4
 
@@ -177,10 +190,10 @@ CONVERT_RGBA8888( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_8888_LE( 0xff, src[0], src[1], src[2] )
 
-#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+#define CONVERT_TEXEL_DWORD( dst, src )                CONVERT_TEXEL( dst, src )
 
 #define SRC_TEXEL_BYTES                3
 
@@ -190,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;                                       \
@@ -224,12 +237,12 @@ 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...
     */
@@ -237,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...
     */
@@ -246,15 +259,15 @@ convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
 
 
 
-/* ================================================================
- * RGB565 textures:
+/* =============================================================
+ * Convert to RGB565 textures:
  */
 
 #define DST_TYPE               GLushort
 #define DST_TEXELS_PER_DWORD   2
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_565( src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
 
 #define CONVERT_DIRECT
 
@@ -265,12 +278,12 @@ convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_565( src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
 
-#define CONVERT_TEXEL_DWORD( src )                                     \
-               ((PACK_COLOR_565( src[0], src[1], src[2] )) |           \
-                (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ),    \
+                       PACK_COLOR_565_LE( src[3], src[4], src[5] ) )
 
 #define SRC_TEXEL_BYTES                3
 
@@ -279,12 +292,12 @@ convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_565( src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
 
-#define CONVERT_TEXEL_DWORD( src )                                     \
-               ((PACK_COLOR_565( src[0], src[1], src[2] )) |           \
-                (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ),    \
+                       PACK_COLOR_565_LE( src[4], src[5], src[6] ) )
 
 #define SRC_TEXEL_BYTES                4
 
@@ -294,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;                                       \
@@ -328,15 +341,15 @@ CONVERT_RGB565( texsubimage3d )
 
 
 
-/* ================================================================
- * ARGB4444 textures:
+/* =============================================================
+ * Convert to ARGB4444 textures:
  */
 
 #define DST_TYPE               GLushort
 #define DST_TEXELS_PER_DWORD   2
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
 
 #define CONVERT_DIRECT
 
@@ -347,22 +360,22 @@ CONVERT_RGB565( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
 
-#define CONVERT_TEXEL_DWORD( src )                                     \
-               ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) |  \
-                (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] ),   \
+                       PACK_COLOR_4444_LE( src[7], src[4], src[5], src[6] ) )
 
 #define SRC_TEXEL_BYTES                4
 
-#define TAG(x) x##_rgba8888_to_argb4444
+#define TAG(x) x##_abgr8888_to_argb4444
 #include "texutil_tmp.h"
 
 
 #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;                                       \
@@ -375,7 +388,7 @@ convert_##name##_argb4444( struct gl_texture_convert *convert )             \
    else if ( convert->format == GL_RGBA &&                             \
             convert->type == GL_UNSIGNED_BYTE )                        \
    {                                                                   \
-      tab = name##_tab_rgba8888_to_argb4444;                           \
+      tab = name##_tab_abgr8888_to_argb4444;                           \
    }                                                                   \
    else                                                                        \
    {                                                                   \
@@ -391,15 +404,15 @@ CONVERT_ARGB4444( texsubimage3d )
 
 
 
-/* ================================================================
- * ARGB1555 textures:
+/* =============================================================
+ * Convert to ARGB1555 textures:
  */
 
 #define DST_TYPE               GLushort
 #define DST_TEXELS_PER_DWORD   2
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
 
 #define CONVERT_DIRECT
 
@@ -410,22 +423,53 @@ CONVERT_ARGB4444( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+#ifdef MESA_BIG_ENDIAN
+
+#define CONVERT_TEXEL( dst, src )                                      \
+       { const GLushort s = *(GLushort *)src;                          \
+         dst = (s >> 9) | ((s & 0x1ff) << 7); }
+
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       { const GLuint s = ((fi_type *)src)->i;                         \
+         dst = (((s & 0xfe00fe00) >> 9) |                              \
+                ((s & 0x01ff01ff) << 7)); }
+
+#else
+
+#define CONVERT_TEXEL( dst, src )                                      \
+       { const GLushort s = *(GLushort *)src;                          \
+         dst = (s >> 1) | ((s & 1) << 15); }
+
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       { const GLuint s = ((fi_type *)src)->i;                         \
+         dst = (((s & 0xfffefffe) >> 1) |                              \
+                ((s & 0x00010001) << 15)); }
+
+#endif
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_rgba5551_to_argb1555
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
 
-#define CONVERT_TEXEL_DWORD( src )                                     \
-               ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) |  \
-                (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] ),   \
+                       PACK_COLOR_1555_LE( src[7], src[4], src[5], src[6] ) )
 
 #define SRC_TEXEL_BYTES                4
 
-#define TAG(x) x##_rgba8888_to_argb1555
+#define TAG(x) x##_abgr8888_to_argb1555
 #include "texutil_tmp.h"
 
 
 #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;                                       \
@@ -435,10 +479,15 @@ convert_##name##_argb1555( struct gl_texture_convert *convert )           \
    {                                                                   \
       tab = name##_tab_argb1555_direct;                                        \
    }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            convert->type == GL_UNSIGNED_SHORT_5_5_5_1 )               \
+   {                                                                   \
+      tab = name##_tab_rgba5551_to_argb1555;                           \
+   }                                                                   \
    else if ( convert->format == GL_RGBA &&                             \
             convert->type == GL_UNSIGNED_BYTE )                        \
    {                                                                   \
-      tab = name##_tab_rgba8888_to_argb1555;                           \
+      tab = name##_tab_abgr8888_to_argb1555;                           \
    }                                                                   \
    else                                                                        \
    {                                                                   \
@@ -454,15 +503,15 @@ CONVERT_ARGB1555( texsubimage3d )
 
 
 
-/* ================================================================
+/* =============================================================
  * AL88 textures:
  */
 
 #define DST_TYPE               GLushort
 #define DST_TEXELS_PER_DWORD   2
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_88( src[0], src[1] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_88_LE( src[0], src[1] )
 
 #define CONVERT_DIRECT
 
@@ -473,12 +522,12 @@ CONVERT_ARGB1555( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_88( src[0], 0x00 )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_88_LE( src[0], 0x00 )
 
-#define CONVERT_TEXEL_DWORD( src )                                     \
-               ((PACK_COLOR_88( src[0], 0x00 )) |                      \
-                (PACK_COLOR_88( src[1], 0x00 ) << 16))
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_88_LE( src[0], 0x00 ),                       \
+                       PACK_COLOR_88_LE( src[1], 0x00 ) )
 
 #define SRC_TEXEL_BYTES                1
 
@@ -487,22 +536,36 @@ CONVERT_ARGB1555( texsubimage3d )
 #include "texutil_tmp.h"
 
 
-#define CONVERT_TEXEL( src )                                           \
-               PACK_COLOR_88( 0xff, src[0] )
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_88_LE( 0xff, src[0] )
 
-#define CONVERT_TEXEL_DWORD( src )                                     \
-               ((PACK_COLOR_88( 0xff, src[0] )) |                      \
-                (PACK_COLOR_88( 0xff, src[1] ) << 16))
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_88_LE( 0xff, src[0] ),                       \
+                       PACK_COLOR_88_LE( 0xff, src[1] ) )
 
 #define SRC_TEXEL_BYTES                1
 
 #define TAG(x) x##_l8_to_al88
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( dst, src )                                      \
+       dst = PACK_COLOR_88_LE( src[3], src[0] )
+
+#define CONVERT_TEXEL_DWORD( dst, src )                                        \
+       dst = APPEND16( PACK_COLOR_88_LE( src[3], src[0] ),             \
+                       PACK_COLOR_88_LE( src[7], src[4] ) )
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_abgr8888_to_al88
 #include "texutil_tmp.h"
 
 
 #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;                                       \
@@ -522,6 +585,11 @@ convert_##name##_al88( struct gl_texture_convert *convert )                \
    {                                                                   \
       tab = name##_tab_l8_to_al88;                                     \
    }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_abgr8888_to_al88;                               \
+   }                                                                   \
    else                                                                        \
    {                                                                   \
       /* Can't handle this source format/type combination */           \
@@ -536,12 +604,12 @@ 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...
     */
@@ -549,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...
     */
@@ -558,14 +626,14 @@ convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
 
 
 
-/* ================================================================
+/* =============================================================
  * CI8 (and all other single-byte texel) textures:
  */
 
 #define DST_TYPE               GLubyte
 #define DST_TEXELS_PER_DWORD   4
 
-#define CONVERT_TEXEL( src )   src[0]
+#define CONVERT_TEXEL( dst, src )      dst = src[0]
 
 #define CONVERT_DIRECT
 
@@ -577,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;                                       \
@@ -603,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,
@@ -621,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,
@@ -636,28 +782,30 @@ static convert_func gl_convert_texsubimage3d_tab[] = {
    convert_texsubimage3d_ci8,
    convert_texsubimage3d_ci8,
    convert_texsubimage3d_ci8,
+   convert_texsubimage3d_ycbcr,
+   convert_texsubimage3d_ycbcr_rev,
 };
 
 
 /* See if we need to care about the pixel store attributes when we're
  * converting the texture image.  This should be stored as
- * packing->_SomeBoolean and updated when the values change, to avoid
+ * unpacking->_SomeBoolean and updated when the values change, to avoid
  * testing every time...
  */
 static INLINE GLboolean
-convert_needs_packing( const struct gl_pixelstore_attrib *packing,
+convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking,
                       GLenum format, GLenum type )
 {
-   if ( ( packing->Alignment == 1 ||
-         ( packing->Alignment == 4 &&  /* Pick up the common Q3A case... */
+   if ( ( unpacking->Alignment == 1 ||
+         ( unpacking->Alignment == 4 &&   /* Pick up the common Q3A case... */
            format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
-       packing->RowLength == 0 &&
-       packing->SkipPixels == 0 &&
-       packing->SkipRows == 0 &&
-       packing->ImageHeight == 0 &&
-       packing->SkipImages == 0 &&
-       packing->SwapBytes == GL_FALSE &&
-       packing->LsbFirst == GL_FALSE ) {
+       unpacking->RowLength == 0 &&
+       unpacking->SkipPixels == 0 &&
+       unpacking->SkipRows == 0 &&
+       unpacking->ImageHeight == 0 &&
+       unpacking->SkipImages == 0 &&
+       unpacking->SwapBytes == GL_FALSE &&
+       unpacking->LsbFirst == GL_FALSE ) {
       return GL_FALSE;
    } else {
       return GL_TRUE;
@@ -670,17 +818,17 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
                             GLint xoffset,
                             GLint width,
                             GLenum format, GLenum type,
-                            const struct gl_pixelstore_attrib *packing,
+                            const struct gl_pixelstore_attrib *unpacking,
                             const GLvoid *srcImage, GLvoid *dstImage )
 {
-   struct gl_texture_convert convert;
+   struct convert_info convert;
 
-   ASSERT( packing );
+   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.
     */
@@ -690,26 +838,27 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
    convert.height = 1;
    convert.format = format;
    convert.type = type;
-   convert.packing = packing;
+   convert.unpacking = unpacking;
    convert.srcImage = srcImage;
    convert.dstImage = dstImage;
 
    convert.index = 0;
 
-   if ( convert_needs_packing( packing, format, type ) )
-      convert.index |= CONVERT_PACKING_BIT;
+   if ( convert_needs_unpacking( unpacking, format, type ) )
+      convert.index |= CONVERT_UNPACKING_BIT;
+
+   ASSERT(convert.index < 4);
 
-   return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+   return convert_texsubimage2d_tab[mesaFormat]( &convert );
 }
 
 
-/*
- * Convert a user's 2D image into a texture image.  This basically repacks
- * pixel data into the special texture formats used by core Mesa and the DRI
- * drivers.  This function can do full images or subimages.
+/* Convert a user's 2D image into a texture image.  This basically
+ * repacks pixel data into the special texture formats used by core Mesa
+ * and the DRI drivers.  This function can do full images or subimages.
  *
- * We return a boolean because this function may not accept some kinds of
- * source image formats and/or types.  For example, if the incoming
+ * We return a boolean because this function may not accept some kinds
+ * of source image formats and/or types.  For example, if the incoming
  * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
  * be able to do the conversion.
  *
@@ -725,27 +874,27 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
  *   width, height - incoming image size, also size of dest region.
  *   dstImageWidth - width (row stride) of dest image in pixels
  *   format, type - incoming image format and type
- *   packing - describes incoming image packing
+ *   unpacking - describes incoming image unpacking
  *   srcImage - pointer to source image
  *   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,
-                            const struct gl_pixelstore_attrib *packing,
+                            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( packing );
+   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.
     */
@@ -756,38 +905,38 @@ _mesa_convert_texsubimage2d( GLint mesaFormat,
    convert.dstImageWidth = destImageWidth;
    convert.format = format;
    convert.type = type;
-   convert.packing = packing;
+   convert.unpacking = unpacking;
    convert.srcImage = srcImage;
    convert.dstImage = dstImage;
 
    convert.index = 0;
 
-   if ( convert_needs_packing( packing, format, type ) )
-      convert.index |= CONVERT_PACKING_BIT;
+   if ( convert_needs_unpacking( unpacking, format, type ) )
+      convert.index |= CONVERT_UNPACKING_BIT;
 
    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,
-                            const struct gl_pixelstore_attrib *packing,
+                            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( packing );
+   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.
     */
@@ -801,19 +950,19 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
    convert.dstImageHeight = dstImageHeight;
    convert.format = format;
    convert.type = type;
-   convert.packing = packing;
+   convert.unpacking = unpacking;
    convert.srcImage = srcImage;
    convert.dstImage = dstImage;
 
    convert.index = 0;
 
-   if ( convert_needs_packing( packing, format, type ) )
-      convert.index |= CONVERT_PACKING_BIT;
+   if ( convert_needs_unpacking( unpacking, format, type ) )
+      convert.index |= CONVERT_UNPACKING_BIT;
 
    if ( width != dstImageWidth || height != dstImageHeight )
       convert.index |= CONVERT_STRIDE_BIT;
 
-   return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
+   return convert_texsubimage3d_tab[mesaFormat]( &convert );
 }
 
 
@@ -822,20 +971,21 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
  * all aspect ratios).  This can be made a lot faster, but I don't
  * really care enough...
  */
-void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
+void _mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride,
                               GLint srcWidth, GLint srcHeight,
                               GLint dstWidth, GLint dstHeight,
                               const GLvoid *srcImage, GLvoid *dstImage )
 {
    GLint row, col;
 
-#define INNER_LOOP( HOP, WOP )                                         \
+#define INNER_LOOP( TYPE, HOP, WOP )                                   \
    for ( row = 0 ; row < dstHeight ; row++ ) {                         \
       GLint srcRow = row HOP hScale;                                   \
       for ( col = 0 ; col < dstWidth ; col++ ) {                       \
         GLint srcCol = col WOP wScale;                                 \
-        *dst++ = src[srcRow * srcWidth + srcCol];                      \
+        dst[col] = src[srcRow * srcWidth + srcCol];                    \
       }                                                                        \
+      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);                 \
    }                                                                   \
 
 #define RESCALE_IMAGE( TYPE )                                          \
@@ -847,27 +997,27 @@ do {                                                                      \
       const GLint hScale = dstHeight / srcHeight;                      \
       if ( srcWidth <= dstWidth ) {                                    \
         const GLint wScale = dstWidth / srcWidth;                      \
-        INNER_LOOP( /, / );                                            \
+        INNER_LOOP( TYPE, /, / );                                      \
       }                                                                        \
       else {                                                           \
         const GLint wScale = srcWidth / dstWidth;                      \
-        INNER_LOOP( /, * );                                            \
+        INNER_LOOP( TYPE, /, * );                                      \
       }                                                                        \
    }                                                                   \
    else {                                                              \
       const GLint hScale = srcHeight / dstHeight;                      \
       if ( srcWidth <= dstWidth ) {                                    \
         const GLint wScale = dstWidth / srcWidth;                      \
-        INNER_LOOP( *, / );                                            \
+        INNER_LOOP( TYPE, *, / );                                      \
       }                                                                        \
       else {                                                           \
         const GLint wScale = srcWidth / dstWidth;                      \
-        INNER_LOOP( *, * );                                            \
+        INNER_LOOP( TYPE, *, * );                                      \
       }                                                                        \
    }                                                                   \
 } while (0)
 
-   switch ( texFormat->TexelBytes ) {
+   switch ( bytesPerPixel ) {
    case 4:
       RESCALE_IMAGE( GLuint );
       break;
@@ -879,5 +1029,7 @@ do {                                                                       \
    case 1:
       RESCALE_IMAGE( GLubyte );
       break;
+   default:
+      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
    }
 }