draw: Change slot from unsigned to int.
[mesa.git] / src / mesa / main / pack.c
index e86c7a4ebb1b2159378a59e6032a4f846a9fe2b3..d976e5aae0002c37fa1473c8b58e917630e835c3 100644 (file)
  */
 
 
+/*
+ * XXX: MSVC takes forever to compile this module for x86_64 unless we disable
+ * this global optimization.
+ *
+ * See also:
+ * - http://msdn.microsoft.com/en-us/library/1yk3ydd7.aspx
+ * - http://msdn.microsoft.com/en-us/library/chh3fb0k.aspx
+ */
+#if defined(_MSC_VER) && defined(_M_X64)
+#  pragma optimize( "g", off )
+#endif
+
+
 #include "glheader.h"
 #include "colormac.h"
 #include "enums.h"
@@ -39,6 +52,7 @@
 #include "pack.h"
 #include "pixeltransfer.h"
 #include "imports.h"
+#include "glformats.h"
 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
 
@@ -143,7 +157,7 @@ _mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
 
    /* Alloc dest storage */
    bytes = ((width + 7) / 8 * height);
-   buffer = (GLubyte *) malloc( bytes );
+   buffer = malloc( bytes );
    if (!buffer)
       return NULL;
 
@@ -448,8 +462,7 @@ get_type_min_max(GLenum type, GLfloat *min, GLfloat *max)
    }
 }
 
-/* Customization of integer packing.  We always treat src as uint, and can pack dst
- * as any integer type/format combo.
+/* Customization of unsigned integer packing.
  */
 #define SRC_TYPE GLuint
 
@@ -461,6 +474,14 @@ get_type_min_max(GLenum type, GLfloat *min, GLfloat *max)
 #undef SRC_CONVERT
 #undef FN_NAME
 
+#define DST_TYPE GLint
+#define SRC_CONVERT(x) MIN2(x, 0x7fffffff)
+#define FN_NAME pack_int_from_uint_rgba
+#include "pack_tmp.h"
+#undef DST_TYPE
+#undef SRC_CONVERT
+#undef FN_NAME
+
 #define DST_TYPE GLushort
 #define SRC_CONVERT(x) MIN2(x, 0xffff)
 #define FN_NAME pack_ushort_from_uint_rgba
@@ -493,33 +514,730 @@ get_type_min_max(GLenum type, GLfloat *min, GLfloat *max)
 #undef SRC_CONVERT
 #undef FN_NAME
 
+#undef SRC_TYPE
+
+static void
+_pack_rgba_span_from_uints_problem(struct gl_context *ctx,
+                                   GLenum dstFormat, GLenum dstType)
+{
+   _mesa_problem(ctx,
+                 "Unsupported type (%s) / format (%s) "
+                 "in _mesa_pack_rgba_span_from_uints",
+                 _mesa_lookup_enum_by_nr(dstType),
+                 _mesa_lookup_enum_by_nr(dstFormat));
+}
+
 void
-_mesa_pack_rgba_span_int(struct gl_context *ctx, GLuint n, GLuint rgba[][4],
-                         GLenum dstFormat, GLenum dstType,
-                         GLvoid *dstAddr)
+_mesa_pack_rgba_span_from_uints(struct gl_context *ctx, GLuint n, GLuint rgba[][4],
+                                GLenum dstFormat, GLenum dstType,
+                                GLvoid *dstAddr)
 {
+   GLuint i;
+
    switch(dstType) {
    case GL_UNSIGNED_INT:
-      pack_uint_from_uint_rgba(dstAddr, dstFormat, rgba, n);
+      pack_uint_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_INT:
+      pack_int_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_UNSIGNED_SHORT:
+      pack_ushort_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_SHORT:
+      pack_short_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_UNSIGNED_BYTE:
+      pack_ubyte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_BYTE:
+      pack_byte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_UNSIGNED_BYTE_3_3_2:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLubyte *dst = (GLubyte *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 7) << 5)
+                   | (MIN2(rgba[i][GCOMP], 7) << 2)
+                   | (MIN2(rgba[i][BCOMP], 3)     );
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_BYTE_2_3_3_REV:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLubyte *dst = (GLubyte *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 7)     )
+                   | (MIN2(rgba[i][GCOMP], 7) << 3)
+                   | (MIN2(rgba[i][BCOMP], 3) << 6);
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_5_6_5:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 31) << 11)
+                   | (MIN2(rgba[i][GCOMP], 63) <<  5)
+                   | (MIN2(rgba[i][BCOMP], 31)      );
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_5_6_5_REV:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 31)      )
+                   | (MIN2(rgba[i][GCOMP], 63) <<  5)
+                   | (MIN2(rgba[i][BCOMP], 31) << 11);
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_4_4_4_4:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 15) << 12)
+                   | (MIN2(rgba[i][GCOMP], 15) <<  8)
+                   | (MIN2(rgba[i][BCOMP], 15) <<  4)
+                   | (MIN2(rgba[i][ACOMP], 15)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 15) << 12)
+                   | (MIN2(rgba[i][GCOMP], 15) <<  8)
+                   | (MIN2(rgba[i][RCOMP], 15) <<  4)
+                   | (MIN2(rgba[i][ACOMP], 15)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 15) << 12)
+                   | (MIN2(rgba[i][BCOMP], 15) <<  8)
+                   | (MIN2(rgba[i][GCOMP], 15) <<  4)
+                   | (MIN2(rgba[i][RCOMP], 15)      );
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 15)      )
+                   | (MIN2(rgba[i][GCOMP], 15) <<  4)
+                   | (MIN2(rgba[i][BCOMP], 15) <<  8)
+                   | (MIN2(rgba[i][ACOMP], 15) << 12);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 15)      )
+                   | (MIN2(rgba[i][GCOMP], 15) <<  4)
+                   | (MIN2(rgba[i][RCOMP], 15) <<  8)
+                   | (MIN2(rgba[i][ACOMP], 15) << 12);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 15)      )
+                   | (MIN2(rgba[i][BCOMP], 15) <<  4)
+                   | (MIN2(rgba[i][GCOMP], 15) <<  8)
+                   | (MIN2(rgba[i][RCOMP], 15) << 12);
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_5_5_5_1:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 31) << 11)
+                   | (MIN2(rgba[i][GCOMP], 31) <<  6)
+                   | (MIN2(rgba[i][BCOMP], 31) <<  1)
+                   | (MIN2(rgba[i][ACOMP],  1)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 31) << 11)
+                   | (MIN2(rgba[i][GCOMP], 31) <<  6)
+                   | (MIN2(rgba[i][RCOMP], 31) <<  1)
+                   | (MIN2(rgba[i][ACOMP],  1)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 31) << 11)
+                   | (MIN2(rgba[i][BCOMP], 31) <<  6)
+                   | (MIN2(rgba[i][GCOMP], 31) <<  1)
+                   | (MIN2(rgba[i][RCOMP],  1)      );
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 31)      )
+                   | (MIN2(rgba[i][GCOMP], 31) <<  5)
+                   | (MIN2(rgba[i][BCOMP], 31) << 10)
+                   | (MIN2(rgba[i][ACOMP],  1) << 15);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 31)      )
+                   | (MIN2(rgba[i][GCOMP], 31) <<  5)
+                   | (MIN2(rgba[i][RCOMP], 31) << 10)
+                   | (MIN2(rgba[i][ACOMP],  1) << 15);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 31)      )
+                   | (MIN2(rgba[i][BCOMP], 31) <<  5)
+                   | (MIN2(rgba[i][GCOMP], 31) << 10)
+                   | (MIN2(rgba[i][RCOMP],  1) << 15);
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_8_8_8_8:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 255) << 24)
+                   | (MIN2(rgba[i][GCOMP], 255) << 16)
+                   | (MIN2(rgba[i][BCOMP], 255) <<  8)
+                   | (MIN2(rgba[i][ACOMP], 255)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 255) << 24)
+                   | (MIN2(rgba[i][GCOMP], 255) << 16)
+                   | (MIN2(rgba[i][RCOMP], 255) <<  8)
+                   | (MIN2(rgba[i][ACOMP], 255)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 255) << 24)
+                   | (MIN2(rgba[i][BCOMP], 255) << 16)
+                   | (MIN2(rgba[i][GCOMP], 255) <<  8)
+                   | (MIN2(rgba[i][RCOMP], 255)      );
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_8_8_8_8_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 255)      )
+                   | (MIN2(rgba[i][GCOMP], 255) <<  8)
+                   | (MIN2(rgba[i][BCOMP], 255) << 16)
+                   | (MIN2(rgba[i][ACOMP], 255) << 24);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 255)      )
+                   | (MIN2(rgba[i][GCOMP], 255) <<  8)
+                   | (MIN2(rgba[i][RCOMP], 255) << 16)
+                   | (MIN2(rgba[i][ACOMP], 255) << 24);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 255)      )
+                   | (MIN2(rgba[i][BCOMP], 255) <<  8)
+                   | (MIN2(rgba[i][GCOMP], 255) << 16)
+                   | (MIN2(rgba[i][RCOMP], 255) << 24);
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_10_10_10_2:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 1023) << 22)
+                   | (MIN2(rgba[i][GCOMP], 1023) << 12)
+                   | (MIN2(rgba[i][BCOMP], 1023) <<  2)
+                   | (MIN2(rgba[i][ACOMP],    3)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 1023) << 22)
+                   | (MIN2(rgba[i][GCOMP], 1023) << 12)
+                   | (MIN2(rgba[i][RCOMP], 1023) <<  2)
+                   | (MIN2(rgba[i][ACOMP],    3)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 1023) << 22)
+                   | (MIN2(rgba[i][BCOMP], 1023) << 12)
+                   | (MIN2(rgba[i][GCOMP], 1023) <<  2)
+                   | (MIN2(rgba[i][RCOMP],    3)      );
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_2_10_10_10_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][RCOMP], 1023)      )
+                   | (MIN2(rgba[i][GCOMP], 1023) << 10)
+                   | (MIN2(rgba[i][BCOMP], 1023) << 20)
+                   | (MIN2(rgba[i][ACOMP],    3) << 30);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][BCOMP], 1023)      )
+                   | (MIN2(rgba[i][GCOMP], 1023) << 10)
+                   | (MIN2(rgba[i][RCOMP], 1023) << 20)
+                   | (MIN2(rgba[i][ACOMP],    3) << 30);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (MIN2(rgba[i][ACOMP], 1023)      )
+                   | (MIN2(rgba[i][BCOMP], 1023) << 10)
+                   | (MIN2(rgba[i][GCOMP], 1023) << 20)
+                   | (MIN2(rgba[i][RCOMP],    3) << 30);
+         }
+      } else {
+         _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   default:
+      _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType);
+      return;
+   }
+}
+
+
+/* Customization of signed integer packing.
+ */
+#define SRC_TYPE GLint
+
+#define DST_TYPE GLuint
+#define SRC_CONVERT(x) MAX2(x, 0)
+#define FN_NAME pack_uint_from_int_rgba
+#include "pack_tmp.h"
+#undef DST_TYPE
+#undef SRC_CONVERT
+#undef FN_NAME
+
+#define DST_TYPE GLushort
+#define SRC_CONVERT(x) MAX2(x, 0)
+#define FN_NAME pack_ushort_from_int_rgba
+#include "pack_tmp.h"
+#undef DST_TYPE
+#undef SRC_CONVERT
+#undef FN_NAME
+
+#define DST_TYPE GLshort
+#define SRC_CONVERT(x) CLAMP(x, -0x8000, 0x7fff)
+#define FN_NAME pack_short_from_int_rgba
+#include "pack_tmp.h"
+#undef DST_TYPE
+#undef SRC_CONVERT
+#undef FN_NAME
+
+#define DST_TYPE GLubyte
+#define SRC_CONVERT(x) MAX2(x, 0)
+#define FN_NAME pack_ubyte_from_int_rgba
+#include "pack_tmp.h"
+#undef DST_TYPE
+#undef SRC_CONVERT
+#undef FN_NAME
+
+#define DST_TYPE GLbyte
+#define SRC_CONVERT(x) CLAMP(x, -0x80, 0x7f)
+#define FN_NAME pack_byte_from_int_rgba
+#include "pack_tmp.h"
+#undef DST_TYPE
+#undef SRC_CONVERT
+#undef FN_NAME
+
+#undef SRC_TYPE
+
+static void
+_pack_rgba_span_from_ints_problem(struct gl_context *ctx,
+                                   GLenum dstFormat, GLenum dstType)
+{
+   _mesa_problem(ctx,
+                 "Unsupported type (%s) / format (%s) "
+                 "in _mesa_pack_rgba_span_from_ints",
+                 _mesa_lookup_enum_by_nr(dstType),
+                 _mesa_lookup_enum_by_nr(dstFormat));
+}
+
+void
+_mesa_pack_rgba_span_from_ints(struct gl_context *ctx, GLuint n, GLint rgba[][4],
+                               GLenum dstFormat, GLenum dstType,
+                               GLvoid *dstAddr)
+{
+   GLuint i;
+
+   switch(dstType) {
+   case GL_UNSIGNED_INT:
+      pack_uint_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n);
       break;
    case GL_INT:
       /* No conversion necessary. */
-      pack_uint_from_uint_rgba(dstAddr, dstFormat, rgba, n);
+      pack_uint_from_uint_rgba(ctx, dstAddr, dstFormat, (GLuint (*)[4]) rgba, n);
       break;
    case GL_UNSIGNED_SHORT:
-      pack_ushort_from_uint_rgba(dstAddr, dstFormat, rgba, n);
+      pack_ushort_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n);
       break;
    case GL_SHORT:
-      pack_short_from_uint_rgba(dstAddr, dstFormat, rgba, n);
+      pack_short_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n);
       break;
    case GL_UNSIGNED_BYTE:
-      pack_ubyte_from_uint_rgba(dstAddr, dstFormat, rgba, n);
+      pack_ubyte_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n);
       break;
    case GL_BYTE:
-      pack_byte_from_uint_rgba(dstAddr, dstFormat, rgba, n);
+      pack_byte_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n);
+      break;
+   case GL_UNSIGNED_BYTE_3_3_2:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLubyte *dst = (GLubyte *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 7) << 5)
+                   | (CLAMP(rgba[i][GCOMP], 0, 7) << 2)
+                   | (CLAMP(rgba[i][BCOMP], 0, 3)     );
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_BYTE_2_3_3_REV:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLubyte *dst = (GLubyte *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 7)     )
+                   | (CLAMP(rgba[i][GCOMP], 0, 7) << 3)
+                   | (CLAMP(rgba[i][BCOMP], 0, 3) << 6);
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_5_6_5:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31) << 11)
+                   | (CLAMP(rgba[i][GCOMP], 0, 63) <<  5)
+                   | (CLAMP(rgba[i][BCOMP], 0, 31)      );
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_5_6_5_REV:
+      if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 63) <<  5)
+                   | (CLAMP(rgba[i][BCOMP], 0, 31) << 11);
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_4_4_4_4:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 15) << 12)
+                   | (CLAMP(rgba[i][GCOMP], 0, 15) <<  8)
+                   | (CLAMP(rgba[i][BCOMP], 0, 15) <<  4)
+                   | (CLAMP(rgba[i][ACOMP], 0, 15)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 15) << 12)
+                   | (CLAMP(rgba[i][GCOMP], 0, 15) <<  8)
+                   | (CLAMP(rgba[i][RCOMP], 0, 15) <<  4)
+                   | (CLAMP(rgba[i][ACOMP], 0, 15)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 15) << 12)
+                   | (CLAMP(rgba[i][BCOMP], 0, 15) <<  8)
+                   | (CLAMP(rgba[i][GCOMP], 0, 15) <<  4)
+                   | (CLAMP(rgba[i][RCOMP], 0, 15)      );
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 15)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 15) <<  4)
+                   | (CLAMP(rgba[i][BCOMP], 0, 15) <<  8)
+                   | (CLAMP(rgba[i][ACOMP], 0, 15) << 12);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 15)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 15) <<  4)
+                   | (CLAMP(rgba[i][RCOMP], 0, 15) <<  8)
+                   | (CLAMP(rgba[i][ACOMP], 0, 15) << 12);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 15)      )
+                   | (CLAMP(rgba[i][BCOMP], 0, 15) <<  4)
+                   | (CLAMP(rgba[i][GCOMP], 0, 15) <<  8)
+                   | (CLAMP(rgba[i][RCOMP], 0, 15) << 12);
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_5_5_5_1:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31) << 11)
+                   | (CLAMP(rgba[i][GCOMP], 0, 31) <<  6)
+                   | (CLAMP(rgba[i][BCOMP], 0, 31) <<  1)
+                   | (CLAMP(rgba[i][ACOMP], 0,  1)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 31) << 11)
+                   | (CLAMP(rgba[i][GCOMP], 0, 31) <<  6)
+                   | (CLAMP(rgba[i][RCOMP], 0, 31) <<  1)
+                   | (CLAMP(rgba[i][ACOMP], 0,  1)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 31) << 11)
+                   | (CLAMP(rgba[i][BCOMP], 0, 31) <<  6)
+                   | (CLAMP(rgba[i][GCOMP], 0, 31) <<  1)
+                   | (CLAMP(rgba[i][RCOMP], 0,  1)      );
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 31) <<  5)
+                   | (CLAMP(rgba[i][BCOMP], 0, 31) << 10)
+                   | (CLAMP(rgba[i][ACOMP], 0,  1) << 15);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 31)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 31) <<  5)
+                   | (CLAMP(rgba[i][RCOMP], 0, 31) << 10)
+                   | (CLAMP(rgba[i][ACOMP], 0,  1) << 15);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLushort *dst = (GLushort *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 31)      )
+                   | (CLAMP(rgba[i][BCOMP], 0, 31) <<  5)
+                   | (CLAMP(rgba[i][GCOMP], 0, 31) << 10)
+                   | (CLAMP(rgba[i][RCOMP], 0,  1) << 15);
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_8_8_8_8:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 255) << 24)
+                   | (CLAMP(rgba[i][GCOMP], 0, 255) << 16)
+                   | (CLAMP(rgba[i][BCOMP], 0, 255) <<  8)
+                   | (CLAMP(rgba[i][ACOMP], 0, 255)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 255) << 24)
+                   | (CLAMP(rgba[i][GCOMP], 0, 255) << 16)
+                   | (CLAMP(rgba[i][RCOMP], 0, 255) <<  8)
+                   | (CLAMP(rgba[i][ACOMP], 0, 255)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 255) << 24)
+                   | (CLAMP(rgba[i][BCOMP], 0, 255) << 16)
+                   | (CLAMP(rgba[i][GCOMP], 0, 255) <<  8)
+                   | (CLAMP(rgba[i][RCOMP], 0, 255)      );
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_8_8_8_8_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 255)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 255) <<  8)
+                   | (CLAMP(rgba[i][BCOMP], 0, 255) << 16)
+                   | (CLAMP(rgba[i][ACOMP], 0, 255) << 24);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 255)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 255) <<  8)
+                   | (CLAMP(rgba[i][RCOMP], 0, 255) << 16)
+                   | (CLAMP(rgba[i][ACOMP], 0, 255) << 24);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 255)      )
+                   | (CLAMP(rgba[i][BCOMP], 0, 255) <<  8)
+                   | (CLAMP(rgba[i][GCOMP], 0, 255) << 16)
+                   | (CLAMP(rgba[i][RCOMP], 0, 255) << 24);
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_10_10_10_2:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 1023) << 22)
+                   | (CLAMP(rgba[i][GCOMP], 0, 1023) << 12)
+                   | (CLAMP(rgba[i][BCOMP], 0, 1023) <<  2)
+                   | (CLAMP(rgba[i][ACOMP], 0,    3)      );
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 1023) << 22)
+                   | (CLAMP(rgba[i][GCOMP], 0, 1023) << 12)
+                   | (CLAMP(rgba[i][RCOMP], 0, 1023) <<  2)
+                   | (CLAMP(rgba[i][ACOMP], 0,    3)      );
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 1023) << 22)
+                   | (CLAMP(rgba[i][BCOMP], 0, 1023) << 12)
+                   | (CLAMP(rgba[i][GCOMP], 0, 1023) <<  2)
+                   | (CLAMP(rgba[i][RCOMP], 0,    3)      );
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
+      break;
+   case GL_UNSIGNED_INT_2_10_10_10_REV:
+      if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][RCOMP], 0, 1023)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 1023) << 10)
+                   | (CLAMP(rgba[i][BCOMP], 0, 1023) << 20)
+                   | (CLAMP(rgba[i][ACOMP], 0,    3) << 30);
+         }
+      }
+      else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][BCOMP], 0, 1023)      )
+                   | (CLAMP(rgba[i][GCOMP], 0, 1023) << 10)
+                   | (CLAMP(rgba[i][RCOMP], 0, 1023) << 20)
+                   | (CLAMP(rgba[i][ACOMP], 0,    3) << 30);
+         }
+      }
+      else if (dstFormat == GL_ABGR_EXT) {
+         GLuint *dst = (GLuint *) dstAddr;
+         for (i=0;i<n;i++) {
+            dst[i] = (CLAMP(rgba[i][ACOMP], 0, 1023)      )
+                   | (CLAMP(rgba[i][BCOMP], 0, 1023) << 10)
+                   | (CLAMP(rgba[i][GCOMP], 0, 1023) << 20)
+                   | (CLAMP(rgba[i][RCOMP], 0,    3) << 30);
+         }
+      } else {
+         _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
+      }
       break;
    default:
-      assert(0);
+      _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType);
       return;
    }
 }
@@ -545,14 +1263,14 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
 {
    GLfloat *luminance;
    const GLint comps = _mesa_components_in_format(dstFormat);
-   const GLboolean intDstFormat = _mesa_is_integer_format(dstFormat);
+   const GLboolean intDstFormat = _mesa_is_enum_format_integer(dstFormat);
    GLuint i;
 
    if (dstFormat == GL_LUMINANCE ||
        dstFormat == GL_LUMINANCE_ALPHA ||
        dstFormat == GL_LUMINANCE_INTEGER_EXT ||
        dstFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT) {
-      luminance = (GLfloat *) malloc(n * sizeof(GLfloat));
+      luminance = malloc(n * sizeof(GLfloat));
       if (!luminance) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
          return;
@@ -1175,9 +1893,8 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
                   break;
                case GL_RG_INTEGER:
                   for (i=0;i<n;i++) {
-                     dst[i*3+0] = (GLshort) rgba[i][RCOMP];
-                     dst[i*3+1] = (GLshort) rgba[i][GCOMP];
-                     dst[i*3+2] = (GLshort) rgba[i][BCOMP];
+                     dst[i*2+0] = (GLshort) rgba[i][RCOMP];
+                     dst[i*2+1] = (GLshort) rgba[i][GCOMP];
                   }
                   break;
                case GL_RGB_INTEGER_EXT:
@@ -1727,9 +2444,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLubyte *dst = (GLubyte *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F) << 5)
-                      | (IROUND(rgba[i][GCOMP] * 7.0F) << 2)
-                      | (IROUND(rgba[i][BCOMP] * 3.0F)     );
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 7.0F) << 5)
+                      | (F_TO_I(rgba[i][GCOMP] * 7.0F) << 2)
+                      | (F_TO_I(rgba[i][BCOMP] * 3.0F)     );
             }
          }
          break;
@@ -1737,9 +2454,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLubyte *dst = (GLubyte *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F)     )
-                      | (IROUND(rgba[i][GCOMP] * 7.0F) << 3)
-                      | (IROUND(rgba[i][BCOMP] * 3.0F) << 6);
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 7.0F)     )
+                      | (F_TO_I(rgba[i][GCOMP] * 7.0F) << 3)
+                      | (F_TO_I(rgba[i][BCOMP] * 3.0F) << 6);
             }
          }
          break;
@@ -1747,9 +2464,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11)
-                      | (IROUND(rgba[i][GCOMP] * 63.0F) <<  5)
-                      | (IROUND(rgba[i][BCOMP] * 31.0F)      );
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) << 11)
+                      | (F_TO_I(rgba[i][GCOMP] * 63.0F) <<  5)
+                      | (F_TO_I(rgba[i][BCOMP] * 31.0F)      );
             }
          }
          break;
@@ -1757,9 +2474,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 63.0F) <<  5)
-                      | (IROUND(rgba[i][BCOMP] * 31.0F) << 11);
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 63.0F) <<  5)
+                      | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 11);
             }
          }
          break;
@@ -1767,28 +2484,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 15.0F) << 12)
-                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  8)
-                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  4)
-                      | (IROUND(rgba[i][ACOMP] * 15.0F)      );
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 15.0F) << 12)
+                      | (F_TO_I(rgba[i][GCOMP] * 15.0F) <<  8)
+                      | (F_TO_I(rgba[i][BCOMP] * 15.0F) <<  4)
+                      | (F_TO_I(rgba[i][ACOMP] * 15.0F)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 15.0F) << 12)
-                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  8)
-                      | (IROUND(rgba[i][RCOMP] * 15.0F) <<  4)
-                      | (IROUND(rgba[i][ACOMP] * 15.0F)      );
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 15.0F) << 12)
+                      | (F_TO_I(rgba[i][GCOMP] * 15.0F) <<  8)
+                      | (F_TO_I(rgba[i][RCOMP] * 15.0F) <<  4)
+                      | (F_TO_I(rgba[i][ACOMP] * 15.0F)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 15.0F) << 12)
-                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  8)
-                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  4)
-                      | (IROUND(rgba[i][RCOMP] * 15.0F)      );
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12)
+                      | (F_TO_I(rgba[i][BCOMP] * 15.0F) <<  8)
+                      | (F_TO_I(rgba[i][GCOMP] * 15.0F) <<  4)
+                      | (F_TO_I(rgba[i][RCOMP] * 15.0F)      );
             }
          }
          break;
@@ -1796,28 +2513,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 15.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  4)
-                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  8)
-                      | (IROUND(rgba[i][ACOMP] * 15.0F) << 12);
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 15.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 15.0F) <<  4)
+                      | (F_TO_I(rgba[i][BCOMP] * 15.0F) <<  8)
+                      | (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 15.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  4)
-                      | (IROUND(rgba[i][RCOMP] * 15.0F) <<  8)
-                      | (IROUND(rgba[i][ACOMP] * 15.0F) << 12);
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 15.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 15.0F) <<  4)
+                      | (F_TO_I(rgba[i][RCOMP] * 15.0F) <<  8)
+                      | (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 15.0F)      )
-                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  4)
-                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  8)
-                      | (IROUND(rgba[i][RCOMP] * 15.0F) << 12);
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 15.0F)      )
+                      | (F_TO_I(rgba[i][BCOMP] * 15.0F) <<  4)
+                      | (F_TO_I(rgba[i][GCOMP] * 15.0F) <<  8)
+                      | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 12);
             }
          }
          break;
@@ -1825,28 +2542,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11)
-                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  6)
-                      | (IROUND(rgba[i][BCOMP] * 31.0F) <<  1)
-                      | (IROUND(rgba[i][ACOMP] *  1.0F)      );
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) << 11)
+                      | (F_TO_I(rgba[i][GCOMP] * 31.0F) <<  6)
+                      | (F_TO_I(rgba[i][BCOMP] * 31.0F) <<  1)
+                      | (F_TO_I(rgba[i][ACOMP] *  1.0F)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 31.0F) << 11)
-                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  6)
-                      | (IROUND(rgba[i][RCOMP] * 31.0F) <<  1)
-                      | (IROUND(rgba[i][ACOMP] *  1.0F)      );
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 31.0F) << 11)
+                      | (F_TO_I(rgba[i][GCOMP] * 31.0F) <<  6)
+                      | (F_TO_I(rgba[i][RCOMP] * 31.0F) <<  1)
+                      | (F_TO_I(rgba[i][ACOMP] *  1.0F)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 31.0F) << 11)
-                      | (IROUND(rgba[i][BCOMP] * 31.0F) <<  6)
-                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  1)
-                      | (IROUND(rgba[i][RCOMP] *  1.0F)      );
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 31.0F) << 11)
+                      | (F_TO_I(rgba[i][BCOMP] * 31.0F) <<  6)
+                      | (F_TO_I(rgba[i][GCOMP] * 31.0F) <<  1)
+                      | (F_TO_I(rgba[i][RCOMP] *  1.0F)      );
             }
          }
          break;
@@ -1854,28 +2571,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  5)
-                      | (IROUND(rgba[i][BCOMP] * 31.0F) << 10)
-                      | (IROUND(rgba[i][ACOMP] *  1.0F) << 15);
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 31.0F) <<  5)
+                      | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 10)
+                      | (F_TO_I(rgba[i][ACOMP] *  1.0F) << 15);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 31.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  5)
-                      | (IROUND(rgba[i][RCOMP] * 31.0F) << 10)
-                      | (IROUND(rgba[i][ACOMP] *  1.0F) << 15);
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 31.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 31.0F) <<  5)
+                      | (F_TO_I(rgba[i][RCOMP] * 31.0F) << 10)
+                      | (F_TO_I(rgba[i][ACOMP] *  1.0F) << 15);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 31.0F)      )
-                      | (IROUND(rgba[i][BCOMP] * 31.0F) <<  5)
-                      | (IROUND(rgba[i][GCOMP] * 31.0F) << 10)
-                      | (IROUND(rgba[i][RCOMP] *  1.0F) << 15);
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 31.0F)      )
+                      | (F_TO_I(rgba[i][BCOMP] * 31.0F) <<  5)
+                      | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 10)
+                      | (F_TO_I(rgba[i][RCOMP] *  1.0F) << 15);
             }
          }
          break;
@@ -1883,28 +2600,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 255.F) << 24)
-                      | (IROUND(rgba[i][GCOMP] * 255.F) << 16)
-                      | (IROUND(rgba[i][BCOMP] * 255.F) <<  8)
-                      | (IROUND(rgba[i][ACOMP] * 255.F)      );
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 255.F) << 24)
+                      | (F_TO_I(rgba[i][GCOMP] * 255.F) << 16)
+                      | (F_TO_I(rgba[i][BCOMP] * 255.F) <<  8)
+                      | (F_TO_I(rgba[i][ACOMP] * 255.F)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 255.F) << 24)
-                      | (IROUND(rgba[i][GCOMP] * 255.F) << 16)
-                      | (IROUND(rgba[i][RCOMP] * 255.F) <<  8)
-                      | (IROUND(rgba[i][ACOMP] * 255.F)      );
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 255.F) << 24)
+                      | (F_TO_I(rgba[i][GCOMP] * 255.F) << 16)
+                      | (F_TO_I(rgba[i][RCOMP] * 255.F) <<  8)
+                      | (F_TO_I(rgba[i][ACOMP] * 255.F)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 255.F) << 24)
-                      | (IROUND(rgba[i][BCOMP] * 255.F) << 16)
-                      | (IROUND(rgba[i][GCOMP] * 255.F) <<  8)
-                      | (IROUND(rgba[i][RCOMP] * 255.F)      );
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 255.F) << 24)
+                      | (F_TO_I(rgba[i][BCOMP] * 255.F) << 16)
+                      | (F_TO_I(rgba[i][GCOMP] * 255.F) <<  8)
+                      | (F_TO_I(rgba[i][RCOMP] * 255.F)      );
             }
          }
          break;
@@ -1912,28 +2629,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 255.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 255.0F) <<  8)
-                      | (IROUND(rgba[i][BCOMP] * 255.0F) << 16)
-                      | (IROUND(rgba[i][ACOMP] * 255.0F) << 24);
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 255.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 255.0F) <<  8)
+                      | (F_TO_I(rgba[i][BCOMP] * 255.0F) << 16)
+                      | (F_TO_I(rgba[i][ACOMP] * 255.0F) << 24);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 255.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 255.0F) <<  8)
-                      | (IROUND(rgba[i][RCOMP] * 255.0F) << 16)
-                      | (IROUND(rgba[i][ACOMP] * 255.0F) << 24);
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 255.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 255.0F) <<  8)
+                      | (F_TO_I(rgba[i][RCOMP] * 255.0F) << 16)
+                      | (F_TO_I(rgba[i][ACOMP] * 255.0F) << 24);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 255.0F)      )
-                      | (IROUND(rgba[i][BCOMP] * 255.0F) <<  8)
-                      | (IROUND(rgba[i][GCOMP] * 255.0F) << 16)
-                      | (IROUND(rgba[i][RCOMP] * 255.0F) << 24);
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 255.0F)      )
+                      | (F_TO_I(rgba[i][BCOMP] * 255.0F) <<  8)
+                      | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 16)
+                      | (F_TO_I(rgba[i][RCOMP] * 255.0F) << 24);
             }
          }
          break;
@@ -1941,28 +2658,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 1023.0F) << 22)
-                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 12)
-                      | (IROUND(rgba[i][BCOMP] * 1023.0F) <<  2)
-                      | (IROUND(rgba[i][ACOMP] *    3.0F)      );
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 22)
+                      | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 12)
+                      | (F_TO_I(rgba[i][BCOMP] * 1023.0F) <<  2)
+                      | (F_TO_I(rgba[i][ACOMP] *    3.0F)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 1023.0F) << 22)
-                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 12)
-                      | (IROUND(rgba[i][RCOMP] * 1023.0F) <<  2)
-                      | (IROUND(rgba[i][ACOMP] *    3.0F)      );
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 22)
+                      | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 12)
+                      | (F_TO_I(rgba[i][RCOMP] * 1023.0F) <<  2)
+                      | (F_TO_I(rgba[i][ACOMP] *    3.0F)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 1023.0F) << 22)
-                      | (IROUND(rgba[i][BCOMP] * 1023.0F) << 12)
-                      | (IROUND(rgba[i][GCOMP] * 1023.0F) <<  2)
-                      | (IROUND(rgba[i][RCOMP] *    3.0F)      );
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 1023.0F) << 22)
+                      | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 12)
+                      | (F_TO_I(rgba[i][GCOMP] * 1023.0F) <<  2)
+                      | (F_TO_I(rgba[i][RCOMP] *    3.0F)      );
             }
          }
          break;
@@ -1970,28 +2687,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][RCOMP] * 1023.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 10)
-                      | (IROUND(rgba[i][BCOMP] * 1023.0F) << 20)
-                      | (IROUND(rgba[i][ACOMP] *    3.0F) << 30);
+               dst[i] = (F_TO_I(rgba[i][RCOMP] * 1023.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 10)
+                      | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 20)
+                      | (F_TO_I(rgba[i][ACOMP] *    3.0F) << 30);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][BCOMP] * 1023.0F)      )
-                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 10)
-                      | (IROUND(rgba[i][RCOMP] * 1023.0F) << 20)
-                      | (IROUND(rgba[i][ACOMP] *    3.0F) << 30);
+               dst[i] = (F_TO_I(rgba[i][BCOMP] * 1023.0F)      )
+                      | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 10)
+                      | (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 20)
+                      | (F_TO_I(rgba[i][ACOMP] *    3.0F) << 30);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (IROUND(rgba[i][ACOMP] * 1023.0F)      )
-                      | (IROUND(rgba[i][BCOMP] * 1023.0F) << 10)
-                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 20)
-                      | (IROUND(rgba[i][RCOMP] *    3.0F) << 30);
+               dst[i] = (F_TO_I(rgba[i][ACOMP] * 1023.0F)      )
+                      | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 10)
+                      | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 20)
+                      | (F_TO_I(rgba[i][RCOMP] *    3.0F) << 30);
             }
          }
          break;
@@ -2020,14 +2737,10 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
    if (dstPacking->SwapBytes) {
       GLint swapSize = _mesa_sizeof_packed_type(dstType);
       if (swapSize == 2) {
-         if (dstPacking->SwapBytes) {
-            _mesa_swap2((GLushort *) dstAddr, n * comps);
-         }
+         _mesa_swap2((GLushort *) dstAddr, n * comps);
       }
       else if (swapSize == 4) {
-         if (dstPacking->SwapBytes) {
-            _mesa_swap4((GLuint *) dstAddr, n * comps);
-         }
+         _mesa_swap4((GLuint *) dstAddr, n * comps);
       }
    }
 
@@ -2481,7 +3194,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
 
    stride = _mesa_components_in_format(srcFormat);
 
-   intFormat = _mesa_is_integer_format(srcFormat);
+   intFormat = _mesa_is_enum_format_integer(srcFormat);
 
 #define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT_FLT, DEFAULT_INT, TYPE, CONVERSION) \
    if ((SRC_INDEX) < 0) {                                              \
@@ -2928,7 +3641,11 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
                rgba[i][rDst] = ((p      ) & 0x3ff) * rs;
                rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs;
                rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs;
-               rgba[i][aDst] = ((p >> 30)        ) * as;
+               if (aSrc < 0) {
+                  rgba[i][aDst] = 1.0F;
+               } else {
+                  rgba[i][aDst] = (p >> 30) * as;
+               }
             }
          }
          else {
@@ -2939,7 +3656,11 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
                rgba[i][rDst] = ((p      ) & 0x3ff) * rs;
                rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs;
                rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs;
-               rgba[i][aDst] = ((p >> 30)        ) * as;
+               if (aSrc < 0) {
+                  rgba[i][aDst] = 1.0F;
+               } else {
+                  rgba[i][aDst] = (p >> 30) * as;
+               }
             }
          }
          break;
@@ -3010,7 +3731,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
 static inline GLuint
 clamp_float_to_uint(GLfloat f)
 {
-   return f < 0.0F ? 0 : IROUND(f);
+   return f < 0.0F ? 0 : F_TO_I(f);
 }
 
 
@@ -3018,7 +3739,7 @@ static inline GLuint
 clamp_half_to_uint(GLhalfARB h)
 {
    GLfloat f = _mesa_half_to_float(h);
-   return f < 0.0F ? 0 : IROUND(f);
+   return f < 0.0F ? 0 : F_TO_I(f);
 }
 
 
@@ -3536,7 +4257,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx,
                               const struct gl_pixelstore_attrib *srcPacking,
                               GLbitfield transferOps )
 {
-   GLboolean intFormat = _mesa_is_integer_format(srcFormat);
+   GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat);
    ASSERT(dstFormat == GL_ALPHA ||
           dstFormat == GL_LUMINANCE ||
           dstFormat == GL_LUMINANCE_ALPHA ||
@@ -3648,7 +4369,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx,
    {
       GLint dstComponents;
       GLint rDst, gDst, bDst, aDst, lDst, iDst;
-      GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+      GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat));
 
       if (!rgba) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -3663,7 +4384,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx,
        * Extract image data and convert to RGBA floats
        */
       if (srcFormat == GL_COLOR_INDEX) {
-         GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+         GLuint *indexes = malloc(n * sizeof(GLuint));
 
          if (!indexes) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -3842,8 +4563,8 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
    {
       GLint dstComponents;
       GLint rDst, gDst, bDst, aDst, lDst, iDst;
-      GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
-      GLboolean intFormat = _mesa_is_integer_format(srcFormat);
+      GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat));
+      GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat);
 
       if (!rgba) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -3865,7 +4586,7 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
        * Extract image data and convert to RGBA floats
        */
       if (srcFormat == GL_COLOR_INDEX) {
-         GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+         GLuint *indexes = malloc(n * sizeof(GLuint));
 
          if (!indexes) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -3978,7 +4699,7 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx,
                              const GLvoid *source,
                              const struct gl_pixelstore_attrib *srcPacking)
 {
-   GLuint (*rgba)[4] = (GLuint (*)[4]) malloc(n * 4 * sizeof(GLfloat));
+   GLuint (*rgba)[4] = malloc(n * 4 * sizeof(GLfloat));
 
    if (!rgba) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -4156,7 +4877,7 @@ _mesa_unpack_dudv_span_byte( struct gl_context *ctx,
       GLint dstComponents;
       GLbyte *dst = dest;
       GLuint i;
-      GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * n * sizeof(GLfloat));
+      GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat));
 
       if (!rgba) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -4243,7 +4964,7 @@ _mesa_unpack_index_span( struct gl_context *ctx, GLuint n,
       /*
        * general solution
        */
-      GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+      GLuint *indexes = malloc(n * sizeof(GLuint));
 
       if (!indexes) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
@@ -4294,7 +5015,7 @@ _mesa_pack_index_span( struct gl_context *ctx, GLuint n,
                        const struct gl_pixelstore_attrib *dstPacking,
                        GLbitfield transferOps )
 {
-   GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+   GLuint *indexes = malloc(n * sizeof(GLuint));
 
    if (!indexes) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
@@ -4470,7 +5191,7 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
       /*
        * general solution
        */
-      GLuint *indexes = (GLuint *) malloc(n * sizeof(GLuint));
+      GLuint *indexes = malloc(n * sizeof(GLuint));
 
       if (!indexes) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking");
@@ -4540,7 +5261,7 @@ _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n,
                          GLenum dstType, GLvoid *dest, const GLubyte *source,
                          const struct gl_pixelstore_attrib *dstPacking )
 {
-   GLubyte *stencil = (GLubyte *) malloc(n * sizeof(GLubyte));
+   GLubyte *stencil = malloc(n * sizeof(GLubyte));
 
    if (!stencil) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing");
@@ -4762,7 +5483,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
       depthValues = (GLfloat *) dest;
    }
    else {
-      depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat));
+      depthTemp = malloc(n * sizeof(GLfloat));
       if (!depthTemp) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
          return;
@@ -4901,7 +5622,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
       else {
          /* need to use double precision to prevent overflow problems */
          for (i = 0; i < n; i++) {
-            GLdouble z = depthValues[i] * (GLfloat) depthMax;
+            GLdouble z = depthValues[i] * (GLdouble) depthMax;
             if (z >= (GLdouble) 0xffffffff)
                zValues[i] = 0xffffffff;
             else
@@ -4943,7 +5664,7 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
                        GLenum dstType, const GLfloat *depthSpan,
                        const struct gl_pixelstore_attrib *dstPacking )
 {
-   GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat));
+   GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
    if (!depthCopy) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
       return;
@@ -5065,8 +5786,8 @@ _mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
                               const GLubyte *stencilVals,
                               const struct gl_pixelstore_attrib *dstPacking)
 {
-   GLfloat *depthCopy = (GLfloat *) malloc(n * sizeof(GLfloat));
-   GLubyte *stencilCopy = (GLubyte *) malloc(n * sizeof(GLubyte));
+   GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
+   GLubyte *stencilCopy = malloc(n * sizeof(GLubyte));
    GLuint i;
 
    if (!depthCopy || !stencilCopy) {
@@ -5164,7 +5885,7 @@ _mesa_unpack_image( GLuint dimensions,
 
    {
       GLubyte *destBuffer
-         = (GLubyte *) malloc(bytesPerRow * height * depth);
+         = malloc(bytesPerRow * height * depth);
       GLubyte *dst;
       GLint img, row;
       if (!destBuffer)
@@ -5255,3 +5976,130 @@ _mesa_unpack_image( GLuint dimensions,
    }
 }
 
+
+
+/**
+ * If we unpack colors from a luminance surface, we'll get pixel colors
+ * such as (l, l, l, a).
+ * When we call _mesa_pack_rgba_span_float(format=GL_LUMINANCE), that
+ * function will compute L=R+G+B before packing.  The net effect is we'll
+ * accidentally store luminance values = 3*l.
+ * This function compensates for that by converting (aka rebasing) (l,l,l,a)
+ * to be (l,0,0,a).
+ * It's a similar story for other formats such as LUMINANCE_ALPHA, ALPHA
+ * and INTENSITY.
+ *
+ * Finally, we also need to do this when the actual surface format does
+ * not match the logical surface format.  For example, suppose the user
+ * requests a GL_LUMINANCE texture but the driver stores it as RGBA.
+ * Again, we'll get pixel values like (l,l,l,a).
+ */
+void
+_mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat)
+{
+   GLuint i;
+
+   switch (baseFormat) {
+   case GL_ALPHA:
+      for (i = 0; i < n; i++) {
+         rgba[i][RCOMP] = 0.0F;
+         rgba[i][GCOMP] = 0.0F;
+         rgba[i][BCOMP] = 0.0F;
+      }
+      break;
+   case GL_INTENSITY:
+      /* fall-through */
+   case GL_LUMINANCE:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0.0F;
+         rgba[i][BCOMP] = 0.0F;
+         rgba[i][ACOMP] = 1.0F;
+      }
+      break;
+   case GL_LUMINANCE_ALPHA:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0.0F;
+         rgba[i][BCOMP] = 0.0F;
+      }
+      break;
+   case GL_RGB:
+      for (i = 0; i < n; i++) {
+         rgba[i][ACOMP] = 1.0F;
+      }
+      break;
+   case GL_RG:
+      for (i = 0; i < n; i++) {
+         rgba[i][BCOMP] = 0.0F;
+         rgba[i][ACOMP] = 1.0F;
+      }
+      break;
+   case GL_RED:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0.0F;
+         rgba[i][BCOMP] = 0.0F;
+         rgba[i][ACOMP] = 1.0F;
+      }
+      break;
+
+   default:
+      /* no-op */
+      ;
+   }
+}
+
+
+/**
+ * As above, but GLuint components.
+ */
+void
+_mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat)
+{
+   GLuint i;
+
+   switch (baseFormat) {
+   case GL_ALPHA:
+      for (i = 0; i < n; i++) {
+         rgba[i][RCOMP] = 0;
+         rgba[i][GCOMP] = 0;
+         rgba[i][BCOMP] = 0;
+      }
+      break;
+   case GL_INTENSITY:
+      /* fall-through */
+   case GL_LUMINANCE:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0;
+         rgba[i][BCOMP] = 0;
+         rgba[i][ACOMP] = 1;
+      }
+      break;
+   case GL_LUMINANCE_ALPHA:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0;
+         rgba[i][BCOMP] = 0;
+      }
+      break;
+   case GL_RGB:
+      for (i = 0; i < n; i++) {
+         rgba[i][ACOMP] = 1;
+      }
+      break;
+   case GL_RG:
+      for (i = 0; i < n; i++) {
+         rgba[i][BCOMP] = 0;
+         rgba[i][ACOMP] = 1;
+      }
+      break;
+   case GL_RED:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0;
+         rgba[i][BCOMP] = 0;
+         rgba[i][ACOMP] = 1;
+      }
+   default:
+      /* no-op */
+      ;
+   }
+}
+
+