glthread: rename marshal.h/c to glthread_marshal.h and glthread_shaderobj.c
[mesa.git] / src / mesa / main / image.c
index 3b16d3d443bc99dea8459ad12d6409b863225fd0..ad6b378f7f62d8f7bbd137b5d66e377861224627 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.5
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 
 
 #include "glheader.h"
 #include "colormac.h"
+#include "glformats.h"
 #include "image.h"
 #include "imports.h"
 #include "macros.h"
-#include "mfeatures.h"
 #include "mtypes.h"
 
 
-/**
- * NOTE:
- * Normally, BYTE_TO_FLOAT(0) returns 0.00392  That causes problems when
- * we later convert the float to a packed integer value (such as for
- * GL_RGB5_A1) because we'll wind up with a non-zero value.
- *
- * We redefine the macros here so zero is handled correctly.
- */
-#undef BYTE_TO_FLOAT
-#define BYTE_TO_FLOAT(B)    ((B) == 0 ? 0.0F : ((2.0F * (B) + 1.0F) * (1.0F/255.0F)))
-
-#undef SHORT_TO_FLOAT
-#define SHORT_TO_FLOAT(S)   ((S) == 0 ? 0.0F : ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)))
-
-
-
-/** Compute ceiling of integer quotient of A divided by B. */
-#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
-
-
-/**
- * \return GL_TRUE if type is packed pixel type, GL_FALSE otherwise.
- */
-GLboolean
-_mesa_type_is_packed(GLenum type)
-{
-   switch (type) {
-   case GL_UNSIGNED_BYTE_3_3_2:
-   case GL_UNSIGNED_BYTE_2_3_3_REV:
-   case MESA_UNSIGNED_BYTE_4_4:
-   case GL_UNSIGNED_SHORT_5_6_5:
-   case GL_UNSIGNED_SHORT_5_6_5_REV:
-   case GL_UNSIGNED_SHORT_4_4_4_4:
-   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-   case GL_UNSIGNED_SHORT_5_5_5_1:
-   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-   case GL_UNSIGNED_INT_8_8_8_8:
-   case GL_UNSIGNED_INT_8_8_8_8_REV:
-   case GL_UNSIGNED_INT_10_10_10_2:
-   case GL_UNSIGNED_INT_2_10_10_10_REV:
-   case GL_UNSIGNED_SHORT_8_8_MESA:
-   case GL_UNSIGNED_SHORT_8_8_REV_MESA:
-   case GL_UNSIGNED_INT_24_8_EXT:
-   case GL_UNSIGNED_INT_5_9_9_9_REV:
-   case GL_UNSIGNED_INT_10F_11F_11F_REV:
-   case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-      return GL_TRUE;
-   }
-
-   return GL_FALSE;
-}
-
-
 
 /**
- * Flip the order of the 2 bytes in each word in the given array.
+ * Flip the order of the 2 bytes in each word in the given array (src) and
+ * store the result in another array (dst). For in-place byte-swapping this
+ * function can be called with the same array for src and dst.
  *
- * \param p array.
+ * \param dst the array where byte-swapped data will be stored.
+ * \param src the array with the source data we want to byte-swap.
  * \param n number of words.
  */
-void
-_mesa_swap2( GLushort *p, GLuint n )
+static void
+swap2_copy( GLushort *dst, GLushort *src, GLuint n )
 {
    GLuint i;
    for (i = 0; i < n; i++) {
-      p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
+      dst[i] = (src[i] >> 8) | ((src[i] << 8) & 0xff00);
    }
 }
 
-
+void
+_mesa_swap2(GLushort *p, GLuint n)
+{
+   swap2_copy(p, p, n);
+}
 
 /*
- * Flip the order of the 4 bytes in each word in the given array.
+ * Flip the order of the 4 bytes in each word in the given array (src) and
+ * store the result in another array (dst). For in-place byte-swapping this
+ * function can be called with the same array for src and dst.
+ *
+ * \param dst the array where byte-swapped data will be stored.
+ * \param src the array with the source data we want to byte-swap.
+ * \param n number of words.
  */
-void
-_mesa_swap4( GLuint *p, GLuint n )
+static void
+swap4_copy( GLuint *dst, GLuint *src, GLuint n )
 {
    GLuint i, a, b;
    for (i = 0; i < n; i++) {
-      b = p[i];
+      b = src[i];
       a =  (b >> 24)
        | ((b >> 8) & 0xff00)
        | ((b << 8) & 0xff0000)
        | ((b << 24) & 0xff000000);
-      p[i] = a;
-   }
-}
-
-
-/**
- * Get the size of a GL data type.
- *
- * \param type GL data type.
- *
- * \return the size, in bytes, of the given data type, 0 if a GL_BITMAP, or -1
- * if an invalid type enum.
- */
-GLint
-_mesa_sizeof_type( GLenum type )
-{
-   switch (type) {
-      case GL_BITMAP:
-        return 0;
-      case GL_UNSIGNED_BYTE:
-         return sizeof(GLubyte);
-      case GL_BYTE:
-        return sizeof(GLbyte);
-      case GL_UNSIGNED_SHORT:
-        return sizeof(GLushort);
-      case GL_SHORT:
-        return sizeof(GLshort);
-      case GL_UNSIGNED_INT:
-        return sizeof(GLuint);
-      case GL_INT:
-        return sizeof(GLint);
-      case GL_FLOAT:
-        return sizeof(GLfloat);
-      case GL_DOUBLE:
-        return sizeof(GLdouble);
-      case GL_HALF_FLOAT_ARB:
-        return sizeof(GLhalfARB);
-      case GL_FIXED:
-        return sizeof(GLfixed);
-      default:
-         return -1;
-   }
-}
-
-
-/**
- * Same as _mesa_sizeof_type() but also accepting the packed pixel
- * format data types.
- */
-GLint
-_mesa_sizeof_packed_type( GLenum type )
-{
-   switch (type) {
-      case GL_BITMAP:
-        return 0;
-      case GL_UNSIGNED_BYTE:
-         return sizeof(GLubyte);
-      case GL_BYTE:
-        return sizeof(GLbyte);
-      case GL_UNSIGNED_SHORT:
-        return sizeof(GLushort);
-      case GL_SHORT:
-        return sizeof(GLshort);
-      case GL_UNSIGNED_INT:
-        return sizeof(GLuint);
-      case GL_INT:
-        return sizeof(GLint);
-      case GL_HALF_FLOAT_ARB:
-        return sizeof(GLhalfARB);
-      case GL_FLOAT:
-        return sizeof(GLfloat);
-      case GL_UNSIGNED_BYTE_3_3_2:
-      case GL_UNSIGNED_BYTE_2_3_3_REV:
-      case MESA_UNSIGNED_BYTE_4_4:
-         return sizeof(GLubyte);
-      case GL_UNSIGNED_SHORT_5_6_5:
-      case GL_UNSIGNED_SHORT_5_6_5_REV:
-      case GL_UNSIGNED_SHORT_4_4_4_4:
-      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-      case GL_UNSIGNED_SHORT_5_5_5_1:
-      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-      case GL_UNSIGNED_SHORT_8_8_MESA:
-      case GL_UNSIGNED_SHORT_8_8_REV_MESA:
-         return sizeof(GLushort);
-      case GL_UNSIGNED_INT_8_8_8_8:
-      case GL_UNSIGNED_INT_8_8_8_8_REV:
-      case GL_UNSIGNED_INT_10_10_10_2:
-      case GL_UNSIGNED_INT_2_10_10_10_REV:
-      case GL_UNSIGNED_INT_24_8_EXT:
-      case GL_UNSIGNED_INT_5_9_9_9_REV:
-      case GL_UNSIGNED_INT_10F_11F_11F_REV:
-         return sizeof(GLuint);
-      case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-         return 8;
-      default:
-         return -1;
-   }
-}
-
-
-/**
- * Get the number of components in a pixel format.
- *
- * \param format pixel format.
- *
- * \return the number of components in the given format, or -1 if a bad format.
- */
-GLint
-_mesa_components_in_format( GLenum format )
-{
-   switch (format) {
-      case GL_COLOR_INDEX:
-      case GL_STENCIL_INDEX:
-      case GL_DEPTH_COMPONENT:
-      case GL_RED:
-      case GL_RED_INTEGER_EXT:
-      case GL_GREEN:
-      case GL_GREEN_INTEGER_EXT:
-      case GL_BLUE:
-      case GL_BLUE_INTEGER_EXT:
-      case GL_ALPHA:
-      case GL_ALPHA_INTEGER_EXT:
-      case GL_LUMINANCE:
-      case GL_LUMINANCE_INTEGER_EXT:
-      case GL_INTENSITY:
-         return 1;
-
-      case GL_LUMINANCE_ALPHA:
-      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
-      case GL_RG:
-      case GL_YCBCR_MESA:
-      case GL_DEPTH_STENCIL_EXT:
-      case GL_DUDV_ATI:
-      case GL_DU8DV8_ATI:
-        return 2;
-
-      case GL_RGB:
-      case GL_BGR:
-      case GL_RGB_INTEGER_EXT:
-        return 3;
-
-      case GL_RGBA:
-      case GL_BGRA:
-      case GL_ABGR_EXT:
-      case GL_RGBA_INTEGER_EXT:
-         return 4;
-
-      default:
-         return -1;
-   }
-}
-
-
-/**
- * Get the bytes per pixel of pixel format type pair.
- *
- * \param format pixel format.
- * \param type pixel type.
- *
- * \return bytes per pixel, or -1 if a bad format or type was given.
- */
-GLint
-_mesa_bytes_per_pixel( GLenum format, GLenum type )
-{
-   GLint comps = _mesa_components_in_format( format );
-   if (comps < 0)
-      return -1;
-
-   switch (type) {
-      case GL_BITMAP:
-         return 0;  /* special case */
-      case GL_BYTE:
-      case GL_UNSIGNED_BYTE:
-         return comps * sizeof(GLubyte);
-      case GL_SHORT:
-      case GL_UNSIGNED_SHORT:
-         return comps * sizeof(GLshort);
-      case GL_INT:
-      case GL_UNSIGNED_INT:
-         return comps * sizeof(GLint);
-      case GL_FLOAT:
-         return comps * sizeof(GLfloat);
-      case GL_HALF_FLOAT_ARB:
-         return comps * sizeof(GLhalfARB);
-      case GL_UNSIGNED_BYTE_3_3_2:
-      case GL_UNSIGNED_BYTE_2_3_3_REV:
-         if (format == GL_RGB || format == GL_BGR ||
-             format == GL_RGB_INTEGER_EXT || format == GL_BGR_INTEGER_EXT)
-            return sizeof(GLubyte);
-         else
-            return -1;  /* error */
-      case GL_UNSIGNED_SHORT_5_6_5:
-      case GL_UNSIGNED_SHORT_5_6_5_REV:
-         if (format == GL_RGB || format == GL_BGR ||
-             format == GL_RGB_INTEGER_EXT || format == GL_BGR_INTEGER_EXT)
-            return sizeof(GLushort);
-         else
-            return -1;  /* error */
-      case GL_UNSIGNED_SHORT_4_4_4_4:
-      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-      case GL_UNSIGNED_SHORT_5_5_5_1:
-      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT ||
-             format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT)
-            return sizeof(GLushort);
-         else
-            return -1;
-      case GL_UNSIGNED_INT_8_8_8_8:
-      case GL_UNSIGNED_INT_8_8_8_8_REV:
-      case GL_UNSIGNED_INT_10_10_10_2:
-      case GL_UNSIGNED_INT_2_10_10_10_REV:
-         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT ||
-             format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT)
-            return sizeof(GLuint);
-         else
-            return -1;
-      case GL_UNSIGNED_SHORT_8_8_MESA:
-      case GL_UNSIGNED_SHORT_8_8_REV_MESA:
-         if (format == GL_YCBCR_MESA)
-            return sizeof(GLushort);
-         else
-            return -1;
-      case GL_UNSIGNED_INT_24_8_EXT:
-         if (format == GL_DEPTH_STENCIL_EXT)
-            return sizeof(GLuint);
-         else
-            return -1;
-      case GL_UNSIGNED_INT_5_9_9_9_REV:
-         if (format == GL_RGB)
-            return sizeof(GLuint);
-         else
-            return -1;
-      case GL_UNSIGNED_INT_10F_11F_11F_REV:
-         if (format == GL_RGB)
-            return sizeof(GLuint);
-         else
-            return -1;
-      case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
-         if (format == GL_DEPTH_STENCIL)
-            return 8;
-         else
-            return -1;
-      default:
-         return -1;
-   }
-}
-
-
-/**
- * Test for a legal pixel format and type.
- *
- * \param format pixel format.
- * \param type pixel type.
- *
- * \return GL_TRUE if the given pixel format and type are legal, or GL_FALSE
- * otherwise.
- */
-GLboolean
-_mesa_is_legal_format_and_type(const struct gl_context *ctx,
-                               GLenum format, GLenum type)
-{
-   switch (format) {
-      case GL_COLOR_INDEX:
-      case GL_STENCIL_INDEX:
-         switch (type) {
-            case GL_BITMAP:
-            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;
-            case GL_HALF_FLOAT_ARB:
-               return ctx->Extensions.ARB_half_float_pixel;
-            default:
-               return GL_FALSE;
-         }
-      case GL_RED:
-      case GL_GREEN:
-      case GL_BLUE:
-      case GL_ALPHA:
-#if 0 /* not legal!  see table 3.6 of the 1.5 spec */
-      case GL_INTENSITY:
-#endif
-      case GL_LUMINANCE:
-      case GL_LUMINANCE_ALPHA:
-      case GL_DEPTH_COMPONENT:
-         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;
-            case GL_HALF_FLOAT_ARB:
-               return ctx->Extensions.ARB_half_float_pixel;
-            default:
-               return GL_FALSE;
-         }
-      case GL_RG:
-        if (!ctx->Extensions.ARB_texture_rg)
-           return GL_FALSE;
-
-         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;
-            case GL_HALF_FLOAT_ARB:
-               return ctx->Extensions.ARB_half_float_pixel;
-            default:
-               return GL_FALSE;
-         }
-      case GL_RGB:
-         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:
-            case GL_UNSIGNED_BYTE_3_3_2:
-            case GL_UNSIGNED_BYTE_2_3_3_REV:
-            case GL_UNSIGNED_SHORT_5_6_5:
-            case GL_UNSIGNED_SHORT_5_6_5_REV:
-               return GL_TRUE;
-            case GL_HALF_FLOAT_ARB:
-               return ctx->Extensions.ARB_half_float_pixel;
-            case GL_UNSIGNED_INT_5_9_9_9_REV:
-               return ctx->Extensions.EXT_texture_shared_exponent;
-            case GL_UNSIGNED_INT_10F_11F_11F_REV:
-               return ctx->Extensions.EXT_packed_float;
-            default:
-               return GL_FALSE;
-         }
-      case GL_BGR:
-         switch (type) {
-            /* NOTE: no packed types are supported with BGR.  That's
-             * intentional, according to the GL spec.
-             */
-            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;
-            case GL_HALF_FLOAT_ARB:
-               return ctx->Extensions.ARB_half_float_pixel;
-            default:
-               return GL_FALSE;
-         }
-      case GL_RGBA:
-      case GL_BGRA:
-      case GL_ABGR_EXT:
-         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:
-            case GL_UNSIGNED_SHORT_4_4_4_4:
-            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-            case GL_UNSIGNED_SHORT_5_5_5_1:
-            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-            case GL_UNSIGNED_INT_8_8_8_8:
-            case GL_UNSIGNED_INT_8_8_8_8_REV:
-            case GL_UNSIGNED_INT_10_10_10_2:
-            case GL_UNSIGNED_INT_2_10_10_10_REV:
-               return GL_TRUE;
-            case GL_HALF_FLOAT_ARB:
-               return ctx->Extensions.ARB_half_float_pixel;
-            default:
-               return GL_FALSE;
-         }
-      case GL_YCBCR_MESA:
-         if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
-             type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
-            return GL_TRUE;
-         else
-            return GL_FALSE;
-      case GL_DEPTH_STENCIL_EXT:
-         if ((ctx->Extensions.EXT_packed_depth_stencil &&
-              type == GL_UNSIGNED_INT_24_8_EXT) ||
-             (ctx->Extensions.ARB_depth_buffer_float &&
-              type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV))
-            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;
-         }
-
-      /* integer-valued formats */
-      case GL_RED_INTEGER_EXT:
-      case GL_GREEN_INTEGER_EXT:
-      case GL_BLUE_INTEGER_EXT:
-      case GL_ALPHA_INTEGER_EXT:
-         switch (type) {
-            case GL_BYTE:
-            case GL_UNSIGNED_BYTE:
-            case GL_SHORT:
-            case GL_UNSIGNED_SHORT:
-            case GL_INT:
-            case GL_UNSIGNED_INT:
-               return ctx->Extensions.EXT_texture_integer;
-            default:
-               return GL_FALSE;
-         }
-
-      case GL_RGB_INTEGER_EXT:
-         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_UNSIGNED_BYTE_3_3_2:
-            case GL_UNSIGNED_BYTE_2_3_3_REV:
-            case GL_UNSIGNED_SHORT_5_6_5:
-            case GL_UNSIGNED_SHORT_5_6_5_REV:
-               return ctx->Extensions.EXT_texture_integer;
-            default:
-               return GL_FALSE;
-         }
-
-      case GL_BGR_INTEGER_EXT:
-         switch (type) {
-            case GL_BYTE:
-            case GL_UNSIGNED_BYTE:
-            case GL_SHORT:
-            case GL_UNSIGNED_SHORT:
-            case GL_INT:
-            case GL_UNSIGNED_INT:
-            /* NOTE: no packed formats w/ BGR format */
-               return ctx->Extensions.EXT_texture_integer;
-            default:
-               return GL_FALSE;
-         }
-
-      case GL_RGBA_INTEGER_EXT:
-      case GL_BGRA_INTEGER_EXT:
-         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_UNSIGNED_SHORT_4_4_4_4:
-            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-            case GL_UNSIGNED_SHORT_5_5_5_1:
-            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-            case GL_UNSIGNED_INT_8_8_8_8:
-            case GL_UNSIGNED_INT_8_8_8_8_REV:
-            case GL_UNSIGNED_INT_10_10_10_2:
-            case GL_UNSIGNED_INT_2_10_10_10_REV:
-               return ctx->Extensions.EXT_texture_integer;
-            default:
-               return GL_FALSE;
-         }
-
-      case GL_LUMINANCE_INTEGER_EXT:
-      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
-         switch (type) {
-            case GL_BYTE:
-            case GL_UNSIGNED_BYTE:
-            case GL_SHORT:
-            case GL_UNSIGNED_SHORT:
-            case GL_INT:
-            case GL_UNSIGNED_INT:
-               return ctx->Extensions.EXT_texture_integer;
-            default:
-               return GL_FALSE;
-         }
-
-      default:
-         ; /* fall-through */
-   }
-   return GL_FALSE;
-}
-
-
-/**
- * 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 GL_R8:
-      case GL_R16:
-      case GL_RG:
-      case GL_RG8:
-      case GL_RG16:
-      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_R16F:
-      case GL_R32F:
-      case GL_RG16F:
-      case GL_RG32F:
-      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_RED:
-      case GL_COMPRESSED_RG:
-      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 */
-      case GL_COMPRESSED_RED_RGTC1:
-      case GL_COMPRESSED_SIGNED_RED_RGTC1:
-      case GL_COMPRESSED_RG_RGTC2:
-      case GL_COMPRESSED_SIGNED_RG_RGTC2:
-      case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
-      case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
-      case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
-      case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
-      case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
-      /* generic integer formats */
-      case GL_RED_INTEGER_EXT:
-      case GL_GREEN_INTEGER_EXT:
-      case GL_BLUE_INTEGER_EXT:
-      case GL_ALPHA_INTEGER_EXT:
-      case GL_RGB_INTEGER_EXT:
-      case GL_RGBA_INTEGER_EXT:
-      case GL_BGR_INTEGER_EXT:
-      case GL_BGRA_INTEGER_EXT:
-      case GL_LUMINANCE_INTEGER_EXT:
-      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
-      /* sized integer formats */
-      case GL_RGBA32UI_EXT:
-      case GL_RGB32UI_EXT:
-      case GL_ALPHA32UI_EXT:
-      case GL_INTENSITY32UI_EXT:
-      case GL_LUMINANCE32UI_EXT:
-      case GL_LUMINANCE_ALPHA32UI_EXT:
-      case GL_RGBA16UI_EXT:
-      case GL_RGB16UI_EXT:
-      case GL_ALPHA16UI_EXT:
-      case GL_INTENSITY16UI_EXT:
-      case GL_LUMINANCE16UI_EXT:
-      case GL_LUMINANCE_ALPHA16UI_EXT:
-      case GL_RGBA8UI_EXT:
-      case GL_RGB8UI_EXT:
-      case GL_ALPHA8UI_EXT:
-      case GL_INTENSITY8UI_EXT:
-      case GL_LUMINANCE8UI_EXT:
-      case GL_LUMINANCE_ALPHA8UI_EXT:
-      case GL_RGBA32I_EXT:
-      case GL_RGB32I_EXT:
-      case GL_ALPHA32I_EXT:
-      case GL_INTENSITY32I_EXT:
-      case GL_LUMINANCE32I_EXT:
-      case GL_LUMINANCE_ALPHA32I_EXT:
-      case GL_RGBA16I_EXT:
-      case GL_RGB16I_EXT:
-      case GL_ALPHA16I_EXT:
-      case GL_INTENSITY16I_EXT:
-      case GL_LUMINANCE16I_EXT:
-      case GL_LUMINANCE_ALPHA16I_EXT:
-      case GL_RGBA8I_EXT:
-      case GL_RGB8I_EXT:
-      case GL_ALPHA8I_EXT:
-      case GL_INTENSITY8I_EXT:
-      case GL_LUMINANCE8I_EXT:
-      case GL_LUMINANCE_ALPHA8I_EXT:
-      /* signed, normalized texture formats */
-      case GL_RED_SNORM:
-      case GL_R8_SNORM:
-      case GL_R16_SNORM:
-      case GL_RG_SNORM:
-      case GL_RG8_SNORM:
-      case GL_RG16_SNORM:
-      case GL_RGB_SNORM:
-      case GL_RGB8_SNORM:
-      case GL_RGB16_SNORM:
-      case GL_RGBA_SNORM:
-      case GL_RGBA8_SNORM:
-      case GL_RGBA16_SNORM:
-      case GL_ALPHA_SNORM:
-      case GL_ALPHA8_SNORM:
-      case GL_ALPHA16_SNORM:
-      case GL_LUMINANCE_SNORM:
-      case GL_LUMINANCE8_SNORM:
-      case GL_LUMINANCE16_SNORM:
-      case GL_LUMINANCE_ALPHA_SNORM:
-      case GL_LUMINANCE8_ALPHA8_SNORM:
-      case GL_LUMINANCE16_ALPHA16_SNORM:
-      case GL_INTENSITY_SNORM:
-      case GL_INTENSITY8_SNORM:
-      case GL_INTENSITY16_SNORM:
-      case GL_RGB9_E5:
-      case GL_R11F_G11F_B10F:
-         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 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:
-      case GL_DEPTH_COMPONENT32F:
-         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:
-      case GL_DEPTH32F_STENCIL8:
-         return GL_TRUE;
-      default:
-         return GL_FALSE;
+      dst[i] = a;
    }
 }
 
-
-/**
- * Test if the given image format is a depth or stencil format.
- */
-GLboolean
-_mesa_is_depth_or_stencil_format(GLenum format)
-{
-   switch (format) {
-      case GL_DEPTH_COMPONENT:
-      case GL_DEPTH_COMPONENT16:
-      case GL_DEPTH_COMPONENT24:
-      case GL_DEPTH_COMPONENT32:
-      case GL_STENCIL_INDEX:
-      case GL_STENCIL_INDEX1_EXT:
-      case GL_STENCIL_INDEX4_EXT:
-      case GL_STENCIL_INDEX8_EXT:
-      case GL_STENCIL_INDEX16_EXT:
-      case GL_DEPTH_STENCIL_EXT:
-      case GL_DEPTH24_STENCIL8_EXT:
-      case GL_DEPTH_COMPONENT32F:
-      case GL_DEPTH32F_STENCIL8:
-         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;
-   }
-}
-
-
-/**
- * Test if the given format is an integer (non-normalized) format.
- */
-GLboolean
-_mesa_is_integer_format(GLenum format)
-{
-   switch (format) {
-   /* generic integer formats */
-   case GL_RED_INTEGER_EXT:
-   case GL_GREEN_INTEGER_EXT:
-   case GL_BLUE_INTEGER_EXT:
-   case GL_ALPHA_INTEGER_EXT:
-   case GL_RGB_INTEGER_EXT:
-   case GL_RGBA_INTEGER_EXT:
-   case GL_BGR_INTEGER_EXT:
-   case GL_BGRA_INTEGER_EXT:
-   case GL_LUMINANCE_INTEGER_EXT:
-   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
-   /* specific integer formats */
-   case GL_RGBA32UI_EXT:
-   case GL_RGB32UI_EXT:
-   case GL_ALPHA32UI_EXT:
-   case GL_INTENSITY32UI_EXT:
-   case GL_LUMINANCE32UI_EXT:
-   case GL_LUMINANCE_ALPHA32UI_EXT:
-   case GL_RGBA16UI_EXT:
-   case GL_RGB16UI_EXT:
-   case GL_ALPHA16UI_EXT:
-   case GL_INTENSITY16UI_EXT:
-   case GL_LUMINANCE16UI_EXT:
-   case GL_LUMINANCE_ALPHA16UI_EXT:
-   case GL_RGBA8UI_EXT:
-   case GL_RGB8UI_EXT:
-   case GL_ALPHA8UI_EXT:
-   case GL_INTENSITY8UI_EXT:
-   case GL_LUMINANCE8UI_EXT:
-   case GL_LUMINANCE_ALPHA8UI_EXT:
-   case GL_RGBA32I_EXT:
-   case GL_RGB32I_EXT:
-   case GL_ALPHA32I_EXT:
-   case GL_INTENSITY32I_EXT:
-   case GL_LUMINANCE32I_EXT:
-   case GL_LUMINANCE_ALPHA32I_EXT:
-   case GL_RGBA16I_EXT:
-   case GL_RGB16I_EXT:
-   case GL_ALPHA16I_EXT:
-   case GL_INTENSITY16I_EXT:
-   case GL_LUMINANCE16I_EXT:
-   case GL_LUMINANCE_ALPHA16I_EXT:
-   case GL_RGBA8I_EXT:
-   case GL_RGB8I_EXT:
-   case GL_ALPHA8I_EXT:
-   case GL_INTENSITY8I_EXT:
-   case GL_LUMINANCE8I_EXT:
-   case GL_LUMINANCE_ALPHA8I_EXT:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Test if an image format is a supported compressed format.
- * \param format the internal format token provided by the user.
- * \return GL_TRUE if compressed, GL_FALSE if uncompressed
- */
-GLboolean
-_mesa_is_compressed_format(struct gl_context *ctx, GLenum format)
+void
+_mesa_swap4(GLuint *p, GLuint n)
 {
-   switch (format) {
-   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:
-      return ctx->Extensions.EXT_texture_compression_s3tc;
-   case GL_RGB_S3TC:
-   case GL_RGB4_S3TC:
-   case GL_RGBA_S3TC:
-   case GL_RGBA4_S3TC:
-      return ctx->Extensions.S3_s3tc;
-   case GL_COMPRESSED_SRGB_S3TC_DXT1_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:
-      return ctx->Extensions.EXT_texture_sRGB
-         && ctx->Extensions.EXT_texture_compression_s3tc;
-   case GL_COMPRESSED_RGB_FXT1_3DFX:
-   case GL_COMPRESSED_RGBA_FXT1_3DFX:
-      return ctx->Extensions.TDFX_texture_compression_FXT1;
-   case GL_COMPRESSED_RED_RGTC1:
-   case GL_COMPRESSED_SIGNED_RED_RGTC1:
-   case GL_COMPRESSED_RG_RGTC2:
-   case GL_COMPRESSED_SIGNED_RG_RGTC2:
-      return ctx->Extensions.ARB_texture_compression_rgtc;
-   case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
-   case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
-   case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
-   case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
-      return ctx->Extensions.EXT_texture_compression_latc;
-   case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
-      return ctx->Extensions.ATI_texture_compression_3dc;
-#if FEATURE_ES
-   case GL_PALETTE4_RGB8_OES:
-   case GL_PALETTE4_RGBA8_OES:
-   case GL_PALETTE4_R5_G6_B5_OES:
-   case GL_PALETTE4_RGBA4_OES:
-   case GL_PALETTE4_RGB5_A1_OES:
-   case GL_PALETTE8_RGB8_OES:
-   case GL_PALETTE8_RGBA8_OES:
-   case GL_PALETTE8_R5_G6_B5_OES:
-   case GL_PALETTE8_RGBA4_OES:
-   case GL_PALETTE8_RGB5_A1_OES:
-      return ctx->API == API_OPENGLES;
-#endif
-   default:
-      return GL_FALSE;
-   }
+   swap4_copy(p, p, n);
 }
 
-
 /**
- * Return the address of a specific pixel in an image (1D, 2D or 3D).
+ * Return the byte offset of a specific pixel in an image (1D, 2D or 3D).
  *
  * Pixel unpacking/packing parameters are observed according to \p packing.
  *
  * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
- * \param image  starting address of image data
- * \param width  the image width
- * \param height  theimage height
- * \param format  the pixel format
- * \param type  the pixel data type
  * \param packing  the pixelstore attributes
+ * \param width  the image width
+ * \param height  the image height
+ * \param format  the pixel format (must be validated beforehand)
+ * \param type  the pixel data type (must be validated beforehand)
  * \param img  which image in the volume (0 for 1D or 2D images)
  * \param row  row of pixel in the image (0 for 1D images)
  * \param column column of pixel in the image
- * 
- * \return address of pixel on success, or NULL on error.
+ *
+ * \return offset of pixel.
  *
  * \sa gl_pixelstore_attrib.
  */
-GLvoid *
-_mesa_image_address( GLuint dimensions,
-                     const struct gl_pixelstore_attrib *packing,
-                     const GLvoid *image,
-                     GLsizei width, GLsizei height,
-                     GLenum format, GLenum type,
-                     GLint img, GLint row, GLint column )
+GLintptr
+_mesa_image_offset( GLuint dimensions,
+                    const struct gl_pixelstore_attrib *packing,
+                    GLsizei width, GLsizei height,
+                    GLenum format, GLenum type,
+                    GLint img, GLint row, GLint column )
 {
    GLint alignment;        /* 1, 2 or 4 */
    GLint pixels_per_row;
@@ -1105,9 +125,9 @@ _mesa_image_address( GLuint dimensions,
    GLint skiprows;
    GLint skippixels;
    GLint skipimages;       /* for 3-D volume images */
-   GLubyte *pixel_addr;
+   GLintptr offset;
 
-   ASSERT(dimensions >= 1 && dimensions <= 3);
+   assert(dimensions >= 1 && dimensions <= 3);
 
    alignment = packing->Alignment;
    if (packing->RowLength > 0) {
@@ -1131,37 +151,27 @@ _mesa_image_address( GLuint dimensions,
 
    if (type == GL_BITMAP) {
       /* BITMAP data */
-      GLint comp_per_pixel;   /* components per pixel */
-      GLint bytes_per_comp;   /* bytes per component */
-      GLint bytes_per_row;
-      GLint bytes_per_image;
-
-      /* Compute bytes per component */
-      bytes_per_comp = _mesa_sizeof_packed_type( type );
-      if (bytes_per_comp < 0) {
-         return NULL;
-      }
+      GLintptr bytes_per_row;
+      GLintptr bytes_per_image;
+      /* components per pixel for color or stencil index: */
+      const GLint comp_per_pixel = 1;
 
-      /* Compute number of components per pixel */
-      comp_per_pixel = _mesa_components_in_format( format );
-      if (comp_per_pixel < 0) {
-         return NULL;
-      }
+      /* The pixel type and format should have been error checked earlier */
+      assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX);
 
       bytes_per_row = alignment
-                    * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
+                    * DIV_ROUND_UP( comp_per_pixel*pixels_per_row, 8*alignment );
 
       bytes_per_image = bytes_per_row * rows_per_image;
 
-      pixel_addr = (GLubyte *) image
-                 + (skipimages + img) * bytes_per_image
+      offset = (skipimages + img) * bytes_per_image
                  + (skiprows + row) * bytes_per_row
                  + (skippixels + column) / 8;
    }
    else {
       /* Non-BITMAP data */
-      GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
-      GLint topOfImage;
+      GLintptr bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
+      GLintptr topOfImage;
 
       bytes_per_pixel = _mesa_bytes_per_pixel( format, type );
 
@@ -1173,7 +183,7 @@ _mesa_image_address( GLuint dimensions,
       if (remainder > 0)
          bytes_per_row += (alignment - remainder);
 
-      ASSERT(bytes_per_row % alignment == 0);
+      assert(bytes_per_row % alignment == 0);
 
       bytes_per_image = bytes_per_row * rows_per_image;
 
@@ -1187,14 +197,50 @@ _mesa_image_address( GLuint dimensions,
       }
 
       /* compute final pixel address */
-      pixel_addr = (GLubyte *) image
-                 + (skipimages + img) * bytes_per_image
+      offset = (skipimages + img) * bytes_per_image
                  + topOfImage
                  + (skiprows + row) * bytes_per_row
                  + (skippixels + column) * bytes_per_pixel;
    }
 
-   return (GLvoid *) pixel_addr;
+   return offset;
+}
+
+
+/**
+ * Return the address of a specific pixel in an image (1D, 2D or 3D).
+ *
+ * Pixel unpacking/packing parameters are observed according to \p packing.
+ *
+ * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
+ * \param packing  the pixelstore attributes
+ * \param image  starting address of image data
+ * \param width  the image width
+ * \param height  the image height
+ * \param format  the pixel format (must be validated beforehand)
+ * \param type  the pixel data type (must be validated beforehand)
+ * \param img  which image in the volume (0 for 1D or 2D images)
+ * \param row  row of pixel in the image (0 for 1D images)
+ * \param column column of pixel in the image
+ *
+ * \return address of pixel.
+ *
+ * \sa gl_pixelstore_attrib.
+ */
+GLvoid *
+_mesa_image_address( GLuint dimensions,
+                     const struct gl_pixelstore_attrib *packing,
+                     const GLvoid *image,
+                     GLsizei width, GLsizei height,
+                     GLenum format, GLenum type,
+                     GLint img, GLint row, GLint column )
+{
+   const GLubyte *addr = (const GLubyte *) image;
+
+   addr += _mesa_image_offset(dimensions, packing, width, height,
+                              format, type, img, row, column);
+
+   return (GLvoid *) addr;
 }
 
 
@@ -1251,7 +297,7 @@ _mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
 {
    GLint bytesPerRow, remainder;
 
-   ASSERT(packing);
+   assert(packing);
 
    if (type == GL_BITMAP) {
       if (packing->RowLength == 0) {
@@ -1299,7 +345,7 @@ _mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
 {
    GLint bytesPerRow, bytesPerImage, remainder;
 
-   ASSERT(packing);
+   assert(packing);
 
    if (type == GL_BITMAP) {
       if (packing->RowLength == 0) {
@@ -1362,9 +408,7 @@ _mesa_expand_bitmap(GLsizei width, GLsizei height,
    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;
+   GLubyte *dstRow = destBuffer;
 
    for (row = 0; row < height; row++) {
       const GLubyte *src = srcRow;
@@ -1375,7 +419,7 @@ _mesa_expand_bitmap(GLsizei width, GLsizei height,
          for (col = 0; col < width; col++) {
 
             if (*src & mask) {
-               SET_PIXEL(col, row);
+               dstRow[col] = onValue;
             }
 
             if (mask == 128U) {
@@ -1397,7 +441,7 @@ _mesa_expand_bitmap(GLsizei width, GLsizei height,
          for (col = 0; col < width; col++) {
 
             if (*src & mask) {
-               SET_PIXEL(col, row);
+               dstRow[col] = onValue;
             }
 
             if (mask == 1U) {
@@ -1415,9 +459,8 @@ _mesa_expand_bitmap(GLsizei width, GLsizei height,
       }
 
       srcRow += srcStride;
+      dstRow += destStride;
    } /* row */
-
-#undef SET_PIXEL
 }
 
 
@@ -1432,10 +475,14 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
                      GLenum dstType, GLvoid *dst,
                      GLuint count, const GLubyte mask[])
 {
-   GLuint tempBuffer[MAX_WIDTH][4];
+   GLuint *tempBuffer;
    const GLboolean useTemp = (src == dst);
 
-   ASSERT(srcType != dstType);
+   tempBuffer = malloc(count * MAX_PIXEL_BYTES);
+   if (!tempBuffer)
+      return;
+
+   assert(srcType != dstType);
 
    switch (srcType) {
    case GL_UNSIGNED_BYTE:
@@ -1458,7 +505,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
          const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
          GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
          GLuint i;
-         ASSERT(dstType == GL_FLOAT);
+         assert(dstType == GL_FLOAT);
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]);
@@ -1491,7 +538,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
          const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
          GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
          GLuint i;
-         ASSERT(dstType == GL_FLOAT);
+         assert(dstType == GL_FLOAT);
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]);
@@ -1520,7 +567,7 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
          const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
          GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
          GLuint i;
-         ASSERT(dstType == GL_UNSIGNED_SHORT);
+         assert(dstType == GL_UNSIGNED_SHORT);
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]);
@@ -1534,8 +581,10 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src,
       }
       break;
    default:
-      _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors");
+      unreachable("Invalid datatype in _mesa_convert_colors");
    }
+
+   free(tempBuffer);
 }
 
 
@@ -1564,8 +613,8 @@ _mesa_clip_drawpixels(const struct gl_context *ctx,
       unpack->RowLength = *width;
    }
 
-   ASSERT(ctx->Pixel.ZoomX == 1.0F);
-   ASSERT(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F);
+   assert(ctx->Pixel.ZoomX == 1.0F);
+   assert(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F);
 
    /* left clipping */
    if (*destX < buffer->_Xmin) {
@@ -1618,7 +667,7 @@ _mesa_clip_drawpixels(const struct gl_context *ctx,
  * so that the image region is entirely within the window bounds.
  * Note: this is different from _mesa_clip_drawpixels() in that the
  * scissor box is ignored, and we use the bounds of the current readbuffer
- * surface.
+ * surface or the attached image.
  *
  * \return  GL_TRUE if region to read is in bounds
  *          GL_FALSE if region is completely out of bounds (nothing to read)
@@ -1630,6 +679,18 @@ _mesa_clip_readpixels(const struct gl_context *ctx,
                       struct gl_pixelstore_attrib *pack)
 {
    const struct gl_framebuffer *buffer = ctx->ReadBuffer;
+   struct gl_renderbuffer *rb = buffer->_ColorReadBuffer;
+   GLsizei clip_width;
+   GLsizei clip_height;
+
+   if (rb) {
+      clip_width = rb->Width;
+      clip_height = rb->Height;
+   } else {
+      clip_width = buffer->Width;
+      clip_height = buffer->Height;
+   }
+
 
    if (pack->RowLength == 0) {
       pack->RowLength = *width;
@@ -1642,8 +703,8 @@ _mesa_clip_readpixels(const struct gl_context *ctx,
       *srcX = 0;
    }
    /* right clipping */
-   if (*srcX + *width > (GLsizei) buffer->Width)
-      *width -= (*srcX + *width - buffer->Width);
+   if (*srcX + *width > clip_width)
+      *width -= (*srcX + *width - clip_width);
 
    if (*width <= 0)
       return GL_FALSE;
@@ -1655,8 +716,8 @@ _mesa_clip_readpixels(const struct gl_context *ctx,
       *srcY = 0;
    }
    /* top clipping */
-   if (*srcY + *height > (GLsizei) buffer->Height)
-      *height -= (*srcY + *height - buffer->Height);
+   if (*srcY + *height > clip_height)
+      *height -= (*srcY + *height - clip_height);
 
    if (*height <= 0)
       return GL_FALSE;
@@ -1749,20 +810,20 @@ clip_right_or_top(GLint *srcX0, GLint *srcX1,
 
    if (*dstX1 > maxValue) {
       /* X1 outside right edge */
-      ASSERT(*dstX0 < maxValue); /* X0 should be inside 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);
+      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 */
+      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);
+      assert(t >= 0.0 && t <= 1.0);
       *dstX0 = maxValue;
       bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F;
       *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
@@ -1782,22 +843,22 @@ clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
 
    if (*dstX0 < minValue) {
       /* X0 outside left edge */
-      ASSERT(*dstX1 > minValue); /* X1 should be inside 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);
+      assert(t >= 0.0 && t <= 1.0);
       *dstX0 = minValue;
-      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; /* flipped??? */
+      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
       *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
    }
    else if (*dstX1 < minValue) {
       /* X1 outside left edge */
-      ASSERT(*dstX0 > minValue); /* X0 should be inside 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);
+      assert(t >= 0.0 && t <= 1.0);
       *dstX1 = minValue;
-      bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F;
+      bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F;
       *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
    }
 }
@@ -1818,19 +879,21 @@ clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
  */
 GLboolean
 _mesa_clip_blit(struct gl_context *ctx,
+                const struct gl_framebuffer *readFb,
+                const struct gl_framebuffer *drawFb,
                 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 srcXmax = readFb->Width;
    const GLint srcYmin = 0;
-   const GLint srcYmax = ctx->ReadBuffer->Height;
+   const GLint srcYmax = readFb->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;
+   const GLint dstXmin = drawFb->_Xmin;
+   const GLint dstXmax = drawFb->_Xmax;
+   const GLint dstYmin = drawFb->_Ymin;
+   const GLint dstYmax = drawFb->_Ymax;
 
    /*
    printf("PreClipX:  src: %d .. %d  dst: %d .. %d\n",
@@ -1891,25 +954,64 @@ _mesa_clip_blit(struct gl_context *ctx,
           *srcY0, *srcY1, *dstY0, *dstY1);
    */
 
-   ASSERT(*dstX0 >= dstXmin);
-   ASSERT(*dstX0 <= dstXmax);
-   ASSERT(*dstX1 >= dstXmin);
-   ASSERT(*dstX1 <= dstXmax);
+   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(*dstY0 >= dstYmin);
+   assert(*dstY0 <= dstYmax);
+   assert(*dstY1 >= dstYmin);
+   assert(*dstY1 <= dstYmax);
 
-   ASSERT(*srcX0 >= srcXmin);
-   ASSERT(*srcX0 <= srcXmax);
-   ASSERT(*srcX1 >= srcXmin);
-   ASSERT(*srcX1 <= srcXmax);
+   assert(*srcX0 >= srcXmin);
+   assert(*srcX0 <= srcXmax);
+   assert(*srcX1 >= srcXmin);
+   assert(*srcX1 <= srcXmax);
 
-   ASSERT(*srcY0 >= srcYmin);
-   ASSERT(*srcY0 <= srcYmax);
-   ASSERT(*srcY1 >= srcYmin);
-   ASSERT(*srcY1 <= srcYmax);
+   assert(*srcY0 >= srcYmin);
+   assert(*srcY0 <= srcYmax);
+   assert(*srcY1 >= srcYmin);
+   assert(*srcY1 <= srcYmax);
 
    return GL_TRUE;
 }
+
+/**
+ * Swap the bytes in a 2D image.
+ *
+ * using the packing information this swaps the bytes
+ * according to the format and type of data being input.
+ * It takes into a/c various packing parameters like
+ * Alignment and RowLength.
+ */
+void
+_mesa_swap_bytes_2d_image(GLenum format, GLenum type,
+                          const struct gl_pixelstore_attrib *packing,
+                          GLsizei width, GLsizei height,
+                          GLvoid *dst, const GLvoid *src)
+{
+   GLint swapSize = _mesa_sizeof_packed_type(type);
+
+   assert(packing->SwapBytes);
+
+   if (swapSize == 2 || swapSize == 4) {
+      int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize;
+      int stride = _mesa_image_row_stride(packing, width, format, type);
+      int row;
+      uint8_t *dstrow;
+      const uint8_t *srcrow;
+      assert(swapsPerPixel > 0);
+      assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0);
+      dstrow = dst;
+      srcrow = src;
+      for (row = 0; row < height; row++) {
+         if (swapSize == 2)
+            swap2_copy((GLushort *)dstrow, (GLushort *)srcrow, width * swapsPerPixel);
+         else if (swapSize == 4)
+            swap4_copy((GLuint *)dstrow, (GLuint *)srcrow, width * swapsPerPixel);
+         dstrow += stride;
+         srcrow += stride;
+      }
+   }
+}