mesa: Remove unnecessary header.
[mesa.git] / src / mesa / main / image.c
index bd38e0c3d8c732a7e012fcc1bbc03d9616940512..dc8d97728bf1cce592de692c5a40c66715dc08bc 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.1
+ * Version:  7.5
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, Inc.  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"),
 #include "glheader.h"
 #include "colormac.h"
 #include "context.h"
+#include "enums.h"
 #include "image.h"
 #include "imports.h"
 #include "macros.h"
-#include "pixel.h"
 
 
 /**
@@ -61,7 +62,7 @@
 /**
  * \return GL_TRUE if type is packed pixel type, GL_FALSE otherwise.
  */
-static GLboolean
+GLboolean
 _mesa_type_is_packed(GLenum type)
 {
    switch (type) {
@@ -181,6 +182,8 @@ _mesa_sizeof_type( GLenum type )
         return sizeof(GLint);
       case GL_FLOAT:
         return sizeof(GLfloat);
+      case GL_DOUBLE:
+        return sizeof(GLdouble);
       case GL_HALF_FLOAT_ARB:
         return sizeof(GLhalfARB);
       default:
@@ -293,6 +296,9 @@ _mesa_components_in_format( GLenum format )
          return 2;
       case GL_DEPTH_STENCIL_EXT:
          return 2;
+      case GL_DUDV_ATI:
+      case GL_DU8DV8_ATI:
+         return 2;
       default:
          return -1;
    }
@@ -503,6 +509,20 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
             return GL_TRUE;
          else
             return GL_FALSE;
+      case GL_DUDV_ATI:
+      case GL_DU8DV8_ATI:
+         switch (type) {
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+            case GL_FLOAT:
+               return GL_TRUE;
+            default:
+               return GL_FALSE;
+         }
       default:
          ; /* fall-through */
    }
@@ -510,6 +530,226 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
 }
 
 
+/**
+ * Test if the given image format is a color/RGBA format (i.e., not color
+ * index, depth, stencil, etc).
+ * \param format  the image format value (may by an internal texture format)
+ * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
+ */
+GLboolean
+_mesa_is_color_format(GLenum format)
+{
+   switch (format) {
+      case GL_RED:
+      case GL_GREEN:
+      case GL_BLUE:
+      case GL_ALPHA:
+      case GL_ALPHA4:
+      case GL_ALPHA8:
+      case GL_ALPHA12:
+      case GL_ALPHA16:
+      case 1:
+      case GL_LUMINANCE:
+      case GL_LUMINANCE4:
+      case GL_LUMINANCE8:
+      case GL_LUMINANCE12:
+      case GL_LUMINANCE16:
+      case 2:
+      case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE4_ALPHA4:
+      case GL_LUMINANCE6_ALPHA2:
+      case GL_LUMINANCE8_ALPHA8:
+      case GL_LUMINANCE12_ALPHA4:
+      case GL_LUMINANCE12_ALPHA12:
+      case GL_LUMINANCE16_ALPHA16:
+      case GL_INTENSITY:
+      case GL_INTENSITY4:
+      case GL_INTENSITY8:
+      case GL_INTENSITY12:
+      case GL_INTENSITY16:
+      case 3:
+      case GL_RGB:
+      case GL_BGR:
+      case GL_R3_G3_B2:
+      case GL_RGB4:
+      case GL_RGB5:
+      case GL_RGB8:
+      case GL_RGB10:
+      case GL_RGB12:
+      case GL_RGB16:
+      case 4:
+      case GL_ABGR_EXT:
+      case GL_RGBA:
+      case GL_BGRA:
+      case GL_RGBA2:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8:
+      case GL_RGB10_A2:
+      case GL_RGBA12:
+      case GL_RGBA16:
+      /* float texture formats */
+      case GL_ALPHA16F_ARB:
+      case GL_ALPHA32F_ARB:
+      case GL_LUMINANCE16F_ARB:
+      case GL_LUMINANCE32F_ARB:
+      case GL_LUMINANCE_ALPHA16F_ARB:
+      case GL_LUMINANCE_ALPHA32F_ARB:
+      case GL_INTENSITY16F_ARB:
+      case GL_INTENSITY32F_ARB:
+      case GL_RGB16F_ARB:
+      case GL_RGB32F_ARB:
+      case GL_RGBA16F_ARB:
+      case GL_RGBA32F_ARB:
+      /* compressed formats */
+      case GL_COMPRESSED_ALPHA:
+      case GL_COMPRESSED_LUMINANCE:
+      case GL_COMPRESSED_LUMINANCE_ALPHA:
+      case GL_COMPRESSED_INTENSITY:
+      case GL_COMPRESSED_RGB:
+      case GL_COMPRESSED_RGBA:
+      case GL_RGB_S3TC:
+      case GL_RGB4_S3TC:
+      case GL_RGBA_S3TC:
+      case GL_RGBA4_S3TC:
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      case GL_COMPRESSED_RGB_FXT1_3DFX:
+      case GL_COMPRESSED_RGBA_FXT1_3DFX:
+#if FEATURE_EXT_texture_sRGB
+      case GL_SRGB_EXT:
+      case GL_SRGB8_EXT:
+      case GL_SRGB_ALPHA_EXT:
+      case GL_SRGB8_ALPHA8_EXT:
+      case GL_SLUMINANCE_ALPHA_EXT:
+      case GL_SLUMINANCE8_ALPHA8_EXT:
+      case GL_SLUMINANCE_EXT:
+      case GL_SLUMINANCE8_EXT:
+      case GL_COMPRESSED_SRGB_EXT:
+      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_SRGB_ALPHA_EXT:
+      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+      case GL_COMPRESSED_SLUMINANCE_EXT:
+      case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+#endif /* FEATURE_EXT_texture_sRGB */
+         return GL_TRUE;
+      /* signed texture formats */
+      case GL_RGBA_SNORM:
+      case GL_RGBA8_SNORM:
+         return GL_TRUE;
+      case GL_YCBCR_MESA:  /* not considered to be RGB */
+         /* fall-through */
+      default:
+         return GL_FALSE;
+   }
+}
+
+
+/**
+ * Test if the given image format is a color index format.
+ */
+GLboolean
+_mesa_is_index_format(GLenum format)
+{
+   switch (format) {
+      case GL_COLOR_INDEX:
+      case GL_COLOR_INDEX1_EXT:
+      case GL_COLOR_INDEX2_EXT:
+      case GL_COLOR_INDEX4_EXT:
+      case GL_COLOR_INDEX8_EXT:
+      case GL_COLOR_INDEX12_EXT:
+      case GL_COLOR_INDEX16_EXT:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+   }
+}
+
+
+/**
+ * Test if the given image format is a depth component format.
+ */
+GLboolean
+_mesa_is_depth_format(GLenum format)
+{
+   switch (format) {
+      case GL_DEPTH_COMPONENT:
+      case GL_DEPTH_COMPONENT16:
+      case GL_DEPTH_COMPONENT24:
+      case GL_DEPTH_COMPONENT32:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+   }
+}
+
+
+/**
+ * Test if the given image format is a stencil format.
+ */
+GLboolean
+_mesa_is_stencil_format(GLenum format)
+{
+   switch (format) {
+      case GL_STENCIL_INDEX:
+      case GL_DEPTH_STENCIL:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+   }
+}
+
+
+/**
+ * Test if the given image format is a YCbCr format.
+ */
+GLboolean
+_mesa_is_ycbcr_format(GLenum format)
+{
+   switch (format) {
+      case GL_YCBCR_MESA:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+   }
+}
+
+
+/**
+ * Test if the given image format is a depth+stencil format.
+ */
+GLboolean
+_mesa_is_depthstencil_format(GLenum format)
+{
+   switch (format) {
+      case GL_DEPTH24_STENCIL8_EXT:
+      case GL_DEPTH_STENCIL_EXT:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+   }
+}
+
+/**
+ * Test if the given image format is a dudv format.
+ */
+GLboolean
+_mesa_is_dudv_format(GLenum format)
+{
+   switch (format) {
+      case GL_DUDV_ATI:
+      case GL_DU8DV8_ATI:
+         return GL_TRUE;
+      default:
+         return GL_FALSE;
+   }
+}
+
+
 /**
  * Return the address of a specific pixel in an image (1D, 2D or 3D).
  *
@@ -738,12 +978,20 @@ _mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
                           GLint width, GLint height,
                           GLenum format, GLenum type )
 {
+   GLint bytesPerRow, bytesPerImage, remainder;
+
    ASSERT(packing);
-   ASSERT(type != GL_BITMAP);
 
-   {
+   if (type == GL_BITMAP) {
+      if (packing->RowLength == 0) {
+         bytesPerRow = (width + 7) / 8;
+      }
+      else {
+         bytesPerRow = (packing->RowLength + 7) / 8;
+      }
+   }
+   else {
       const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
-      GLint bytesPerRow, bytesPerImage, remainder;
 
       if (bytesPerPixel <= 0)
          return -1;  /* error */
@@ -753,17 +1001,18 @@ _mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
       else {
          bytesPerRow = bytesPerPixel * packing->RowLength;
       }
-      remainder = bytesPerRow % packing->Alignment;
-      if (remainder > 0)
-         bytesPerRow += (packing->Alignment - remainder);
+   }
 
-      if (packing->ImageHeight == 0)
-         bytesPerImage = bytesPerRow * height;
-      else
-         bytesPerImage = bytesPerRow * packing->ImageHeight;
+   remainder = bytesPerRow % packing->Alignment;
+   if (remainder > 0)
+      bytesPerRow += (packing->Alignment - remainder);
 
-      return bytesPerImage;
-   }
+   if (packing->ImageHeight == 0)
+      bytesPerImage = bytesPerRow * height;
+   else
+      bytesPerImage = bytesPerRow * packing->ImageHeight;
+
+   return bytesPerImage;
 }
 
 
@@ -789,7 +1038,7 @@ _mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
                  | (p[3]      );
          p += 4;
       }
-      _mesa_free(ptrn);
+      free(ptrn);
    }
 }
 
@@ -834,7 +1083,7 @@ _mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
 
    /* Alloc dest storage */
    bytes = ((width + 7) / 8 * height);
-   buffer = (GLubyte *) _mesa_malloc( bytes );
+   buffer = (GLubyte *) malloc( bytes );
    if (!buffer)
       return NULL;
 
@@ -845,12 +1094,12 @@ _mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
          _mesa_image_address2d(packing, pixels, width, height,
                                GL_COLOR_INDEX, GL_BITMAP, row, 0);
       if (!src) {
-         _mesa_free(buffer);
+         free(buffer);
          return NULL;
       }
 
       if ((packing->SkipPixels & 7) == 0) {
-         _mesa_memcpy( dst, src, width_in_bytes );
+         memcpy( dst, src, width_in_bytes );
          if (packing->LsbFirst) {
             flip_bytes( dst, width_in_bytes );
          }
@@ -942,7 +1191,7 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
          return;
 
       if ((packing->SkipPixels & 7) == 0) {
-         _mesa_memcpy( dst, src, width_in_bytes );
+         memcpy( dst, src, width_in_bytes );
          if (packing->LsbFirst) {
             flip_bytes( dst, width_in_bytes );
          }
@@ -1010,6 +1259,91 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
 }
 
 
+/**
+ * "Expand" a bitmap from 1-bit per pixel to 8-bits per pixel.
+ * This is typically used to convert a bitmap into a GLubyte/pixel texture.
+ * "On" bits will set texels to \p onValue.
+ * "Off" bits will not modify texels.
+ * \param width  src bitmap width in pixels
+ * \param height  src bitmap height in pixels
+ * \param unpack  bitmap unpacking state
+ * \param bitmap  the src bitmap data
+ * \param destBuffer  start of dest buffer
+ * \param destStride  row stride in dest buffer
+ * \param onValue  if bit is 1, set destBuffer pixel to this value
+ */
+void
+_mesa_expand_bitmap(GLsizei width, GLsizei height,
+                    const struct gl_pixelstore_attrib *unpack,
+                    const GLubyte *bitmap,
+                    GLubyte *destBuffer, GLint destStride,
+                    GLubyte onValue)
+{
+   const GLubyte *srcRow = (const GLubyte *)
+      _mesa_image_address2d(unpack, bitmap, width, height,
+                            GL_COLOR_INDEX, GL_BITMAP, 0, 0);
+   const GLint srcStride = _mesa_image_row_stride(unpack, width,
+                                                  GL_COLOR_INDEX, GL_BITMAP);
+   GLint row, col;
+
+#define SET_PIXEL(COL, ROW) \
+   destBuffer[(ROW) * destStride + (COL)] = onValue;
+
+   for (row = 0; row < height; row++) {
+      const GLubyte *src = srcRow;
+
+      if (unpack->LsbFirst) {
+         /* Lsb first */
+         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
+         for (col = 0; col < width; col++) {
+
+            if (*src & mask) {
+               SET_PIXEL(col, row);
+            }
+
+            if (mask == 128U) {
+               src++;
+               mask = 1U;
+            }
+            else {
+               mask = mask << 1;
+            }
+         }
+
+         /* get ready for next row */
+         if (mask != 1)
+            src++;
+      }
+      else {
+         /* Msb first */
+         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
+         for (col = 0; col < width; col++) {
+
+            if (*src & mask) {
+               SET_PIXEL(col, row);
+            }
+
+            if (mask == 1U) {
+               src++;
+               mask = 128U;
+            }
+            else {
+               mask = mask >> 1;
+            }
+         }
+
+         /* get ready for next row */
+         if (mask != 128)
+            src++;
+      }
+
+      srcRow += srcStride;
+   } /* row */
+
+#undef SET_PIXEL
+}
+
+
 /**********************************************************************/
 /*****                  Pixel processing functions               ******/
 /**********************************************************************/
@@ -1660,7 +1994,6 @@ _mesa_apply_stencil_transfer_ops(const GLcontext *ctx, GLuint n,
  * Used to pack an array [][4] of RGBA float colors as specified
  * by the dstFormat, dstType and dstPacking.  Used by glReadPixels,
  * glGetConvolutionFilter(), etc.
- * Incoming colors will be clamped to [0,1] if needed.
  * Note: the rgba values will be modified by this function when any pixel
  * transfer ops are enabled.
  */
@@ -1675,6 +2008,10 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
    const GLint comps = _mesa_components_in_format(dstFormat);
    GLuint i;
 
+   /* XXX
+    * This test should probably go away.  Have the caller set/clear the
+    * IMAGE_CLAMP_BIT as needed.
+    */
    if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
       /* need to clamp to [0, 1] */
       transferOps |= IMAGE_CLAMP_BIT;
@@ -1689,7 +2026,7 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
 
    if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
       /* compute luminance values */
-      if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
+      if (transferOps & IMAGE_CLAMP_BIT) {
          for (i = 0; i < n; i++) {
             GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
             luminance[i] = CLAMP(sum, 0.0F, 1.0F);
@@ -1774,6 +2111,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
+                     dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -1847,6 +2191,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+                     dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -1920,6 +2271,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = FLOAT_TO_USHORT(rgba[i][RCOMP]);
+                     dst[i*2+1] = FLOAT_TO_USHORT(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -1993,6 +2351,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
+                     dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -2066,6 +2431,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
+                     dst[i*2+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -2139,6 +2511,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
+                     dst[i*2+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -2212,6 +2591,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = rgba[i][RCOMP];
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = rgba[i][RCOMP];
+                     dst[i*2+1] = rgba[i][GCOMP];
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -2285,6 +2671,13 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
                      dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]);
                   }
                   break;
+               case GL_DUDV_ATI:
+               case GL_DU8DV8_ATI:
+                  for (i=0;i<n;i++) {
+                     dst[i*2+0] = _mesa_float_to_half(rgba[i][RCOMP]);
+                     dst[i*2+1] = _mesa_float_to_half(rgba[i][GCOMP]);
+                  }
+                  break;
                default:
                   _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
             }
@@ -2294,9 +2687,9 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLubyte *dst = (GLubyte *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 7.0F)) << 5)
-                      | (((GLint) (rgba[i][GCOMP] * 7.0F)) << 2)
-                      | (((GLint) (rgba[i][BCOMP] * 3.0F))     );
+               dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F) << 5)
+                      | (IROUND(rgba[i][GCOMP] * 7.0F) << 2)
+                      | (IROUND(rgba[i][BCOMP] * 3.0F)     );
             }
          }
          break;
@@ -2304,9 +2697,9 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLubyte *dst = (GLubyte *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 7.0F))     )
-                      | (((GLint) (rgba[i][GCOMP] * 7.0F)) << 3)
-                      | (((GLint) (rgba[i][BCOMP] * 3.0F)) << 6);
+               dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F)     )
+                      | (IROUND(rgba[i][GCOMP] * 7.0F) << 3)
+                      | (IROUND(rgba[i][BCOMP] * 3.0F) << 6);
             }
          }
          break;
@@ -2314,9 +2707,9 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) << 11)
-                      | (((GLint) (rgba[i][GCOMP] * 63.0F)) <<  5)
-                      | (((GLint) (rgba[i][BCOMP] * 31.0F))      );
+               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11)
+                      | (IROUND(rgba[i][GCOMP] * 63.0F) <<  5)
+                      | (IROUND(rgba[i][BCOMP] * 31.0F)      );
             }
          }
          break;
@@ -2324,9 +2717,9 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGB) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F))      )
-                      | (((GLint) (rgba[i][GCOMP] * 63.0F)) <<  5)
-                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 11);
+               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F)      )
+                      | (IROUND(rgba[i][GCOMP] * 63.0F) <<  5)
+                      | (IROUND(rgba[i][BCOMP] * 31.0F) << 11);
             }
          }
          break;
@@ -2334,28 +2727,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 15.0F)) << 12)
-                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  8)
-                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  4)
-                      | (((GLint) (rgba[i][ACOMP] * 15.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][BCOMP] * 15.0F)) << 12)
-                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  8)
-                      | (((GLint) (rgba[i][RCOMP] * 15.0F)) <<  4)
-                      | (((GLint) (rgba[i][ACOMP] * 15.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12)
-                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  8)
-                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  4)
-                      | (((GLint) (rgba[i][RCOMP] * 15.0F))      );
+               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)      );
             }
          }
          break;
@@ -2363,28 +2756,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 15.0F))      )
-                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  4)
-                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  8)
-                      | (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12);
+               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);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][BCOMP] * 15.0F))      )
-                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  4)
-                      | (((GLint) (rgba[i][RCOMP] * 15.0F)) <<  8)
-                      | (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12);
+               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);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][ACOMP] * 15.0F))      )
-                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  4)
-                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  8)
-                      | (((GLint) (rgba[i][RCOMP] * 15.0F)) << 12);
+               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);
             }
          }
          break;
@@ -2392,28 +2785,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) << 11)
-                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  6)
-                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) <<  1)
-                      | (((GLint) (rgba[i][ACOMP] *  1.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][BCOMP] * 31.0F)) << 11)
-                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  6)
-                      | (((GLint) (rgba[i][RCOMP] * 31.0F)) <<  1)
-                      | (((GLint) (rgba[i][ACOMP] *  1.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][ACOMP] * 31.0F)) << 11)
-                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) <<  6)
-                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  1)
-                      | (((GLint) (rgba[i][RCOMP] *  1.0F))      );
+               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)      );
             }
          }
          break;
@@ -2421,28 +2814,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F))      )
-                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  5)
-                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 10)
-                      | (((GLint) (rgba[i][ACOMP] *  1.0F)) << 15);
+               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);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][BCOMP] * 31.0F))      )
-                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  5)
-                      | (((GLint) (rgba[i][RCOMP] * 31.0F)) << 10)
-                      | (((GLint) (rgba[i][ACOMP] *  1.0F)) << 15);
+               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);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLushort *dst = (GLushort *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLint) (rgba[i][ACOMP] * 31.0F))      )
-                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) <<  5)
-                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 10)
-                      | (((GLint) (rgba[i][RCOMP] *  1.0F)) << 15);
+               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);
             }
          }
          break;
@@ -2450,28 +2843,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 24)
-                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
-                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) <<  8)
-                      | (((GLuint) (rgba[i][ACOMP] * 255.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 24)
-                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
-                      | (((GLuint) (rgba[i][RCOMP] * 255.0F)) <<  8)
-                      | (((GLuint) (rgba[i][ACOMP] * 255.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24)
-                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 16)
-                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) <<  8)
-                      | (((GLuint) (rgba[i][RCOMP] * 255.0F))      );
+               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)      );
             }
          }
          break;
@@ -2479,28 +2872,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][RCOMP] * 255.0F))      )
-                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) <<  8)
-                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 16)
-                      | (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24);
+               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);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][BCOMP] * 255.0F))      )
-                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) <<  8)
-                      | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 16)
-                      | (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24);
+               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);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][ACOMP] * 255.0F))      )
-                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) <<  8)
-                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
-                      | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 24);
+               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);
             }
          }
          break;
@@ -2508,28 +2901,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 22)
-                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 12)
-                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) <<  2)
-                      | (((GLuint) (rgba[i][ACOMP] *    3.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 22)
-                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 12)
-                      | (((GLuint) (rgba[i][RCOMP] * 1023.0F)) <<  2)
-                      | (((GLuint) (rgba[i][ACOMP] *    3.0F))      );
+               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)      );
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][ACOMP] * 1023.0F)) << 22)
-                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 12)
-                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) <<  2)
-                      | (((GLuint) (rgba[i][RCOMP] *    3.0F))      );
+               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)      );
             }
          }
          break;
@@ -2537,28 +2930,28 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
          if (dstFormat == GL_RGBA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][RCOMP] * 1023.0F))      )
-                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 10)
-                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 20)
-                      | (((GLuint) (rgba[i][ACOMP] *    3.0F)) << 30);
+               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);
             }
          }
          else if (dstFormat == GL_BGRA) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][BCOMP] * 1023.0F))      )
-                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 10)
-                      | (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 20)
-                      | (((GLuint) (rgba[i][ACOMP] *    3.0F)) << 30);
+               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);
             }
          }
          else if (dstFormat == GL_ABGR_EXT) {
             GLuint *dst = (GLuint *) dstAddr;
             for (i=0;i<n;i++) {
-               dst[i] = (((GLuint) (rgba[i][ACOMP] * 1023.0F))      )
-                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 10)
-                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 20)
-                      | (((GLuint) (rgba[i][RCOMP] *    3.0F)) << 30);
+               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);
             }
          }
          break;
@@ -2786,7 +3179,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
             }
             else {
                for (i = 0; i < n; i++)
-                  indexes[i] = s[i] & 0xfff;  /* lower 8 bits */
+                  indexes[i] = s[i] & 0xff;  /* lower 8 bits */
             }
          }
          break;
@@ -2834,7 +3227,9 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
           srcFormat == GL_BGR ||
           srcFormat == GL_RGBA ||
           srcFormat == GL_BGRA ||
-          srcFormat == GL_ABGR_EXT);
+          srcFormat == GL_ABGR_EXT ||
+          srcFormat == GL_DU8DV8_ATI ||
+          srcFormat == GL_DUDV_ATI);
 
    ASSERT(srcType == GL_UNSIGNED_BYTE ||
           srcType == GL_BYTE ||
@@ -2949,8 +3344,17 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          aComp = 0;
          stride = 4;
          break;
+      case GL_DU8DV8_ATI:
+      case GL_DUDV_ATI:
+         redIndex = 0;
+         greenIndex = 1;
+         blueIndex = -1;
+         alphaIndex = -1;
+         stride = 2;
+         break;
       default:
-         _mesa_problem(NULL, "bad srcFormat in extract float data");
+         _mesa_problem(NULL, "bad srcFormat %s in extract float data",
+                       _mesa_lookup_enum_by_nr(srcFormat));
          return;
    }
 
@@ -3390,7 +3794,7 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
       if (srcType == CHAN_TYPE) {
          if (dstFormat == GL_RGBA) {
             if (srcFormat == GL_RGBA) {
-               _mesa_memcpy( dest, source, n * 4 * sizeof(GLchan) );
+               memcpy( dest, source, n * 4 * sizeof(GLchan) );
                return;
             }
             else if (srcFormat == GL_RGB) {
@@ -3410,7 +3814,7 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
          }
          else if (dstFormat == GL_RGB) {
             if (srcFormat == GL_RGB) {
-               _mesa_memcpy( dest, source, n * 3 * sizeof(GLchan) );
+               memcpy( dest, source, n * 3 * sizeof(GLchan) );
                return;
             }
             else if (srcFormat == GL_RGBA) {
@@ -3430,7 +3834,7 @@ _mesa_unpack_color_span_chan( GLcontext *ctx,
          else if (dstFormat == srcFormat) {
             GLint comps = _mesa_components_in_format(srcFormat);
             assert(comps > 0);
-            _mesa_memcpy( dest, source, n * comps * sizeof(GLchan) );
+            memcpy( dest, source, n * comps * sizeof(GLchan) );
             return;
          }
       }
@@ -3877,6 +4281,62 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
    }
 }
 
+/**
+ * Similar to _mesa_unpack_color_span_float(), but for dudv data instead of rgba,
+ * directly return GLbyte data, no transfer ops apply.
+ */
+void
+_mesa_unpack_dudv_span_byte( GLcontext *ctx,
+                             GLuint n, GLenum dstFormat, GLbyte dest[],
+                             GLenum srcFormat, GLenum srcType,
+                             const GLvoid *source,
+                             const struct gl_pixelstore_attrib *srcPacking,
+                             GLbitfield transferOps )
+{
+   ASSERT(dstFormat == GL_DUDV_ATI);
+   ASSERT(srcFormat == GL_DUDV_ATI);
+
+   ASSERT(srcType == GL_UNSIGNED_BYTE ||
+          srcType == GL_BYTE ||
+          srcType == GL_UNSIGNED_SHORT ||
+          srcType == GL_SHORT ||
+          srcType == GL_UNSIGNED_INT ||
+          srcType == GL_INT ||
+          srcType == GL_HALF_FLOAT_ARB ||
+          srcType == GL_FLOAT);
+
+   /* general solution */
+   {
+      GLint dstComponents;
+      GLfloat rgba[MAX_WIDTH][4];
+      GLbyte *dst = dest;
+      GLuint i;
+
+      dstComponents = _mesa_components_in_format( dstFormat );
+      /* source & dest image formats should have been error checked by now */
+      assert(dstComponents > 0);
+
+      /*
+       * Extract image data and convert to RGBA floats
+       */
+      assert(n <= MAX_WIDTH);
+      extract_float_rgba(n, rgba, srcFormat, srcType, source,
+                         srcPacking->SwapBytes);
+
+
+      /* Now determine which color channels we need to produce.
+       * And determine the dest index (offset) within each color tuple.
+       */
+
+      /* Now pack results in the requested dstFormat */
+      for (i = 0; i < n; i++) {
+         /* not sure - need clamp[-1,1] here? */
+         dst[0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
+         dst[1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
+         dst += dstComponents;
+      }
+   }
+}
 
 /*
  * Unpack a row of color index data from a client buffer according to
@@ -3921,11 +4381,11 @@ _mesa_unpack_index_span( const GLcontext *ctx, GLuint n,
     */
    if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE
        && dstType == GL_UNSIGNED_BYTE) {
-      _mesa_memcpy(dest, source, n * sizeof(GLubyte));
+      memcpy(dest, source, n * sizeof(GLubyte));
    }
    else if (transferOps == 0 && srcType == GL_UNSIGNED_INT
             && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) {
-      _mesa_memcpy(dest, source, n * sizeof(GLuint));
+      memcpy(dest, source, n * sizeof(GLuint));
    }
    else {
       /*
@@ -3961,7 +4421,7 @@ _mesa_unpack_index_span( const GLcontext *ctx, GLuint n,
             }
             break;
          case GL_UNSIGNED_INT:
-            _mesa_memcpy(dest, indexes, n * sizeof(GLuint));
+            memcpy(dest, indexes, n * sizeof(GLuint));
             break;
          default:
             _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span");
@@ -3984,7 +4444,7 @@ _mesa_pack_index_span( const GLcontext *ctx, GLuint n,
 
    if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) {
       /* make a copy of input */
-      _mesa_memcpy(indexes, source, n * sizeof(GLuint));
+      memcpy(indexes, source, n * sizeof(GLuint));
       _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
       source = indexes;
    }
@@ -4132,14 +4592,14 @@ _mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
        !ctx->Pixel.MapStencilFlag &&
        srcType == GL_UNSIGNED_BYTE &&
        dstType == GL_UNSIGNED_BYTE) {
-      _mesa_memcpy(dest, source, n * sizeof(GLubyte));
+      memcpy(dest, source, n * sizeof(GLubyte));
    }
    else if (transferOps == 0 &&
             !ctx->Pixel.MapStencilFlag &&
             srcType == GL_UNSIGNED_INT &&
             dstType == GL_UNSIGNED_INT &&
             !srcPacking->SwapBytes) {
-      _mesa_memcpy(dest, source, n * sizeof(GLuint));
+      memcpy(dest, source, n * sizeof(GLuint));
    }
    else {
       /*
@@ -4186,7 +4646,7 @@ _mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
             }
             break;
          case GL_UNSIGNED_INT:
-            _mesa_memcpy(dest, indexes, n * sizeof(GLuint));
+            memcpy(dest, indexes, n * sizeof(GLuint));
             break;
          default:
             _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
@@ -4207,7 +4667,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
    if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
        ctx->Pixel.MapStencilFlag) {
       /* make a copy of input */
-      _mesa_memcpy(stencil, source, n * sizeof(GLstencil));
+      memcpy(stencil, source, n * sizeof(GLstencil));
       _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
       source = stencil;
    }
@@ -4215,7 +4675,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
    switch (dstType) {
    case GL_UNSIGNED_BYTE:
       if (sizeof(GLstencil) == 1) {
-         _mesa_memcpy( dest, source, n );
+         memcpy( dest, source, n );
       }
       else {
          GLubyte *dst = (GLubyte *) dest;
@@ -4406,6 +4866,17 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
          }
          return;
       }
+      if (srcType == GL_UNSIGNED_INT_24_8
+          && dstType == GL_UNSIGNED_INT
+          && depthMax == 0xffffff) {
+         const GLuint *src = (const GLuint *) source;
+         GLuint *dst = (GLuint *) dest;
+         GLuint i;
+         for (i = 0; i < n; i++) {
+            dst[i] = src[i] >> 8;
+         }
+         return;
+      }
       /* XXX may want to add additional cases here someday */
    }
 
@@ -4568,7 +5039,7 @@ _mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest,
    ASSERT(n <= MAX_WIDTH);
 
    if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
-      _mesa_memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
+      memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
       _mesa_scale_and_bias_depth(ctx, n, depthCopy);
       depthSpan = depthCopy;
    }
@@ -4687,7 +5158,7 @@ _mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest,
    ASSERT(n <= MAX_WIDTH);
 
    if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
-      _mesa_memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
+      memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
       _mesa_scale_and_bias_depth(ctx, n, depthCopy);
       depthVals = depthCopy;
    }
@@ -4695,7 +5166,7 @@ _mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest,
    if (ctx->Pixel.IndexShift ||
        ctx->Pixel.IndexOffset ||
        ctx->Pixel.MapStencilFlag) {
-      _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
+      memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
       _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
       stencilVals = stencilCopy;
    }
@@ -4761,7 +5232,7 @@ _mesa_unpack_image( GLuint dimensions,
 
    {
       GLubyte *destBuffer
-         = (GLubyte *) _mesa_malloc(bytesPerRow * height * depth);
+         = (GLubyte *) malloc(bytesPerRow * height * depth);
       GLubyte *dst;
       GLint img, row;
       if (!destBuffer)
@@ -4832,7 +5303,7 @@ _mesa_unpack_image( GLuint dimensions,
                }
             }
             else {
-               _mesa_memcpy(dst, src, bytesPerRow);
+               memcpy(dst, src, bytesPerRow);
             }
 
             /* byte flipping/swapping */
@@ -4885,7 +5356,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
             }
          }
          if (useTemp)
-            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
+            memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
       }
       else {
          const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
@@ -4901,7 +5372,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
             }
          }
          if (useTemp)
-            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
+            memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
       }
       break;
    case GL_UNSIGNED_SHORT:
@@ -4918,7 +5389,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
             }
          }
          if (useTemp)
-            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
+            memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
       }
       else {
          const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
@@ -4934,7 +5405,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
             }
          }
          if (useTemp)
-            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
+            memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
       }
       break;
    case GL_FLOAT:
@@ -4951,7 +5422,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
             }
          }
          if (useTemp)
-            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
+            memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
       }
       else {
          const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
@@ -4967,7 +5438,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
             }
          }
          if (useTemp)
-            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
+            memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
       }
       break;
    default:
@@ -5043,7 +5514,7 @@ _mesa_clip_drawpixels(const GLcontext *ctx,
    }
 
    if (*height <= 0)
-      return GL_TRUE;
+      return GL_FALSE;
 
    return GL_TRUE;
 }
@@ -5096,7 +5567,7 @@ _mesa_clip_readpixels(const GLcontext *ctx,
       *height -= (*srcY + *height - buffer->Height);
 
    if (*height <= 0)
-      return GL_TRUE;
+      return GL_FALSE;
 
    return GL_TRUE;
 }
@@ -5152,7 +5623,7 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
 
    /* right clipping */
    if (*x + *width > xmax)
-      *width -= (*x + *width - xmax - 1);
+      *width -= (*x + *width - xmax);
 
    if (*width <= 0)
       return GL_FALSE;
@@ -5165,10 +5636,188 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
 
    /* top (or bottom) clipping */
    if (*y + *height > ymax)
-      *height -= (*y + *height - ymax - 1);
+      *height -= (*y + *height - ymax);
 
    if (*height <= 0)
       return GL_FALSE;
 
    return GL_TRUE;
 }
+
+
+/**
+ * Clip dst coords against Xmax (or Ymax).
+ */
+static INLINE void
+clip_right_or_top(GLint *srcX0, GLint *srcX1,
+                  GLint *dstX0, GLint *dstX1,
+                  GLint maxValue)
+{
+   GLfloat t, bias;
+
+   if (*dstX1 > maxValue) {
+      /* X1 outside right edge */
+      ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
+      t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+      /* chop off [t, 1] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX1 = maxValue;
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
+      *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+   }
+   else if (*dstX0 > maxValue) {
+      /* X0 outside right edge */
+      ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
+      t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+      /* chop off [t, 1] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX0 = maxValue;
+      bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F;
+      *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+   }
+}
+
+
+/**
+ * Clip dst coords against Xmin (or Ymin).
+ */
+static INLINE void
+clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
+                    GLint *dstX0, GLint *dstX1,
+                    GLint minValue)
+{
+   GLfloat t, bias;
+
+   if (*dstX0 < minValue) {
+      /* X0 outside left edge */
+      ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
+      t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+      /* chop off [0, t] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX0 = minValue;
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; /* flipped??? */
+      *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+   }
+   else if (*dstX1 < minValue) {
+      /* X1 outside left edge */
+      ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
+      t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+      /* chop off [0, t] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX1 = minValue;
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
+      *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+   }
+}
+
+
+/**
+ * Do clipping of blit src/dest rectangles.
+ * The dest rect is clipped against both the buffer bounds and scissor bounds.
+ * The src rect is just clipped against the buffer bounds.
+ *
+ * When either the src or dest rect is clipped, the other is also clipped
+ * proportionately!
+ *
+ * Note that X0 need not be less than X1 (same for Y) for either the source
+ * and dest rects.  That makes the clipping a little trickier.
+ *
+ * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
+ */
+GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+                GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+                GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
+{
+   const GLint srcXmin = 0;
+   const GLint srcXmax = ctx->ReadBuffer->Width;
+   const GLint srcYmin = 0;
+   const GLint srcYmax = ctx->ReadBuffer->Height;
+
+   /* these include scissor bounds */
+   const GLint dstXmin = ctx->DrawBuffer->_Xmin;
+   const GLint dstXmax = ctx->DrawBuffer->_Xmax;
+   const GLint dstYmin = ctx->DrawBuffer->_Ymin;
+   const GLint dstYmax = ctx->DrawBuffer->_Ymax;
+
+   /*
+   printf("PreClipX:  src: %d .. %d  dst: %d .. %d\n",
+          *srcX0, *srcX1, *dstX0, *dstX1);
+   printf("PreClipY:  src: %d .. %d  dst: %d .. %d\n",
+          *srcY0, *srcY1, *dstY0, *dstY1);
+   */
+
+   /* trivial rejection tests */
+   if (*dstX0 == *dstX1)
+      return GL_FALSE; /* no width */
+   if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
+      return GL_FALSE; /* totally out (left) of bounds */
+   if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
+      return GL_FALSE; /* totally out (right) of bounds */
+
+   if (*dstY0 == *dstY1)
+      return GL_FALSE;
+   if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
+      return GL_FALSE;
+   if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
+      return GL_FALSE;
+
+   if (*srcX0 == *srcX1)
+      return GL_FALSE;
+   if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
+      return GL_FALSE;
+   if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
+      return GL_FALSE;
+
+   if (*srcY0 == *srcY1)
+      return GL_FALSE;
+   if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
+      return GL_FALSE;
+   if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
+      return GL_FALSE;
+
+   /*
+    * dest clip
+    */
+   clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
+   clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
+   clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
+   clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
+
+   /*
+    * src clip (just swap src/dst values from above)
+    */
+   clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
+   clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
+   clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
+   clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
+
+   /*
+   printf("PostClipX: src: %d .. %d  dst: %d .. %d\n",
+          *srcX0, *srcX1, *dstX0, *dstX1);
+   printf("PostClipY: src: %d .. %d  dst: %d .. %d\n",
+          *srcY0, *srcY1, *dstY0, *dstY1);
+   */
+
+   ASSERT(*dstX0 >= dstXmin);
+   ASSERT(*dstX0 <= dstXmax);
+   ASSERT(*dstX1 >= dstXmin);
+   ASSERT(*dstX1 <= dstXmax);
+
+   ASSERT(*dstY0 >= dstYmin);
+   ASSERT(*dstY0 <= dstYmax);
+   ASSERT(*dstY1 >= dstYmin);
+   ASSERT(*dstY1 <= dstYmax);
+
+   ASSERT(*srcX0 >= srcXmin);
+   ASSERT(*srcX0 <= srcXmax);
+   ASSERT(*srcX1 >= srcXmin);
+   ASSERT(*srcX1 <= srcXmax);
+
+   ASSERT(*srcY0 >= srcYmin);
+   ASSERT(*srcY0 <= srcYmax);
+   ASSERT(*srcY1 >= srcYmin);
+   ASSERT(*srcY1 <= srcYmax);
+
+   return GL_TRUE;
+}