image.c revision 4a49301e
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
3c7037ccdSmrg * Version:  7.5
47117f1b4Smrg *
5c1f859d4Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6c7037ccdSmrg * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
77117f1b4Smrg *
87117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
97117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
107117f1b4Smrg * to deal in the Software without restriction, including without limitation
117117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
127117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
137117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
147117f1b4Smrg *
157117f1b4Smrg * The above copyright notice and this permission notice shall be included
167117f1b4Smrg * in all copies or substantial portions of the Software.
177117f1b4Smrg *
187117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
197117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
207117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
217117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
227117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
237117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
247117f1b4Smrg */
257117f1b4Smrg
267117f1b4Smrg
277117f1b4Smrg/**
287117f1b4Smrg * \file image.c
297117f1b4Smrg * Image handling.
307117f1b4Smrg */
317117f1b4Smrg
327117f1b4Smrg
337117f1b4Smrg#include "glheader.h"
347117f1b4Smrg#include "colormac.h"
357117f1b4Smrg#include "context.h"
367117f1b4Smrg#include "image.h"
377117f1b4Smrg#include "imports.h"
387117f1b4Smrg#include "macros.h"
397117f1b4Smrg
407117f1b4Smrg
417117f1b4Smrg/**
427117f1b4Smrg * NOTE:
437117f1b4Smrg * Normally, BYTE_TO_FLOAT(0) returns 0.00392  That causes problems when
447117f1b4Smrg * we later convert the float to a packed integer value (such as for
457117f1b4Smrg * GL_RGB5_A1) because we'll wind up with a non-zero value.
467117f1b4Smrg *
477117f1b4Smrg * We redefine the macros here so zero is handled correctly.
487117f1b4Smrg */
497117f1b4Smrg#undef BYTE_TO_FLOAT
507117f1b4Smrg#define BYTE_TO_FLOAT(B)    ((B) == 0 ? 0.0F : ((2.0F * (B) + 1.0F) * (1.0F/255.0F)))
517117f1b4Smrg
527117f1b4Smrg#undef SHORT_TO_FLOAT
537117f1b4Smrg#define SHORT_TO_FLOAT(S)   ((S) == 0 ? 0.0F : ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)))
547117f1b4Smrg
557117f1b4Smrg
567117f1b4Smrg
577117f1b4Smrg/** Compute ceiling of integer quotient of A divided by B. */
587117f1b4Smrg#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
597117f1b4Smrg
607117f1b4Smrg
617117f1b4Smrg/**
627117f1b4Smrg * \return GL_TRUE if type is packed pixel type, GL_FALSE otherwise.
637117f1b4Smrg */
64c1f859d4SmrgGLboolean
657117f1b4Smrg_mesa_type_is_packed(GLenum type)
667117f1b4Smrg{
677117f1b4Smrg   switch (type) {
687117f1b4Smrg   case GL_UNSIGNED_BYTE_3_3_2:
697117f1b4Smrg   case GL_UNSIGNED_BYTE_2_3_3_REV:
707117f1b4Smrg   case GL_UNSIGNED_SHORT_5_6_5:
717117f1b4Smrg   case GL_UNSIGNED_SHORT_5_6_5_REV:
727117f1b4Smrg   case GL_UNSIGNED_SHORT_4_4_4_4:
737117f1b4Smrg   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
747117f1b4Smrg   case GL_UNSIGNED_SHORT_5_5_5_1:
757117f1b4Smrg   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
767117f1b4Smrg   case GL_UNSIGNED_INT_8_8_8_8:
777117f1b4Smrg   case GL_UNSIGNED_INT_8_8_8_8_REV:
787117f1b4Smrg   case GL_UNSIGNED_INT_10_10_10_2:
797117f1b4Smrg   case GL_UNSIGNED_INT_2_10_10_10_REV:
807117f1b4Smrg   case GL_UNSIGNED_SHORT_8_8_MESA:
817117f1b4Smrg   case GL_UNSIGNED_SHORT_8_8_REV_MESA:
827117f1b4Smrg   case GL_UNSIGNED_INT_24_8_EXT:
837117f1b4Smrg      return GL_TRUE;
847117f1b4Smrg   }
857117f1b4Smrg
867117f1b4Smrg   return GL_FALSE;
877117f1b4Smrg}
887117f1b4Smrg
897117f1b4Smrg/**
907117f1b4Smrg * Flip the 8 bits in each byte of the given array.
917117f1b4Smrg *
927117f1b4Smrg * \param p array.
937117f1b4Smrg * \param n number of bytes.
947117f1b4Smrg *
957117f1b4Smrg * \todo try this trick to flip bytes someday:
967117f1b4Smrg * \code
977117f1b4Smrg *  v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555);
987117f1b4Smrg *  v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333);
997117f1b4Smrg *  v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f);
1007117f1b4Smrg * \endcode
1017117f1b4Smrg */
1027117f1b4Smrgstatic void
1037117f1b4Smrgflip_bytes( GLubyte *p, GLuint n )
1047117f1b4Smrg{
1057117f1b4Smrg   GLuint i, a, b;
1067117f1b4Smrg   for (i = 0; i < n; i++) {
1077117f1b4Smrg      b = (GLuint) p[i];        /* words are often faster than bytes */
1087117f1b4Smrg      a = ((b & 0x01) << 7) |
1097117f1b4Smrg	  ((b & 0x02) << 5) |
1107117f1b4Smrg	  ((b & 0x04) << 3) |
1117117f1b4Smrg	  ((b & 0x08) << 1) |
1127117f1b4Smrg	  ((b & 0x10) >> 1) |
1137117f1b4Smrg	  ((b & 0x20) >> 3) |
1147117f1b4Smrg	  ((b & 0x40) >> 5) |
1157117f1b4Smrg	  ((b & 0x80) >> 7);
1167117f1b4Smrg      p[i] = (GLubyte) a;
1177117f1b4Smrg   }
1187117f1b4Smrg}
1197117f1b4Smrg
1207117f1b4Smrg
1217117f1b4Smrg/**
1227117f1b4Smrg * Flip the order of the 2 bytes in each word in the given array.
1237117f1b4Smrg *
1247117f1b4Smrg * \param p array.
1257117f1b4Smrg * \param n number of words.
1267117f1b4Smrg */
1277117f1b4Smrgvoid
1287117f1b4Smrg_mesa_swap2( GLushort *p, GLuint n )
1297117f1b4Smrg{
1307117f1b4Smrg   GLuint i;
1317117f1b4Smrg   for (i = 0; i < n; i++) {
1327117f1b4Smrg      p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
1337117f1b4Smrg   }
1347117f1b4Smrg}
1357117f1b4Smrg
1367117f1b4Smrg
1377117f1b4Smrg
1387117f1b4Smrg/*
1397117f1b4Smrg * Flip the order of the 4 bytes in each word in the given array.
1407117f1b4Smrg */
1417117f1b4Smrgvoid
1427117f1b4Smrg_mesa_swap4( GLuint *p, GLuint n )
1437117f1b4Smrg{
1447117f1b4Smrg   GLuint i, a, b;
1457117f1b4Smrg   for (i = 0; i < n; i++) {
1467117f1b4Smrg      b = p[i];
1477117f1b4Smrg      a =  (b >> 24)
1487117f1b4Smrg	| ((b >> 8) & 0xff00)
1497117f1b4Smrg	| ((b << 8) & 0xff0000)
1507117f1b4Smrg	| ((b << 24) & 0xff000000);
1517117f1b4Smrg      p[i] = a;
1527117f1b4Smrg   }
1537117f1b4Smrg}
1547117f1b4Smrg
1557117f1b4Smrg
1567117f1b4Smrg/**
1577117f1b4Smrg * Get the size of a GL data type.
1587117f1b4Smrg *
1597117f1b4Smrg * \param type GL data type.
1607117f1b4Smrg *
1617117f1b4Smrg * \return the size, in bytes, of the given data type, 0 if a GL_BITMAP, or -1
1627117f1b4Smrg * if an invalid type enum.
1637117f1b4Smrg */
1647117f1b4SmrgGLint
1657117f1b4Smrg_mesa_sizeof_type( GLenum type )
1667117f1b4Smrg{
1677117f1b4Smrg   switch (type) {
1687117f1b4Smrg      case GL_BITMAP:
1697117f1b4Smrg	 return 0;
1707117f1b4Smrg      case GL_UNSIGNED_BYTE:
1717117f1b4Smrg         return sizeof(GLubyte);
1727117f1b4Smrg      case GL_BYTE:
1737117f1b4Smrg	 return sizeof(GLbyte);
1747117f1b4Smrg      case GL_UNSIGNED_SHORT:
1757117f1b4Smrg	 return sizeof(GLushort);
1767117f1b4Smrg      case GL_SHORT:
1777117f1b4Smrg	 return sizeof(GLshort);
1787117f1b4Smrg      case GL_UNSIGNED_INT:
1797117f1b4Smrg	 return sizeof(GLuint);
1807117f1b4Smrg      case GL_INT:
1817117f1b4Smrg	 return sizeof(GLint);
1827117f1b4Smrg      case GL_FLOAT:
1837117f1b4Smrg	 return sizeof(GLfloat);
1844a49301eSmrg      case GL_DOUBLE:
1854a49301eSmrg	 return sizeof(GLdouble);
1867117f1b4Smrg      case GL_HALF_FLOAT_ARB:
1877117f1b4Smrg	 return sizeof(GLhalfARB);
1887117f1b4Smrg      default:
1897117f1b4Smrg         return -1;
1907117f1b4Smrg   }
1917117f1b4Smrg}
1927117f1b4Smrg
1937117f1b4Smrg
1947117f1b4Smrg/**
1957117f1b4Smrg * Same as _mesa_sizeof_type() but also accepting the packed pixel
1967117f1b4Smrg * format data types.
1977117f1b4Smrg */
1987117f1b4SmrgGLint
1997117f1b4Smrg_mesa_sizeof_packed_type( GLenum type )
2007117f1b4Smrg{
2017117f1b4Smrg   switch (type) {
2027117f1b4Smrg      case GL_BITMAP:
2037117f1b4Smrg	 return 0;
2047117f1b4Smrg      case GL_UNSIGNED_BYTE:
2057117f1b4Smrg         return sizeof(GLubyte);
2067117f1b4Smrg      case GL_BYTE:
2077117f1b4Smrg	 return sizeof(GLbyte);
2087117f1b4Smrg      case GL_UNSIGNED_SHORT:
2097117f1b4Smrg	 return sizeof(GLushort);
2107117f1b4Smrg      case GL_SHORT:
2117117f1b4Smrg	 return sizeof(GLshort);
2127117f1b4Smrg      case GL_UNSIGNED_INT:
2137117f1b4Smrg	 return sizeof(GLuint);
2147117f1b4Smrg      case GL_INT:
2157117f1b4Smrg	 return sizeof(GLint);
2167117f1b4Smrg      case GL_HALF_FLOAT_ARB:
2177117f1b4Smrg	 return sizeof(GLhalfARB);
2187117f1b4Smrg      case GL_FLOAT:
2197117f1b4Smrg	 return sizeof(GLfloat);
2207117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
2217117f1b4Smrg         return sizeof(GLubyte);
2227117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
2237117f1b4Smrg         return sizeof(GLubyte);
2247117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
2257117f1b4Smrg         return sizeof(GLushort);
2267117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
2277117f1b4Smrg         return sizeof(GLushort);
2287117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
2297117f1b4Smrg         return sizeof(GLushort);
2307117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2317117f1b4Smrg         return sizeof(GLushort);
2327117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
2337117f1b4Smrg         return sizeof(GLushort);
2347117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2357117f1b4Smrg         return sizeof(GLushort);
2367117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
2377117f1b4Smrg         return sizeof(GLuint);
2387117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
2397117f1b4Smrg         return sizeof(GLuint);
2407117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
2417117f1b4Smrg         return sizeof(GLuint);
2427117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
2437117f1b4Smrg         return sizeof(GLuint);
2447117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_MESA:
2457117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_REV_MESA:
2467117f1b4Smrg         return sizeof(GLushort);
2477117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT:
2487117f1b4Smrg         return sizeof(GLuint);
2497117f1b4Smrg      default:
2507117f1b4Smrg         return -1;
2517117f1b4Smrg   }
2527117f1b4Smrg}
2537117f1b4Smrg
2547117f1b4Smrg
2557117f1b4Smrg/**
2567117f1b4Smrg * Get the number of components in a pixel format.
2577117f1b4Smrg *
2587117f1b4Smrg * \param format pixel format.
2597117f1b4Smrg *
2607117f1b4Smrg * \return the number of components in the given format, or -1 if a bad format.
2617117f1b4Smrg */
2627117f1b4SmrgGLint
2637117f1b4Smrg_mesa_components_in_format( GLenum format )
2647117f1b4Smrg{
2657117f1b4Smrg   switch (format) {
2667117f1b4Smrg      case GL_COLOR_INDEX:
2677117f1b4Smrg      case GL_COLOR_INDEX1_EXT:
2687117f1b4Smrg      case GL_COLOR_INDEX2_EXT:
2697117f1b4Smrg      case GL_COLOR_INDEX4_EXT:
2707117f1b4Smrg      case GL_COLOR_INDEX8_EXT:
2717117f1b4Smrg      case GL_COLOR_INDEX12_EXT:
2727117f1b4Smrg      case GL_COLOR_INDEX16_EXT:
2737117f1b4Smrg      case GL_STENCIL_INDEX:
2747117f1b4Smrg      case GL_DEPTH_COMPONENT:
2757117f1b4Smrg      case GL_RED:
2767117f1b4Smrg      case GL_GREEN:
2777117f1b4Smrg      case GL_BLUE:
2787117f1b4Smrg      case GL_ALPHA:
2797117f1b4Smrg      case GL_LUMINANCE:
2807117f1b4Smrg      case GL_INTENSITY:
2817117f1b4Smrg         return 1;
2827117f1b4Smrg      case GL_LUMINANCE_ALPHA:
2837117f1b4Smrg	 return 2;
2847117f1b4Smrg      case GL_RGB:
2857117f1b4Smrg	 return 3;
2867117f1b4Smrg      case GL_RGBA:
2877117f1b4Smrg	 return 4;
2887117f1b4Smrg      case GL_BGR:
2897117f1b4Smrg	 return 3;
2907117f1b4Smrg      case GL_BGRA:
2917117f1b4Smrg	 return 4;
2927117f1b4Smrg      case GL_ABGR_EXT:
2937117f1b4Smrg         return 4;
2947117f1b4Smrg      case GL_YCBCR_MESA:
2957117f1b4Smrg         return 2;
2967117f1b4Smrg      case GL_DEPTH_STENCIL_EXT:
2977117f1b4Smrg         return 2;
2984a49301eSmrg      case GL_DUDV_ATI:
2994a49301eSmrg      case GL_DU8DV8_ATI:
3004a49301eSmrg         return 2;
3017117f1b4Smrg      default:
3027117f1b4Smrg         return -1;
3037117f1b4Smrg   }
3047117f1b4Smrg}
3057117f1b4Smrg
3067117f1b4Smrg
3077117f1b4Smrg/**
3087117f1b4Smrg * Get the bytes per pixel of pixel format type pair.
3097117f1b4Smrg *
3107117f1b4Smrg * \param format pixel format.
3117117f1b4Smrg * \param type pixel type.
3127117f1b4Smrg *
3137117f1b4Smrg * \return bytes per pixel, or -1 if a bad format or type was given.
3147117f1b4Smrg */
3157117f1b4SmrgGLint
3167117f1b4Smrg_mesa_bytes_per_pixel( GLenum format, GLenum type )
3177117f1b4Smrg{
3187117f1b4Smrg   GLint comps = _mesa_components_in_format( format );
3197117f1b4Smrg   if (comps < 0)
3207117f1b4Smrg      return -1;
3217117f1b4Smrg
3227117f1b4Smrg   switch (type) {
3237117f1b4Smrg      case GL_BITMAP:
3247117f1b4Smrg         return 0;  /* special case */
3257117f1b4Smrg      case GL_BYTE:
3267117f1b4Smrg      case GL_UNSIGNED_BYTE:
3277117f1b4Smrg         return comps * sizeof(GLubyte);
3287117f1b4Smrg      case GL_SHORT:
3297117f1b4Smrg      case GL_UNSIGNED_SHORT:
3307117f1b4Smrg         return comps * sizeof(GLshort);
3317117f1b4Smrg      case GL_INT:
3327117f1b4Smrg      case GL_UNSIGNED_INT:
3337117f1b4Smrg         return comps * sizeof(GLint);
3347117f1b4Smrg      case GL_FLOAT:
3357117f1b4Smrg         return comps * sizeof(GLfloat);
3367117f1b4Smrg      case GL_HALF_FLOAT_ARB:
3377117f1b4Smrg         return comps * sizeof(GLhalfARB);
3387117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
3397117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
3407117f1b4Smrg         if (format == GL_RGB || format == GL_BGR)
3417117f1b4Smrg            return sizeof(GLubyte);
3427117f1b4Smrg         else
3437117f1b4Smrg            return -1;  /* error */
3447117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
3457117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
3467117f1b4Smrg         if (format == GL_RGB || format == GL_BGR)
3477117f1b4Smrg            return sizeof(GLushort);
3487117f1b4Smrg         else
3497117f1b4Smrg            return -1;  /* error */
3507117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
3517117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3527117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
3537117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3547117f1b4Smrg         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
3557117f1b4Smrg            return sizeof(GLushort);
3567117f1b4Smrg         else
3577117f1b4Smrg            return -1;
3587117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
3597117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
3607117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
3617117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
3627117f1b4Smrg         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
3637117f1b4Smrg            return sizeof(GLuint);
3647117f1b4Smrg         else
3657117f1b4Smrg            return -1;
3667117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_MESA:
3677117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_REV_MESA:
3687117f1b4Smrg         if (format == GL_YCBCR_MESA)
3697117f1b4Smrg            return sizeof(GLushort);
3707117f1b4Smrg         else
3717117f1b4Smrg            return -1;
3727117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT:
3737117f1b4Smrg         if (format == GL_DEPTH_STENCIL_EXT)
3747117f1b4Smrg            return sizeof(GLuint);
3757117f1b4Smrg         else
3767117f1b4Smrg            return -1;
3777117f1b4Smrg      default:
3787117f1b4Smrg         return -1;
3797117f1b4Smrg   }
3807117f1b4Smrg}
3817117f1b4Smrg
3827117f1b4Smrg
3837117f1b4Smrg/**
3847117f1b4Smrg * Test for a legal pixel format and type.
3857117f1b4Smrg *
3867117f1b4Smrg * \param format pixel format.
3877117f1b4Smrg * \param type pixel type.
3887117f1b4Smrg *
3897117f1b4Smrg * \return GL_TRUE if the given pixel format and type are legal, or GL_FALSE
3907117f1b4Smrg * otherwise.
3917117f1b4Smrg */
3927117f1b4SmrgGLboolean
3937117f1b4Smrg_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
3947117f1b4Smrg{
3957117f1b4Smrg   switch (format) {
3967117f1b4Smrg      case GL_COLOR_INDEX:
3977117f1b4Smrg      case GL_STENCIL_INDEX:
3987117f1b4Smrg         switch (type) {
3997117f1b4Smrg            case GL_BITMAP:
4007117f1b4Smrg            case GL_BYTE:
4017117f1b4Smrg            case GL_UNSIGNED_BYTE:
4027117f1b4Smrg            case GL_SHORT:
4037117f1b4Smrg            case GL_UNSIGNED_SHORT:
4047117f1b4Smrg            case GL_INT:
4057117f1b4Smrg            case GL_UNSIGNED_INT:
4067117f1b4Smrg            case GL_FLOAT:
4077117f1b4Smrg               return GL_TRUE;
4087117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4097117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4107117f1b4Smrg            default:
4117117f1b4Smrg               return GL_FALSE;
4127117f1b4Smrg         }
4137117f1b4Smrg      case GL_RED:
4147117f1b4Smrg      case GL_GREEN:
4157117f1b4Smrg      case GL_BLUE:
4167117f1b4Smrg      case GL_ALPHA:
4177117f1b4Smrg#if 0 /* not legal!  see table 3.6 of the 1.5 spec */
4187117f1b4Smrg      case GL_INTENSITY:
4197117f1b4Smrg#endif
4207117f1b4Smrg      case GL_LUMINANCE:
4217117f1b4Smrg      case GL_LUMINANCE_ALPHA:
4227117f1b4Smrg      case GL_DEPTH_COMPONENT:
4237117f1b4Smrg         switch (type) {
4247117f1b4Smrg            case GL_BYTE:
4257117f1b4Smrg            case GL_UNSIGNED_BYTE:
4267117f1b4Smrg            case GL_SHORT:
4277117f1b4Smrg            case GL_UNSIGNED_SHORT:
4287117f1b4Smrg            case GL_INT:
4297117f1b4Smrg            case GL_UNSIGNED_INT:
4307117f1b4Smrg            case GL_FLOAT:
4317117f1b4Smrg               return GL_TRUE;
4327117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4337117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4347117f1b4Smrg            default:
4357117f1b4Smrg               return GL_FALSE;
4367117f1b4Smrg         }
4377117f1b4Smrg      case GL_RGB:
4387117f1b4Smrg         switch (type) {
4397117f1b4Smrg            case GL_BYTE:
4407117f1b4Smrg            case GL_UNSIGNED_BYTE:
4417117f1b4Smrg            case GL_SHORT:
4427117f1b4Smrg            case GL_UNSIGNED_SHORT:
4437117f1b4Smrg            case GL_INT:
4447117f1b4Smrg            case GL_UNSIGNED_INT:
4457117f1b4Smrg            case GL_FLOAT:
4467117f1b4Smrg            case GL_UNSIGNED_BYTE_3_3_2:
4477117f1b4Smrg            case GL_UNSIGNED_BYTE_2_3_3_REV:
4487117f1b4Smrg            case GL_UNSIGNED_SHORT_5_6_5:
4497117f1b4Smrg            case GL_UNSIGNED_SHORT_5_6_5_REV:
4507117f1b4Smrg               return GL_TRUE;
4517117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4527117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4537117f1b4Smrg            default:
4547117f1b4Smrg               return GL_FALSE;
4557117f1b4Smrg         }
4567117f1b4Smrg      case GL_BGR:
4577117f1b4Smrg         switch (type) {
4587117f1b4Smrg            /* NOTE: no packed types are supported with BGR.  That's
4597117f1b4Smrg             * intentional, according to the GL spec.
4607117f1b4Smrg             */
4617117f1b4Smrg            case GL_BYTE:
4627117f1b4Smrg            case GL_UNSIGNED_BYTE:
4637117f1b4Smrg            case GL_SHORT:
4647117f1b4Smrg            case GL_UNSIGNED_SHORT:
4657117f1b4Smrg            case GL_INT:
4667117f1b4Smrg            case GL_UNSIGNED_INT:
4677117f1b4Smrg            case GL_FLOAT:
4687117f1b4Smrg               return GL_TRUE;
4697117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4707117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4717117f1b4Smrg            default:
4727117f1b4Smrg               return GL_FALSE;
4737117f1b4Smrg         }
4747117f1b4Smrg      case GL_RGBA:
4757117f1b4Smrg      case GL_BGRA:
4767117f1b4Smrg      case GL_ABGR_EXT:
4777117f1b4Smrg         switch (type) {
4787117f1b4Smrg            case GL_BYTE:
4797117f1b4Smrg            case GL_UNSIGNED_BYTE:
4807117f1b4Smrg            case GL_SHORT:
4817117f1b4Smrg            case GL_UNSIGNED_SHORT:
4827117f1b4Smrg            case GL_INT:
4837117f1b4Smrg            case GL_UNSIGNED_INT:
4847117f1b4Smrg            case GL_FLOAT:
4857117f1b4Smrg            case GL_UNSIGNED_SHORT_4_4_4_4:
4867117f1b4Smrg            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4877117f1b4Smrg            case GL_UNSIGNED_SHORT_5_5_5_1:
4887117f1b4Smrg            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4897117f1b4Smrg            case GL_UNSIGNED_INT_8_8_8_8:
4907117f1b4Smrg            case GL_UNSIGNED_INT_8_8_8_8_REV:
4917117f1b4Smrg            case GL_UNSIGNED_INT_10_10_10_2:
4927117f1b4Smrg            case GL_UNSIGNED_INT_2_10_10_10_REV:
4937117f1b4Smrg               return GL_TRUE;
4947117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4957117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4967117f1b4Smrg            default:
4977117f1b4Smrg               return GL_FALSE;
4987117f1b4Smrg         }
4997117f1b4Smrg      case GL_YCBCR_MESA:
5007117f1b4Smrg         if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
5017117f1b4Smrg             type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
5027117f1b4Smrg            return GL_TRUE;
5037117f1b4Smrg         else
5047117f1b4Smrg            return GL_FALSE;
5057117f1b4Smrg      case GL_DEPTH_STENCIL_EXT:
5067117f1b4Smrg         if (ctx->Extensions.EXT_packed_depth_stencil
5077117f1b4Smrg             && type == GL_UNSIGNED_INT_24_8_EXT)
5087117f1b4Smrg            return GL_TRUE;
5097117f1b4Smrg         else
5107117f1b4Smrg            return GL_FALSE;
5114a49301eSmrg      case GL_DUDV_ATI:
5124a49301eSmrg      case GL_DU8DV8_ATI:
5134a49301eSmrg         switch (type) {
5144a49301eSmrg            case GL_BYTE:
5154a49301eSmrg            case GL_UNSIGNED_BYTE:
5164a49301eSmrg            case GL_SHORT:
5174a49301eSmrg            case GL_UNSIGNED_SHORT:
5184a49301eSmrg            case GL_INT:
5194a49301eSmrg            case GL_UNSIGNED_INT:
5204a49301eSmrg            case GL_FLOAT:
5214a49301eSmrg               return GL_TRUE;
5224a49301eSmrg            default:
5234a49301eSmrg               return GL_FALSE;
5244a49301eSmrg         }
5257117f1b4Smrg      default:
5267117f1b4Smrg         ; /* fall-through */
5277117f1b4Smrg   }
5287117f1b4Smrg   return GL_FALSE;
5297117f1b4Smrg}
5307117f1b4Smrg
5317117f1b4Smrg
5324a49301eSmrg/**
5334a49301eSmrg * Test if the given image format is a color/RGBA format (i.e., not color
5344a49301eSmrg * index, depth, stencil, etc).
5354a49301eSmrg * \param format  the image format value (may by an internal texture format)
5364a49301eSmrg * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
5374a49301eSmrg */
5384a49301eSmrgGLboolean
5394a49301eSmrg_mesa_is_color_format(GLenum format)
5404a49301eSmrg{
5414a49301eSmrg   switch (format) {
5424a49301eSmrg      case GL_RED:
5434a49301eSmrg      case GL_GREEN:
5444a49301eSmrg      case GL_BLUE:
5454a49301eSmrg      case GL_ALPHA:
5464a49301eSmrg      case GL_ALPHA4:
5474a49301eSmrg      case GL_ALPHA8:
5484a49301eSmrg      case GL_ALPHA12:
5494a49301eSmrg      case GL_ALPHA16:
5504a49301eSmrg      case 1:
5514a49301eSmrg      case GL_LUMINANCE:
5524a49301eSmrg      case GL_LUMINANCE4:
5534a49301eSmrg      case GL_LUMINANCE8:
5544a49301eSmrg      case GL_LUMINANCE12:
5554a49301eSmrg      case GL_LUMINANCE16:
5564a49301eSmrg      case 2:
5574a49301eSmrg      case GL_LUMINANCE_ALPHA:
5584a49301eSmrg      case GL_LUMINANCE4_ALPHA4:
5594a49301eSmrg      case GL_LUMINANCE6_ALPHA2:
5604a49301eSmrg      case GL_LUMINANCE8_ALPHA8:
5614a49301eSmrg      case GL_LUMINANCE12_ALPHA4:
5624a49301eSmrg      case GL_LUMINANCE12_ALPHA12:
5634a49301eSmrg      case GL_LUMINANCE16_ALPHA16:
5644a49301eSmrg      case GL_INTENSITY:
5654a49301eSmrg      case GL_INTENSITY4:
5664a49301eSmrg      case GL_INTENSITY8:
5674a49301eSmrg      case GL_INTENSITY12:
5684a49301eSmrg      case GL_INTENSITY16:
5694a49301eSmrg      case 3:
5704a49301eSmrg      case GL_RGB:
5714a49301eSmrg      case GL_BGR:
5724a49301eSmrg      case GL_R3_G3_B2:
5734a49301eSmrg      case GL_RGB4:
5744a49301eSmrg      case GL_RGB5:
5754a49301eSmrg      case GL_RGB8:
5764a49301eSmrg      case GL_RGB10:
5774a49301eSmrg      case GL_RGB12:
5784a49301eSmrg      case GL_RGB16:
5794a49301eSmrg      case 4:
5804a49301eSmrg      case GL_ABGR_EXT:
5814a49301eSmrg      case GL_RGBA:
5824a49301eSmrg      case GL_BGRA:
5834a49301eSmrg      case GL_RGBA2:
5844a49301eSmrg      case GL_RGBA4:
5854a49301eSmrg      case GL_RGB5_A1:
5864a49301eSmrg      case GL_RGBA8:
5874a49301eSmrg      case GL_RGB10_A2:
5884a49301eSmrg      case GL_RGBA12:
5894a49301eSmrg      case GL_RGBA16:
5904a49301eSmrg      /* float texture formats */
5914a49301eSmrg      case GL_ALPHA16F_ARB:
5924a49301eSmrg      case GL_ALPHA32F_ARB:
5934a49301eSmrg      case GL_LUMINANCE16F_ARB:
5944a49301eSmrg      case GL_LUMINANCE32F_ARB:
5954a49301eSmrg      case GL_LUMINANCE_ALPHA16F_ARB:
5964a49301eSmrg      case GL_LUMINANCE_ALPHA32F_ARB:
5974a49301eSmrg      case GL_INTENSITY16F_ARB:
5984a49301eSmrg      case GL_INTENSITY32F_ARB:
5994a49301eSmrg      case GL_RGB16F_ARB:
6004a49301eSmrg      case GL_RGB32F_ARB:
6014a49301eSmrg      case GL_RGBA16F_ARB:
6024a49301eSmrg      case GL_RGBA32F_ARB:
6034a49301eSmrg      /* compressed formats */
6044a49301eSmrg      case GL_COMPRESSED_ALPHA:
6054a49301eSmrg      case GL_COMPRESSED_LUMINANCE:
6064a49301eSmrg      case GL_COMPRESSED_LUMINANCE_ALPHA:
6074a49301eSmrg      case GL_COMPRESSED_INTENSITY:
6084a49301eSmrg      case GL_COMPRESSED_RGB:
6094a49301eSmrg      case GL_COMPRESSED_RGBA:
6104a49301eSmrg      case GL_RGB_S3TC:
6114a49301eSmrg      case GL_RGB4_S3TC:
6124a49301eSmrg      case GL_RGBA_S3TC:
6134a49301eSmrg      case GL_RGBA4_S3TC:
6144a49301eSmrg      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6154a49301eSmrg      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6164a49301eSmrg      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
6174a49301eSmrg      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
6184a49301eSmrg      case GL_COMPRESSED_RGB_FXT1_3DFX:
6194a49301eSmrg      case GL_COMPRESSED_RGBA_FXT1_3DFX:
6204a49301eSmrg#if FEATURE_EXT_texture_sRGB
6214a49301eSmrg      case GL_SRGB_EXT:
6224a49301eSmrg      case GL_SRGB8_EXT:
6234a49301eSmrg      case GL_SRGB_ALPHA_EXT:
6244a49301eSmrg      case GL_SRGB8_ALPHA8_EXT:
6254a49301eSmrg      case GL_SLUMINANCE_ALPHA_EXT:
6264a49301eSmrg      case GL_SLUMINANCE8_ALPHA8_EXT:
6274a49301eSmrg      case GL_SLUMINANCE_EXT:
6284a49301eSmrg      case GL_SLUMINANCE8_EXT:
6294a49301eSmrg      case GL_COMPRESSED_SRGB_EXT:
6304a49301eSmrg      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
6314a49301eSmrg      case GL_COMPRESSED_SRGB_ALPHA_EXT:
6324a49301eSmrg      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
6334a49301eSmrg      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
6344a49301eSmrg      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
6354a49301eSmrg      case GL_COMPRESSED_SLUMINANCE_EXT:
6364a49301eSmrg      case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
6374a49301eSmrg#endif /* FEATURE_EXT_texture_sRGB */
6384a49301eSmrg         return GL_TRUE;
6394a49301eSmrg      /* signed texture formats */
6404a49301eSmrg      case GL_RGBA_SNORM:
6414a49301eSmrg      case GL_RGBA8_SNORM:
6424a49301eSmrg         return GL_TRUE;
6434a49301eSmrg      case GL_YCBCR_MESA:  /* not considered to be RGB */
6444a49301eSmrg         /* fall-through */
6454a49301eSmrg      default:
6464a49301eSmrg         return GL_FALSE;
6474a49301eSmrg   }
6484a49301eSmrg}
6494a49301eSmrg
6504a49301eSmrg
6514a49301eSmrg/**
6524a49301eSmrg * Test if the given image format is a color index format.
6534a49301eSmrg */
6544a49301eSmrgGLboolean
6554a49301eSmrg_mesa_is_index_format(GLenum format)
6564a49301eSmrg{
6574a49301eSmrg   switch (format) {
6584a49301eSmrg      case GL_COLOR_INDEX:
6594a49301eSmrg      case GL_COLOR_INDEX1_EXT:
6604a49301eSmrg      case GL_COLOR_INDEX2_EXT:
6614a49301eSmrg      case GL_COLOR_INDEX4_EXT:
6624a49301eSmrg      case GL_COLOR_INDEX8_EXT:
6634a49301eSmrg      case GL_COLOR_INDEX12_EXT:
6644a49301eSmrg      case GL_COLOR_INDEX16_EXT:
6654a49301eSmrg         return GL_TRUE;
6664a49301eSmrg      default:
6674a49301eSmrg         return GL_FALSE;
6684a49301eSmrg   }
6694a49301eSmrg}
6704a49301eSmrg
6714a49301eSmrg
6724a49301eSmrg/**
6734a49301eSmrg * Test if the given image format is a depth component format.
6744a49301eSmrg */
6754a49301eSmrgGLboolean
6764a49301eSmrg_mesa_is_depth_format(GLenum format)
6774a49301eSmrg{
6784a49301eSmrg   switch (format) {
6794a49301eSmrg      case GL_DEPTH_COMPONENT:
6804a49301eSmrg      case GL_DEPTH_COMPONENT16:
6814a49301eSmrg      case GL_DEPTH_COMPONENT24:
6824a49301eSmrg      case GL_DEPTH_COMPONENT32:
6834a49301eSmrg         return GL_TRUE;
6844a49301eSmrg      default:
6854a49301eSmrg         return GL_FALSE;
6864a49301eSmrg   }
6874a49301eSmrg}
6884a49301eSmrg
6894a49301eSmrg
6904a49301eSmrg/**
6914a49301eSmrg * Test if the given image format is a stencil format.
6924a49301eSmrg */
6934a49301eSmrgGLboolean
6944a49301eSmrg_mesa_is_stencil_format(GLenum format)
6954a49301eSmrg{
6964a49301eSmrg   switch (format) {
6974a49301eSmrg      case GL_STENCIL_INDEX:
6984a49301eSmrg      case GL_DEPTH_STENCIL:
6994a49301eSmrg         return GL_TRUE;
7004a49301eSmrg      default:
7014a49301eSmrg         return GL_FALSE;
7024a49301eSmrg   }
7034a49301eSmrg}
7044a49301eSmrg
7054a49301eSmrg
7064a49301eSmrg/**
7074a49301eSmrg * Test if the given image format is a YCbCr format.
7084a49301eSmrg */
7094a49301eSmrgGLboolean
7104a49301eSmrg_mesa_is_ycbcr_format(GLenum format)
7114a49301eSmrg{
7124a49301eSmrg   switch (format) {
7134a49301eSmrg      case GL_YCBCR_MESA:
7144a49301eSmrg         return GL_TRUE;
7154a49301eSmrg      default:
7164a49301eSmrg         return GL_FALSE;
7174a49301eSmrg   }
7184a49301eSmrg}
7194a49301eSmrg
7204a49301eSmrg
7214a49301eSmrg/**
7224a49301eSmrg * Test if the given image format is a depth+stencil format.
7234a49301eSmrg */
7244a49301eSmrgGLboolean
7254a49301eSmrg_mesa_is_depthstencil_format(GLenum format)
7264a49301eSmrg{
7274a49301eSmrg   switch (format) {
7284a49301eSmrg      case GL_DEPTH24_STENCIL8_EXT:
7294a49301eSmrg      case GL_DEPTH_STENCIL_EXT:
7304a49301eSmrg         return GL_TRUE;
7314a49301eSmrg      default:
7324a49301eSmrg         return GL_FALSE;
7334a49301eSmrg   }
7344a49301eSmrg}
7354a49301eSmrg
7364a49301eSmrg/**
7374a49301eSmrg * Test if the given image format is a dudv format.
7384a49301eSmrg */
7394a49301eSmrgGLboolean
7404a49301eSmrg_mesa_is_dudv_format(GLenum format)
7414a49301eSmrg{
7424a49301eSmrg   switch (format) {
7434a49301eSmrg      case GL_DUDV_ATI:
7444a49301eSmrg      case GL_DU8DV8_ATI:
7454a49301eSmrg         return GL_TRUE;
7464a49301eSmrg      default:
7474a49301eSmrg         return GL_FALSE;
7484a49301eSmrg   }
7494a49301eSmrg}
7504a49301eSmrg
7514a49301eSmrg
7527117f1b4Smrg/**
7537117f1b4Smrg * Return the address of a specific pixel in an image (1D, 2D or 3D).
7547117f1b4Smrg *
7557117f1b4Smrg * Pixel unpacking/packing parameters are observed according to \p packing.
7567117f1b4Smrg *
7577117f1b4Smrg * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
7587117f1b4Smrg * \param image  starting address of image data
7597117f1b4Smrg * \param width  the image width
7607117f1b4Smrg * \param height  theimage height
7617117f1b4Smrg * \param format  the pixel format
7627117f1b4Smrg * \param type  the pixel data type
7637117f1b4Smrg * \param packing  the pixelstore attributes
7647117f1b4Smrg * \param img  which image in the volume (0 for 1D or 2D images)
7657117f1b4Smrg * \param row  row of pixel in the image (0 for 1D images)
7667117f1b4Smrg * \param column column of pixel in the image
7677117f1b4Smrg *
7687117f1b4Smrg * \return address of pixel on success, or NULL on error.
7697117f1b4Smrg *
7707117f1b4Smrg * \sa gl_pixelstore_attrib.
7717117f1b4Smrg */
7727117f1b4SmrgGLvoid *
7737117f1b4Smrg_mesa_image_address( GLuint dimensions,
7747117f1b4Smrg                     const struct gl_pixelstore_attrib *packing,
7757117f1b4Smrg                     const GLvoid *image,
7767117f1b4Smrg                     GLsizei width, GLsizei height,
7777117f1b4Smrg                     GLenum format, GLenum type,
7787117f1b4Smrg                     GLint img, GLint row, GLint column )
7797117f1b4Smrg{
7807117f1b4Smrg   GLint alignment;        /* 1, 2 or 4 */
7817117f1b4Smrg   GLint pixels_per_row;
7827117f1b4Smrg   GLint rows_per_image;
7837117f1b4Smrg   GLint skiprows;
7847117f1b4Smrg   GLint skippixels;
7857117f1b4Smrg   GLint skipimages;       /* for 3-D volume images */
7867117f1b4Smrg   GLubyte *pixel_addr;
7877117f1b4Smrg
7887117f1b4Smrg   ASSERT(dimensions >= 1 && dimensions <= 3);
7897117f1b4Smrg
7907117f1b4Smrg   alignment = packing->Alignment;
7917117f1b4Smrg   if (packing->RowLength > 0) {
7927117f1b4Smrg      pixels_per_row = packing->RowLength;
7937117f1b4Smrg   }
7947117f1b4Smrg   else {
7957117f1b4Smrg      pixels_per_row = width;
7967117f1b4Smrg   }
7977117f1b4Smrg   if (packing->ImageHeight > 0) {
7987117f1b4Smrg      rows_per_image = packing->ImageHeight;
7997117f1b4Smrg   }
8007117f1b4Smrg   else {
8017117f1b4Smrg      rows_per_image = height;
8027117f1b4Smrg   }
8037117f1b4Smrg
8047117f1b4Smrg   skippixels = packing->SkipPixels;
8057117f1b4Smrg   /* Note: SKIP_ROWS _is_ used for 1D images */
8067117f1b4Smrg   skiprows = packing->SkipRows;
8077117f1b4Smrg   /* Note: SKIP_IMAGES is only used for 3D images */
8087117f1b4Smrg   skipimages = (dimensions == 3) ? packing->SkipImages : 0;
8097117f1b4Smrg
8107117f1b4Smrg   if (type == GL_BITMAP) {
8117117f1b4Smrg      /* BITMAP data */
8127117f1b4Smrg      GLint comp_per_pixel;   /* components per pixel */
8137117f1b4Smrg      GLint bytes_per_comp;   /* bytes per component */
8147117f1b4Smrg      GLint bytes_per_row;
8157117f1b4Smrg      GLint bytes_per_image;
8167117f1b4Smrg
8177117f1b4Smrg      /* Compute bytes per component */
8187117f1b4Smrg      bytes_per_comp = _mesa_sizeof_packed_type( type );
8197117f1b4Smrg      if (bytes_per_comp < 0) {
8207117f1b4Smrg         return NULL;
8217117f1b4Smrg      }
8227117f1b4Smrg
8237117f1b4Smrg      /* Compute number of components per pixel */
8247117f1b4Smrg      comp_per_pixel = _mesa_components_in_format( format );
8257117f1b4Smrg      if (comp_per_pixel < 0) {
8267117f1b4Smrg         return NULL;
8277117f1b4Smrg      }
8287117f1b4Smrg
8297117f1b4Smrg      bytes_per_row = alignment
8307117f1b4Smrg                    * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
8317117f1b4Smrg
8327117f1b4Smrg      bytes_per_image = bytes_per_row * rows_per_image;
8337117f1b4Smrg
8347117f1b4Smrg      pixel_addr = (GLubyte *) image
8357117f1b4Smrg                 + (skipimages + img) * bytes_per_image
8367117f1b4Smrg                 + (skiprows + row) * bytes_per_row
8377117f1b4Smrg                 + (skippixels + column) / 8;
8387117f1b4Smrg   }
8397117f1b4Smrg   else {
8407117f1b4Smrg      /* Non-BITMAP data */
8417117f1b4Smrg      GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
8427117f1b4Smrg      GLint topOfImage;
8437117f1b4Smrg
8447117f1b4Smrg      bytes_per_pixel = _mesa_bytes_per_pixel( format, type );
8457117f1b4Smrg
8467117f1b4Smrg      /* The pixel type and format should have been error checked earlier */
8477117f1b4Smrg      assert(bytes_per_pixel > 0);
8487117f1b4Smrg
8497117f1b4Smrg      bytes_per_row = pixels_per_row * bytes_per_pixel;
8507117f1b4Smrg      remainder = bytes_per_row % alignment;
8517117f1b4Smrg      if (remainder > 0)
8527117f1b4Smrg         bytes_per_row += (alignment - remainder);
8537117f1b4Smrg
8547117f1b4Smrg      ASSERT(bytes_per_row % alignment == 0);
8557117f1b4Smrg
8567117f1b4Smrg      bytes_per_image = bytes_per_row * rows_per_image;
8577117f1b4Smrg
8587117f1b4Smrg      if (packing->Invert) {
8597117f1b4Smrg         /* set pixel_addr to the last row */
8607117f1b4Smrg         topOfImage = bytes_per_row * (height - 1);
8617117f1b4Smrg         bytes_per_row = -bytes_per_row;
8627117f1b4Smrg      }
8637117f1b4Smrg      else {
8647117f1b4Smrg         topOfImage = 0;
8657117f1b4Smrg      }
8667117f1b4Smrg
8677117f1b4Smrg      /* compute final pixel address */
8687117f1b4Smrg      pixel_addr = (GLubyte *) image
8697117f1b4Smrg                 + (skipimages + img) * bytes_per_image
8707117f1b4Smrg                 + topOfImage
8717117f1b4Smrg                 + (skiprows + row) * bytes_per_row
8727117f1b4Smrg                 + (skippixels + column) * bytes_per_pixel;
8737117f1b4Smrg   }
8747117f1b4Smrg
8757117f1b4Smrg   return (GLvoid *) pixel_addr;
8767117f1b4Smrg}
8777117f1b4Smrg
8787117f1b4Smrg
8797117f1b4SmrgGLvoid *
8807117f1b4Smrg_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
8817117f1b4Smrg                       const GLvoid *image,
8827117f1b4Smrg                       GLsizei width,
8837117f1b4Smrg                       GLenum format, GLenum type,
8847117f1b4Smrg                       GLint column )
8857117f1b4Smrg{
8867117f1b4Smrg   return _mesa_image_address(1, packing, image, width, 1,
8877117f1b4Smrg                              format, type, 0, 0, column);
8887117f1b4Smrg}
8897117f1b4Smrg
8907117f1b4Smrg
8917117f1b4SmrgGLvoid *
8927117f1b4Smrg_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
8937117f1b4Smrg                       const GLvoid *image,
8947117f1b4Smrg                       GLsizei width, GLsizei height,
8957117f1b4Smrg                       GLenum format, GLenum type,
8967117f1b4Smrg                       GLint row, GLint column )
8977117f1b4Smrg{
8987117f1b4Smrg   return _mesa_image_address(2, packing, image, width, height,
8997117f1b4Smrg                              format, type, 0, row, column);
9007117f1b4Smrg}
9017117f1b4Smrg
9027117f1b4Smrg
9037117f1b4SmrgGLvoid *
9047117f1b4Smrg_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
9057117f1b4Smrg                       const GLvoid *image,
9067117f1b4Smrg                       GLsizei width, GLsizei height,
9077117f1b4Smrg                       GLenum format, GLenum type,
9087117f1b4Smrg                       GLint img, GLint row, GLint column )
9097117f1b4Smrg{
9107117f1b4Smrg   return _mesa_image_address(3, packing, image, width, height,
9117117f1b4Smrg                              format, type, img, row, column);
9127117f1b4Smrg}
9137117f1b4Smrg
9147117f1b4Smrg
9157117f1b4Smrg
9167117f1b4Smrg/**
9177117f1b4Smrg * Compute the stride (in bytes) between image rows.
9187117f1b4Smrg *
9197117f1b4Smrg * \param packing the pixelstore attributes
9207117f1b4Smrg * \param width image width.
9217117f1b4Smrg * \param format pixel format.
9227117f1b4Smrg * \param type pixel data type.
9237117f1b4Smrg *
9247117f1b4Smrg * \return the stride in bytes for the given parameters, or -1 if error
9257117f1b4Smrg */
9267117f1b4SmrgGLint
9277117f1b4Smrg_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
9287117f1b4Smrg                        GLint width, GLenum format, GLenum type )
9297117f1b4Smrg{
9307117f1b4Smrg   GLint bytesPerRow, remainder;
9317117f1b4Smrg
9327117f1b4Smrg   ASSERT(packing);
9337117f1b4Smrg
9347117f1b4Smrg   if (type == GL_BITMAP) {
9357117f1b4Smrg      if (packing->RowLength == 0) {
9367117f1b4Smrg         bytesPerRow = (width + 7) / 8;
9377117f1b4Smrg      }
9387117f1b4Smrg      else {
9397117f1b4Smrg         bytesPerRow = (packing->RowLength + 7) / 8;
9407117f1b4Smrg      }
9417117f1b4Smrg   }
9427117f1b4Smrg   else {
9437117f1b4Smrg      /* Non-BITMAP data */
9447117f1b4Smrg      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
9457117f1b4Smrg      if (bytesPerPixel <= 0)
9467117f1b4Smrg         return -1;  /* error */
9477117f1b4Smrg      if (packing->RowLength == 0) {
9487117f1b4Smrg         bytesPerRow = bytesPerPixel * width;
9497117f1b4Smrg      }
9507117f1b4Smrg      else {
9517117f1b4Smrg         bytesPerRow = bytesPerPixel * packing->RowLength;
9527117f1b4Smrg      }
9537117f1b4Smrg   }
9547117f1b4Smrg
9557117f1b4Smrg   remainder = bytesPerRow % packing->Alignment;
9567117f1b4Smrg   if (remainder > 0) {
9577117f1b4Smrg      bytesPerRow += (packing->Alignment - remainder);
9587117f1b4Smrg   }
9597117f1b4Smrg
9607117f1b4Smrg   if (packing->Invert) {
9617117f1b4Smrg      /* negate the bytes per row (negative row stride) */
9627117f1b4Smrg      bytesPerRow = -bytesPerRow;
9637117f1b4Smrg   }
9647117f1b4Smrg
9657117f1b4Smrg   return bytesPerRow;
9667117f1b4Smrg}
9677117f1b4Smrg
9687117f1b4Smrg
9697117f1b4Smrg#if _HAVE_FULL_GL
9707117f1b4Smrg
9717117f1b4Smrg/*
9727117f1b4Smrg * Compute the stride between images in a 3D texture (in bytes) for the given
9737117f1b4Smrg * pixel packing parameters and image width, format and type.
9747117f1b4Smrg */
9757117f1b4SmrgGLint
9767117f1b4Smrg_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
9777117f1b4Smrg                          GLint width, GLint height,
9787117f1b4Smrg                          GLenum format, GLenum type )
9797117f1b4Smrg{
980c7037ccdSmrg   GLint bytesPerRow, bytesPerImage, remainder;
981c7037ccdSmrg
9827117f1b4Smrg   ASSERT(packing);
9837117f1b4Smrg
984c7037ccdSmrg   if (type == GL_BITMAP) {
985c7037ccdSmrg      if (packing->RowLength == 0) {
986c7037ccdSmrg         bytesPerRow = (width + 7) / 8;
987c7037ccdSmrg      }
988c7037ccdSmrg      else {
989c7037ccdSmrg         bytesPerRow = (packing->RowLength + 7) / 8;
990c7037ccdSmrg      }
991c7037ccdSmrg   }
992c7037ccdSmrg   else {
9937117f1b4Smrg      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
9947117f1b4Smrg
9957117f1b4Smrg      if (bytesPerPixel <= 0)
9967117f1b4Smrg         return -1;  /* error */
9977117f1b4Smrg      if (packing->RowLength == 0) {
9987117f1b4Smrg         bytesPerRow = bytesPerPixel * width;
9997117f1b4Smrg      }
10007117f1b4Smrg      else {
10017117f1b4Smrg         bytesPerRow = bytesPerPixel * packing->RowLength;
10027117f1b4Smrg      }
1003c7037ccdSmrg   }
10047117f1b4Smrg
1005c7037ccdSmrg   remainder = bytesPerRow % packing->Alignment;
1006c7037ccdSmrg   if (remainder > 0)
1007c7037ccdSmrg      bytesPerRow += (packing->Alignment - remainder);
10087117f1b4Smrg
1009c7037ccdSmrg   if (packing->ImageHeight == 0)
1010c7037ccdSmrg      bytesPerImage = bytesPerRow * height;
1011c7037ccdSmrg   else
1012c7037ccdSmrg      bytesPerImage = bytesPerRow * packing->ImageHeight;
1013c7037ccdSmrg
1014c7037ccdSmrg   return bytesPerImage;
10157117f1b4Smrg}
10167117f1b4Smrg
10177117f1b4Smrg
10187117f1b4Smrg/*
10197117f1b4Smrg * Unpack a 32x32 pixel polygon stipple from user memory using the
10207117f1b4Smrg * current pixel unpack settings.
10217117f1b4Smrg */
10227117f1b4Smrgvoid
10237117f1b4Smrg_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
10247117f1b4Smrg                              const struct gl_pixelstore_attrib *unpacking )
10257117f1b4Smrg{
10267117f1b4Smrg   GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap(32, 32, pattern, unpacking);
10277117f1b4Smrg   if (ptrn) {
10287117f1b4Smrg      /* Convert pattern from GLubytes to GLuints and handle big/little
10297117f1b4Smrg       * endian differences
10307117f1b4Smrg       */
10317117f1b4Smrg      GLubyte *p = ptrn;
10327117f1b4Smrg      GLint i;
10337117f1b4Smrg      for (i = 0; i < 32; i++) {
10347117f1b4Smrg         dest[i] = (p[0] << 24)
10357117f1b4Smrg                 | (p[1] << 16)
10367117f1b4Smrg                 | (p[2] <<  8)
10377117f1b4Smrg                 | (p[3]      );
10387117f1b4Smrg         p += 4;
10397117f1b4Smrg      }
10407117f1b4Smrg      _mesa_free(ptrn);
10417117f1b4Smrg   }
10427117f1b4Smrg}
10437117f1b4Smrg
10447117f1b4Smrg
10457117f1b4Smrg/*
10467117f1b4Smrg * Pack polygon stipple into user memory given current pixel packing
10477117f1b4Smrg * settings.
10487117f1b4Smrg */
10497117f1b4Smrgvoid
10507117f1b4Smrg_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
10517117f1b4Smrg                            const struct gl_pixelstore_attrib *packing )
10527117f1b4Smrg{
10537117f1b4Smrg   /* Convert pattern from GLuints to GLubytes to handle big/little
10547117f1b4Smrg    * endian differences.
10557117f1b4Smrg    */
10567117f1b4Smrg   GLubyte ptrn[32*4];
10577117f1b4Smrg   GLint i;
10587117f1b4Smrg   for (i = 0; i < 32; i++) {
10597117f1b4Smrg      ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
10607117f1b4Smrg      ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
10617117f1b4Smrg      ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
10627117f1b4Smrg      ptrn[i * 4 + 3] = (GLubyte) ((pattern[i]      ) & 0xff);
10637117f1b4Smrg   }
10647117f1b4Smrg
10657117f1b4Smrg   _mesa_pack_bitmap(32, 32, ptrn, dest, packing);
10667117f1b4Smrg}
10677117f1b4Smrg
10687117f1b4Smrg
10697117f1b4Smrg/*
10707117f1b4Smrg * Unpack bitmap data.  Resulting data will be in most-significant-bit-first
10717117f1b4Smrg * order with row alignment = 1 byte.
10727117f1b4Smrg */
10737117f1b4SmrgGLvoid *
10747117f1b4Smrg_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
10757117f1b4Smrg                     const struct gl_pixelstore_attrib *packing )
10767117f1b4Smrg{
10777117f1b4Smrg   GLint bytes, row, width_in_bytes;
10787117f1b4Smrg   GLubyte *buffer, *dst;
10797117f1b4Smrg
10807117f1b4Smrg   if (!pixels)
10817117f1b4Smrg      return NULL;
10827117f1b4Smrg
10837117f1b4Smrg   /* Alloc dest storage */
10847117f1b4Smrg   bytes = ((width + 7) / 8 * height);
10857117f1b4Smrg   buffer = (GLubyte *) _mesa_malloc( bytes );
10867117f1b4Smrg   if (!buffer)
10877117f1b4Smrg      return NULL;
10887117f1b4Smrg
10897117f1b4Smrg   width_in_bytes = CEILING( width, 8 );
10907117f1b4Smrg   dst = buffer;
10917117f1b4Smrg   for (row = 0; row < height; row++) {
10927117f1b4Smrg      const GLubyte *src = (const GLubyte *)
10937117f1b4Smrg         _mesa_image_address2d(packing, pixels, width, height,
10947117f1b4Smrg                               GL_COLOR_INDEX, GL_BITMAP, row, 0);
10957117f1b4Smrg      if (!src) {
10967117f1b4Smrg         _mesa_free(buffer);
10977117f1b4Smrg         return NULL;
10987117f1b4Smrg      }
10997117f1b4Smrg
11007117f1b4Smrg      if ((packing->SkipPixels & 7) == 0) {
11017117f1b4Smrg         _mesa_memcpy( dst, src, width_in_bytes );
11027117f1b4Smrg         if (packing->LsbFirst) {
11037117f1b4Smrg            flip_bytes( dst, width_in_bytes );
11047117f1b4Smrg         }
11057117f1b4Smrg      }
11067117f1b4Smrg      else {
11077117f1b4Smrg         /* handling SkipPixels is a bit tricky (no pun intended!) */
11087117f1b4Smrg         GLint i;
11097117f1b4Smrg         if (packing->LsbFirst) {
11107117f1b4Smrg            GLubyte srcMask = 1 << (packing->SkipPixels & 0x7);
11117117f1b4Smrg            GLubyte dstMask = 128;
11127117f1b4Smrg            const GLubyte *s = src;
11137117f1b4Smrg            GLubyte *d = dst;
11147117f1b4Smrg            *d = 0;
11157117f1b4Smrg            for (i = 0; i < width; i++) {
11167117f1b4Smrg               if (*s & srcMask) {
11177117f1b4Smrg                  *d |= dstMask;
11187117f1b4Smrg               }
11197117f1b4Smrg               if (srcMask == 128) {
11207117f1b4Smrg                  srcMask = 1;
11217117f1b4Smrg                  s++;
11227117f1b4Smrg               }
11237117f1b4Smrg               else {
11247117f1b4Smrg                  srcMask = srcMask << 1;
11257117f1b4Smrg               }
11267117f1b4Smrg               if (dstMask == 1) {
11277117f1b4Smrg                  dstMask = 128;
11287117f1b4Smrg                  d++;
11297117f1b4Smrg                  *d = 0;
11307117f1b4Smrg               }
11317117f1b4Smrg               else {
11327117f1b4Smrg                  dstMask = dstMask >> 1;
11337117f1b4Smrg               }
11347117f1b4Smrg            }
11357117f1b4Smrg         }
11367117f1b4Smrg         else {
11377117f1b4Smrg            GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7);
11387117f1b4Smrg            GLubyte dstMask = 128;
11397117f1b4Smrg            const GLubyte *s = src;
11407117f1b4Smrg            GLubyte *d = dst;
11417117f1b4Smrg            *d = 0;
11427117f1b4Smrg            for (i = 0; i < width; i++) {
11437117f1b4Smrg               if (*s & srcMask) {
11447117f1b4Smrg                  *d |= dstMask;
11457117f1b4Smrg               }
11467117f1b4Smrg               if (srcMask == 1) {
11477117f1b4Smrg                  srcMask = 128;
11487117f1b4Smrg                  s++;
11497117f1b4Smrg               }
11507117f1b4Smrg               else {
11517117f1b4Smrg                  srcMask = srcMask >> 1;
11527117f1b4Smrg               }
11537117f1b4Smrg               if (dstMask == 1) {
11547117f1b4Smrg                  dstMask = 128;
11557117f1b4Smrg                  d++;
11567117f1b4Smrg                  *d = 0;
11577117f1b4Smrg               }
11587117f1b4Smrg               else {
11597117f1b4Smrg                  dstMask = dstMask >> 1;
11607117f1b4Smrg               }
11617117f1b4Smrg            }
11627117f1b4Smrg         }
11637117f1b4Smrg      }
11647117f1b4Smrg      dst += width_in_bytes;
11657117f1b4Smrg   }
11667117f1b4Smrg
11677117f1b4Smrg   return buffer;
11687117f1b4Smrg}
11697117f1b4Smrg
11707117f1b4Smrg
11717117f1b4Smrg/*
11727117f1b4Smrg * Pack bitmap data.
11737117f1b4Smrg */
11747117f1b4Smrgvoid
11757117f1b4Smrg_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
11767117f1b4Smrg                   GLubyte *dest, const struct gl_pixelstore_attrib *packing )
11777117f1b4Smrg{
11787117f1b4Smrg   GLint row, width_in_bytes;
11797117f1b4Smrg   const GLubyte *src;
11807117f1b4Smrg
11817117f1b4Smrg   if (!source)
11827117f1b4Smrg      return;
11837117f1b4Smrg
11847117f1b4Smrg   width_in_bytes = CEILING( width, 8 );
11857117f1b4Smrg   src = source;
11867117f1b4Smrg   for (row = 0; row < height; row++) {
11877117f1b4Smrg      GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
11887117f1b4Smrg                       width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
11897117f1b4Smrg      if (!dst)
11907117f1b4Smrg         return;
11917117f1b4Smrg
11927117f1b4Smrg      if ((packing->SkipPixels & 7) == 0) {
11937117f1b4Smrg         _mesa_memcpy( dst, src, width_in_bytes );
11947117f1b4Smrg         if (packing->LsbFirst) {
11957117f1b4Smrg            flip_bytes( dst, width_in_bytes );
11967117f1b4Smrg         }
11977117f1b4Smrg      }
11987117f1b4Smrg      else {
11997117f1b4Smrg         /* handling SkipPixels is a bit tricky (no pun intended!) */
12007117f1b4Smrg         GLint i;
12017117f1b4Smrg         if (packing->LsbFirst) {
12027117f1b4Smrg            GLubyte srcMask = 128;
12037117f1b4Smrg            GLubyte dstMask = 1 << (packing->SkipPixels & 0x7);
12047117f1b4Smrg            const GLubyte *s = src;
12057117f1b4Smrg            GLubyte *d = dst;
12067117f1b4Smrg            *d = 0;
12077117f1b4Smrg            for (i = 0; i < width; i++) {
12087117f1b4Smrg               if (*s & srcMask) {
12097117f1b4Smrg                  *d |= dstMask;
12107117f1b4Smrg               }
12117117f1b4Smrg               if (srcMask == 1) {
12127117f1b4Smrg                  srcMask = 128;
12137117f1b4Smrg                  s++;
12147117f1b4Smrg               }
12157117f1b4Smrg               else {
12167117f1b4Smrg                  srcMask = srcMask >> 1;
12177117f1b4Smrg               }
12187117f1b4Smrg               if (dstMask == 128) {
12197117f1b4Smrg                  dstMask = 1;
12207117f1b4Smrg                  d++;
12217117f1b4Smrg                  *d = 0;
12227117f1b4Smrg               }
12237117f1b4Smrg               else {
12247117f1b4Smrg                  dstMask = dstMask << 1;
12257117f1b4Smrg               }
12267117f1b4Smrg            }
12277117f1b4Smrg         }
12287117f1b4Smrg         else {
12297117f1b4Smrg            GLubyte srcMask = 128;
12307117f1b4Smrg            GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7);
12317117f1b4Smrg            const GLubyte *s = src;
12327117f1b4Smrg            GLubyte *d = dst;
12337117f1b4Smrg            *d = 0;
12347117f1b4Smrg            for (i = 0; i < width; i++) {
12357117f1b4Smrg               if (*s & srcMask) {
12367117f1b4Smrg                  *d |= dstMask;
12377117f1b4Smrg               }
12387117f1b4Smrg               if (srcMask == 1) {
12397117f1b4Smrg                  srcMask = 128;
12407117f1b4Smrg                  s++;
12417117f1b4Smrg               }
12427117f1b4Smrg               else {
12437117f1b4Smrg                  srcMask = srcMask >> 1;
12447117f1b4Smrg               }
12457117f1b4Smrg               if (dstMask == 1) {
12467117f1b4Smrg                  dstMask = 128;
12477117f1b4Smrg                  d++;
12487117f1b4Smrg                  *d = 0;
12497117f1b4Smrg               }
12507117f1b4Smrg               else {
12517117f1b4Smrg                  dstMask = dstMask >> 1;
12527117f1b4Smrg               }
12537117f1b4Smrg            }
12547117f1b4Smrg         }
12557117f1b4Smrg      }
12567117f1b4Smrg      src += width_in_bytes;
12577117f1b4Smrg   }
12587117f1b4Smrg}
12597117f1b4Smrg
12607117f1b4Smrg
12614a49301eSmrg/**
12624a49301eSmrg * "Expand" a bitmap from 1-bit per pixel to 8-bits per pixel.
12634a49301eSmrg * This is typically used to convert a bitmap into a GLubyte/pixel texture.
12644a49301eSmrg * "On" bits will set texels to \p onValue.
12654a49301eSmrg * "Off" bits will not modify texels.
12664a49301eSmrg * \param width  src bitmap width in pixels
12674a49301eSmrg * \param height  src bitmap height in pixels
12684a49301eSmrg * \param unpack  bitmap unpacking state
12694a49301eSmrg * \param bitmap  the src bitmap data
12704a49301eSmrg * \param destBuffer  start of dest buffer
12714a49301eSmrg * \param destStride  row stride in dest buffer
12724a49301eSmrg * \param onValue  if bit is 1, set destBuffer pixel to this value
12734a49301eSmrg */
12744a49301eSmrgvoid
12754a49301eSmrg_mesa_expand_bitmap(GLsizei width, GLsizei height,
12764a49301eSmrg                    const struct gl_pixelstore_attrib *unpack,
12774a49301eSmrg                    const GLubyte *bitmap,
12784a49301eSmrg                    GLubyte *destBuffer, GLint destStride,
12794a49301eSmrg                    GLubyte onValue)
12804a49301eSmrg{
12814a49301eSmrg   const GLubyte *srcRow = (const GLubyte *)
12824a49301eSmrg      _mesa_image_address2d(unpack, bitmap, width, height,
12834a49301eSmrg                            GL_COLOR_INDEX, GL_BITMAP, 0, 0);
12844a49301eSmrg   const GLint srcStride = _mesa_image_row_stride(unpack, width,
12854a49301eSmrg                                                  GL_COLOR_INDEX, GL_BITMAP);
12864a49301eSmrg   GLint row, col;
12874a49301eSmrg
12884a49301eSmrg#define SET_PIXEL(COL, ROW) \
12894a49301eSmrg   destBuffer[(ROW) * destStride + (COL)] = onValue;
12904a49301eSmrg
12914a49301eSmrg   for (row = 0; row < height; row++) {
12924a49301eSmrg      const GLubyte *src = srcRow;
12934a49301eSmrg
12944a49301eSmrg      if (unpack->LsbFirst) {
12954a49301eSmrg         /* Lsb first */
12964a49301eSmrg         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
12974a49301eSmrg         for (col = 0; col < width; col++) {
12984a49301eSmrg
12994a49301eSmrg            if (*src & mask) {
13004a49301eSmrg               SET_PIXEL(col, row);
13014a49301eSmrg            }
13024a49301eSmrg
13034a49301eSmrg            if (mask == 128U) {
13044a49301eSmrg               src++;
13054a49301eSmrg               mask = 1U;
13064a49301eSmrg            }
13074a49301eSmrg            else {
13084a49301eSmrg               mask = mask << 1;
13094a49301eSmrg            }
13104a49301eSmrg         }
13114a49301eSmrg
13124a49301eSmrg         /* get ready for next row */
13134a49301eSmrg         if (mask != 1)
13144a49301eSmrg            src++;
13154a49301eSmrg      }
13164a49301eSmrg      else {
13174a49301eSmrg         /* Msb first */
13184a49301eSmrg         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
13194a49301eSmrg         for (col = 0; col < width; col++) {
13204a49301eSmrg
13214a49301eSmrg            if (*src & mask) {
13224a49301eSmrg               SET_PIXEL(col, row);
13234a49301eSmrg            }
13244a49301eSmrg
13254a49301eSmrg            if (mask == 1U) {
13264a49301eSmrg               src++;
13274a49301eSmrg               mask = 128U;
13284a49301eSmrg            }
13294a49301eSmrg            else {
13304a49301eSmrg               mask = mask >> 1;
13314a49301eSmrg            }
13324a49301eSmrg         }
13334a49301eSmrg
13344a49301eSmrg         /* get ready for next row */
13354a49301eSmrg         if (mask != 128)
13364a49301eSmrg            src++;
13374a49301eSmrg      }
13384a49301eSmrg
13394a49301eSmrg      srcRow += srcStride;
13404a49301eSmrg   } /* row */
13414a49301eSmrg
13424a49301eSmrg#undef SET_PIXEL
13434a49301eSmrg}
13444a49301eSmrg
13454a49301eSmrg
1346c1f859d4Smrg/**********************************************************************/
1347c1f859d4Smrg/*****                  Pixel processing functions               ******/
1348c1f859d4Smrg/**********************************************************************/
1349c1f859d4Smrg
1350c1f859d4Smrg/*
1351c1f859d4Smrg * Apply scale and bias factors to an array of RGBA pixels.
1352c1f859d4Smrg */
1353c1f859d4Smrgvoid
1354c1f859d4Smrg_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
1355c1f859d4Smrg                          GLfloat rScale, GLfloat gScale,
1356c1f859d4Smrg                          GLfloat bScale, GLfloat aScale,
1357c1f859d4Smrg                          GLfloat rBias, GLfloat gBias,
1358c1f859d4Smrg                          GLfloat bBias, GLfloat aBias)
1359c1f859d4Smrg{
1360c1f859d4Smrg   if (rScale != 1.0 || rBias != 0.0) {
1361c1f859d4Smrg      GLuint i;
1362c1f859d4Smrg      for (i = 0; i < n; i++) {
1363c1f859d4Smrg         rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
1364c1f859d4Smrg      }
1365c1f859d4Smrg   }
1366c1f859d4Smrg   if (gScale != 1.0 || gBias != 0.0) {
1367c1f859d4Smrg      GLuint i;
1368c1f859d4Smrg      for (i = 0; i < n; i++) {
1369c1f859d4Smrg         rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
1370c1f859d4Smrg      }
1371c1f859d4Smrg   }
1372c1f859d4Smrg   if (bScale != 1.0 || bBias != 0.0) {
1373c1f859d4Smrg      GLuint i;
1374c1f859d4Smrg      for (i = 0; i < n; i++) {
1375c1f859d4Smrg         rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
1376c1f859d4Smrg      }
1377c1f859d4Smrg   }
1378c1f859d4Smrg   if (aScale != 1.0 || aBias != 0.0) {
1379c1f859d4Smrg      GLuint i;
1380c1f859d4Smrg      for (i = 0; i < n; i++) {
1381c1f859d4Smrg         rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
1382c1f859d4Smrg      }
1383c1f859d4Smrg   }
1384c1f859d4Smrg}
1385c1f859d4Smrg
1386c1f859d4Smrg
1387c1f859d4Smrg/*
1388c1f859d4Smrg * Apply pixel mapping to an array of floating point RGBA pixels.
1389c1f859d4Smrg */
1390c1f859d4Smrgvoid
1391c1f859d4Smrg_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
1392c1f859d4Smrg{
1393c1f859d4Smrg   const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1);
1394c1f859d4Smrg   const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1);
1395c1f859d4Smrg   const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1);
1396c1f859d4Smrg   const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1);
1397c1f859d4Smrg   const GLfloat *rMap = ctx->PixelMaps.RtoR.Map;
1398c1f859d4Smrg   const GLfloat *gMap = ctx->PixelMaps.GtoG.Map;
1399c1f859d4Smrg   const GLfloat *bMap = ctx->PixelMaps.BtoB.Map;
1400c1f859d4Smrg   const GLfloat *aMap = ctx->PixelMaps.AtoA.Map;
1401c1f859d4Smrg   GLuint i;
1402c1f859d4Smrg   for (i=0;i<n;i++) {
1403c1f859d4Smrg      GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
1404c1f859d4Smrg      GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
1405c1f859d4Smrg      GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
1406c1f859d4Smrg      GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
1407c1f859d4Smrg      rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
1408c1f859d4Smrg      rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
1409c1f859d4Smrg      rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
1410c1f859d4Smrg      rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
1411c1f859d4Smrg   }
1412c1f859d4Smrg}
1413c1f859d4Smrg
1414c1f859d4Smrg
1415c1f859d4Smrg/*
1416c1f859d4Smrg * Apply the color matrix and post color matrix scaling and biasing.
1417c1f859d4Smrg */
1418c1f859d4Smrgvoid
1419c1f859d4Smrg_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
1420c1f859d4Smrg{
1421c1f859d4Smrg   const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
1422c1f859d4Smrg   const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
1423c1f859d4Smrg   const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
1424c1f859d4Smrg   const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
1425c1f859d4Smrg   const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
1426c1f859d4Smrg   const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
1427c1f859d4Smrg   const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
1428c1f859d4Smrg   const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
1429c1f859d4Smrg   const GLfloat *m = ctx->ColorMatrixStack.Top->m;
1430c1f859d4Smrg   GLuint i;
1431c1f859d4Smrg   for (i = 0; i < n; i++) {
1432c1f859d4Smrg      const GLfloat r = rgba[i][RCOMP];
1433c1f859d4Smrg      const GLfloat g = rgba[i][GCOMP];
1434c1f859d4Smrg      const GLfloat b = rgba[i][BCOMP];
1435c1f859d4Smrg      const GLfloat a = rgba[i][ACOMP];
1436c1f859d4Smrg      rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
1437c1f859d4Smrg      rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
1438c1f859d4Smrg      rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
1439c1f859d4Smrg      rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
1440c1f859d4Smrg   }
1441c1f859d4Smrg}
1442c1f859d4Smrg
1443c1f859d4Smrg
1444c1f859d4Smrg/**
1445c1f859d4Smrg * Apply a color table lookup to an array of floating point RGBA colors.
1446c1f859d4Smrg */
1447c1f859d4Smrgvoid
1448c1f859d4Smrg_mesa_lookup_rgba_float(const struct gl_color_table *table,
1449c1f859d4Smrg                        GLuint n, GLfloat rgba[][4])
1450c1f859d4Smrg{
1451c1f859d4Smrg   const GLint max = table->Size - 1;
1452c1f859d4Smrg   const GLfloat scale = (GLfloat) max;
1453c1f859d4Smrg   const GLfloat *lut = table->TableF;
1454c1f859d4Smrg   GLuint i;
1455c1f859d4Smrg
1456c1f859d4Smrg   if (!table->TableF || table->Size == 0)
1457c1f859d4Smrg      return;
1458c1f859d4Smrg
1459c1f859d4Smrg   switch (table->_BaseFormat) {
1460c1f859d4Smrg      case GL_INTENSITY:
1461c1f859d4Smrg         /* replace RGBA with I */
1462c1f859d4Smrg         for (i = 0; i < n; i++) {
1463c1f859d4Smrg            GLint j = IROUND(rgba[i][RCOMP] * scale);
1464c1f859d4Smrg            GLfloat c = lut[CLAMP(j, 0, max)];
1465c1f859d4Smrg            rgba[i][RCOMP] =
1466c1f859d4Smrg            rgba[i][GCOMP] =
1467c1f859d4Smrg            rgba[i][BCOMP] =
1468c1f859d4Smrg            rgba[i][ACOMP] = c;
1469c1f859d4Smrg         }
1470c1f859d4Smrg         break;
1471c1f859d4Smrg      case GL_LUMINANCE:
1472c1f859d4Smrg         /* replace RGB with L */
1473c1f859d4Smrg         for (i = 0; i < n; i++) {
1474c1f859d4Smrg            GLint j = IROUND(rgba[i][RCOMP] * scale);
1475c1f859d4Smrg            GLfloat c = lut[CLAMP(j, 0, max)];
1476c1f859d4Smrg            rgba[i][RCOMP] =
1477c1f859d4Smrg            rgba[i][GCOMP] =
1478c1f859d4Smrg            rgba[i][BCOMP] = c;
1479c1f859d4Smrg         }
1480c1f859d4Smrg         break;
1481c1f859d4Smrg      case GL_ALPHA:
1482c1f859d4Smrg         /* replace A with A */
1483c1f859d4Smrg         for (i = 0; i < n; i++) {
1484c1f859d4Smrg            GLint j = IROUND(rgba[i][ACOMP] * scale);
1485c1f859d4Smrg            rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
1486c1f859d4Smrg         }
1487c1f859d4Smrg         break;
1488c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
1489c1f859d4Smrg         /* replace RGBA with LLLA */
1490c1f859d4Smrg         for (i = 0; i < n; i++) {
1491c1f859d4Smrg            GLint jL = IROUND(rgba[i][RCOMP] * scale);
1492c1f859d4Smrg            GLint jA = IROUND(rgba[i][ACOMP] * scale);
1493c1f859d4Smrg            GLfloat luminance, alpha;
1494c1f859d4Smrg            jL = CLAMP(jL, 0, max);
1495c1f859d4Smrg            jA = CLAMP(jA, 0, max);
1496c1f859d4Smrg            luminance = lut[jL * 2 + 0];
1497c1f859d4Smrg            alpha     = lut[jA * 2 + 1];
1498c1f859d4Smrg            rgba[i][RCOMP] =
1499c1f859d4Smrg            rgba[i][GCOMP] =
1500c1f859d4Smrg            rgba[i][BCOMP] = luminance;
1501c1f859d4Smrg            rgba[i][ACOMP] = alpha;;
1502c1f859d4Smrg         }
1503c1f859d4Smrg         break;
1504c1f859d4Smrg      case GL_RGB:
1505c1f859d4Smrg         /* replace RGB with RGB */
1506c1f859d4Smrg         for (i = 0; i < n; i++) {
1507c1f859d4Smrg            GLint jR = IROUND(rgba[i][RCOMP] * scale);
1508c1f859d4Smrg            GLint jG = IROUND(rgba[i][GCOMP] * scale);
1509c1f859d4Smrg            GLint jB = IROUND(rgba[i][BCOMP] * scale);
1510c1f859d4Smrg            jR = CLAMP(jR, 0, max);
1511c1f859d4Smrg            jG = CLAMP(jG, 0, max);
1512c1f859d4Smrg            jB = CLAMP(jB, 0, max);
1513c1f859d4Smrg            rgba[i][RCOMP] = lut[jR * 3 + 0];
1514c1f859d4Smrg            rgba[i][GCOMP] = lut[jG * 3 + 1];
1515c1f859d4Smrg            rgba[i][BCOMP] = lut[jB * 3 + 2];
1516c1f859d4Smrg         }
1517c1f859d4Smrg         break;
1518c1f859d4Smrg      case GL_RGBA:
1519c1f859d4Smrg         /* replace RGBA with RGBA */
1520c1f859d4Smrg         for (i = 0; i < n; i++) {
1521c1f859d4Smrg            GLint jR = IROUND(rgba[i][RCOMP] * scale);
1522c1f859d4Smrg            GLint jG = IROUND(rgba[i][GCOMP] * scale);
1523c1f859d4Smrg            GLint jB = IROUND(rgba[i][BCOMP] * scale);
1524c1f859d4Smrg            GLint jA = IROUND(rgba[i][ACOMP] * scale);
1525c1f859d4Smrg            jR = CLAMP(jR, 0, max);
1526c1f859d4Smrg            jG = CLAMP(jG, 0, max);
1527c1f859d4Smrg            jB = CLAMP(jB, 0, max);
1528c1f859d4Smrg            jA = CLAMP(jA, 0, max);
1529c1f859d4Smrg            rgba[i][RCOMP] = lut[jR * 4 + 0];
1530c1f859d4Smrg            rgba[i][GCOMP] = lut[jG * 4 + 1];
1531c1f859d4Smrg            rgba[i][BCOMP] = lut[jB * 4 + 2];
1532c1f859d4Smrg            rgba[i][ACOMP] = lut[jA * 4 + 3];
1533c1f859d4Smrg         }
1534c1f859d4Smrg         break;
1535c1f859d4Smrg      default:
1536c1f859d4Smrg         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
1537c1f859d4Smrg         return;
1538c1f859d4Smrg   }
1539c1f859d4Smrg}
1540c1f859d4Smrg
1541c1f859d4Smrg
1542c1f859d4Smrg
1543c1f859d4Smrg/**
1544c1f859d4Smrg * Apply a color table lookup to an array of ubyte/RGBA colors.
1545c1f859d4Smrg */
1546c1f859d4Smrgvoid
1547c1f859d4Smrg_mesa_lookup_rgba_ubyte(const struct gl_color_table *table,
1548c1f859d4Smrg                        GLuint n, GLubyte rgba[][4])
1549c1f859d4Smrg{
1550c1f859d4Smrg   const GLubyte *lut = table->TableUB;
1551c1f859d4Smrg   const GLfloat scale = (GLfloat) (table->Size - 1) / (GLfloat)255.0;
1552c1f859d4Smrg   GLuint i;
1553c1f859d4Smrg
1554c1f859d4Smrg   if (!table->TableUB || table->Size == 0)
1555c1f859d4Smrg      return;
1556c1f859d4Smrg
1557c1f859d4Smrg   switch (table->_BaseFormat) {
1558c1f859d4Smrg   case GL_INTENSITY:
1559c1f859d4Smrg      /* replace RGBA with I */
1560c1f859d4Smrg      if (table->Size == 256) {
1561c1f859d4Smrg         for (i = 0; i < n; i++) {
1562c1f859d4Smrg            const GLubyte c = lut[rgba[i][RCOMP]];
1563c1f859d4Smrg            rgba[i][RCOMP] =
1564c1f859d4Smrg            rgba[i][GCOMP] =
1565c1f859d4Smrg            rgba[i][BCOMP] =
1566c1f859d4Smrg            rgba[i][ACOMP] = c;
1567c1f859d4Smrg         }
1568c1f859d4Smrg      }
1569c1f859d4Smrg      else {
1570c1f859d4Smrg         for (i = 0; i < n; i++) {
1571c1f859d4Smrg            GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1572c1f859d4Smrg            rgba[i][RCOMP] =
1573c1f859d4Smrg            rgba[i][GCOMP] =
1574c1f859d4Smrg            rgba[i][BCOMP] =
1575c1f859d4Smrg            rgba[i][ACOMP] = lut[j];
1576c1f859d4Smrg         }
1577c1f859d4Smrg      }
1578c1f859d4Smrg      break;
1579c1f859d4Smrg   case GL_LUMINANCE:
1580c1f859d4Smrg      /* replace RGB with L */
1581c1f859d4Smrg      if (table->Size == 256) {
1582c1f859d4Smrg         for (i = 0; i < n; i++) {
1583c1f859d4Smrg            const GLubyte c = lut[rgba[i][RCOMP]];
1584c1f859d4Smrg            rgba[i][RCOMP] =
1585c1f859d4Smrg            rgba[i][GCOMP] =
1586c1f859d4Smrg            rgba[i][BCOMP] = c;
1587c1f859d4Smrg         }
1588c1f859d4Smrg      }
1589c1f859d4Smrg      else {
1590c1f859d4Smrg         for (i = 0; i < n; i++) {
1591c1f859d4Smrg            GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1592c1f859d4Smrg            rgba[i][RCOMP] =
1593c1f859d4Smrg            rgba[i][GCOMP] =
1594c1f859d4Smrg            rgba[i][BCOMP] = lut[j];
1595c1f859d4Smrg         }
1596c1f859d4Smrg      }
1597c1f859d4Smrg      break;
1598c1f859d4Smrg   case GL_ALPHA:
1599c1f859d4Smrg      /* replace A with A */
1600c1f859d4Smrg      if (table->Size == 256) {
1601c1f859d4Smrg         for (i = 0; i < n; i++) {
1602c1f859d4Smrg            rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
1603c1f859d4Smrg         }
1604c1f859d4Smrg      }
1605c1f859d4Smrg      else {
1606c1f859d4Smrg         for (i = 0; i < n; i++) {
1607c1f859d4Smrg            GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1608c1f859d4Smrg            rgba[i][ACOMP] = lut[j];
1609c1f859d4Smrg         }
1610c1f859d4Smrg      }
1611c1f859d4Smrg      break;
1612c1f859d4Smrg   case GL_LUMINANCE_ALPHA:
1613c1f859d4Smrg      /* replace RGBA with LLLA */
1614c1f859d4Smrg      if (table->Size == 256) {
1615c1f859d4Smrg         for (i = 0; i < n; i++) {
1616c1f859d4Smrg            GLubyte l = lut[rgba[i][RCOMP] * 2 + 0];
1617c1f859d4Smrg            GLubyte a = lut[rgba[i][ACOMP] * 2 + 1];;
1618c1f859d4Smrg            rgba[i][RCOMP] =
1619c1f859d4Smrg            rgba[i][GCOMP] =
1620c1f859d4Smrg            rgba[i][BCOMP] = l;
1621c1f859d4Smrg            rgba[i][ACOMP] = a;
1622c1f859d4Smrg         }
1623c1f859d4Smrg      }
1624c1f859d4Smrg      else {
1625c1f859d4Smrg         for (i = 0; i < n; i++) {
1626c1f859d4Smrg            GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1627c1f859d4Smrg            GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1628c1f859d4Smrg            GLubyte luminance = lut[jL * 2 + 0];
1629c1f859d4Smrg            GLubyte alpha     = lut[jA * 2 + 1];
1630c1f859d4Smrg            rgba[i][RCOMP] =
1631c1f859d4Smrg            rgba[i][GCOMP] =
1632c1f859d4Smrg            rgba[i][BCOMP] = luminance;
1633c1f859d4Smrg            rgba[i][ACOMP] = alpha;
1634c1f859d4Smrg         }
1635c1f859d4Smrg      }
1636c1f859d4Smrg      break;
1637c1f859d4Smrg   case GL_RGB:
1638c1f859d4Smrg      if (table->Size == 256) {
1639c1f859d4Smrg         for (i = 0; i < n; i++) {
1640c1f859d4Smrg            rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
1641c1f859d4Smrg            rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
1642c1f859d4Smrg            rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
1643c1f859d4Smrg         }
1644c1f859d4Smrg      }
1645c1f859d4Smrg      else {
1646c1f859d4Smrg         for (i = 0; i < n; i++) {
1647c1f859d4Smrg            GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1648c1f859d4Smrg            GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1649c1f859d4Smrg            GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1650c1f859d4Smrg            rgba[i][RCOMP] = lut[jR * 3 + 0];
1651c1f859d4Smrg            rgba[i][GCOMP] = lut[jG * 3 + 1];
1652c1f859d4Smrg            rgba[i][BCOMP] = lut[jB * 3 + 2];
1653c1f859d4Smrg         }
1654c1f859d4Smrg      }
1655c1f859d4Smrg      break;
1656c1f859d4Smrg   case GL_RGBA:
1657c1f859d4Smrg      if (table->Size == 256) {
1658c1f859d4Smrg         for (i = 0; i < n; i++) {
1659c1f859d4Smrg            rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
1660c1f859d4Smrg            rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
1661c1f859d4Smrg            rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
1662c1f859d4Smrg            rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
1663c1f859d4Smrg         }
1664c1f859d4Smrg      }
1665c1f859d4Smrg      else {
1666c1f859d4Smrg         for (i = 0; i < n; i++) {
1667c1f859d4Smrg            GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1668c1f859d4Smrg            GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1669c1f859d4Smrg            GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1670c1f859d4Smrg            GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1671c1f859d4Smrg            CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1672c1f859d4Smrg            CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1673c1f859d4Smrg            CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1674c1f859d4Smrg            CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1675c1f859d4Smrg         }
1676c1f859d4Smrg      }
1677c1f859d4Smrg      break;
1678c1f859d4Smrg   default:
1679c1f859d4Smrg      _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
1680c1f859d4Smrg      return;
1681c1f859d4Smrg   }
1682c1f859d4Smrg}
1683c1f859d4Smrg
1684c1f859d4Smrg
1685c1f859d4Smrg
1686c1f859d4Smrg/*
1687c1f859d4Smrg * Map color indexes to float rgba values.
1688c1f859d4Smrg */
1689c1f859d4Smrgvoid
1690c1f859d4Smrg_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1691c1f859d4Smrg                      const GLuint index[], GLfloat rgba[][4] )
1692c1f859d4Smrg{
1693c1f859d4Smrg   GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
1694c1f859d4Smrg   GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
1695c1f859d4Smrg   GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
1696c1f859d4Smrg   GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
1697c1f859d4Smrg   const GLfloat *rMap = ctx->PixelMaps.ItoR.Map;
1698c1f859d4Smrg   const GLfloat *gMap = ctx->PixelMaps.ItoG.Map;
1699c1f859d4Smrg   const GLfloat *bMap = ctx->PixelMaps.ItoB.Map;
1700c1f859d4Smrg   const GLfloat *aMap = ctx->PixelMaps.ItoA.Map;
1701c1f859d4Smrg   GLuint i;
1702c1f859d4Smrg   for (i=0;i<n;i++) {
1703c1f859d4Smrg      rgba[i][RCOMP] = rMap[index[i] & rmask];
1704c1f859d4Smrg      rgba[i][GCOMP] = gMap[index[i] & gmask];
1705c1f859d4Smrg      rgba[i][BCOMP] = bMap[index[i] & bmask];
1706c1f859d4Smrg      rgba[i][ACOMP] = aMap[index[i] & amask];
1707c1f859d4Smrg   }
1708c1f859d4Smrg}
1709c1f859d4Smrg
1710c1f859d4Smrg
1711c1f859d4Smrg/**
1712c1f859d4Smrg * Map ubyte color indexes to ubyte/RGBA values.
1713c1f859d4Smrg */
1714c1f859d4Smrgvoid
1715c1f859d4Smrg_mesa_map_ci8_to_rgba8(const GLcontext *ctx, GLuint n, const GLubyte index[],
1716c1f859d4Smrg                       GLubyte rgba[][4])
1717c1f859d4Smrg{
1718c1f859d4Smrg   GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
1719c1f859d4Smrg   GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
1720c1f859d4Smrg   GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
1721c1f859d4Smrg   GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
1722c1f859d4Smrg   const GLubyte *rMap = ctx->PixelMaps.ItoR.Map8;
1723c1f859d4Smrg   const GLubyte *gMap = ctx->PixelMaps.ItoG.Map8;
1724c1f859d4Smrg   const GLubyte *bMap = ctx->PixelMaps.ItoB.Map8;
1725c1f859d4Smrg   const GLubyte *aMap = ctx->PixelMaps.ItoA.Map8;
1726c1f859d4Smrg   GLuint i;
1727c1f859d4Smrg   for (i=0;i<n;i++) {
1728c1f859d4Smrg      rgba[i][RCOMP] = rMap[index[i] & rmask];
1729c1f859d4Smrg      rgba[i][GCOMP] = gMap[index[i] & gmask];
1730c1f859d4Smrg      rgba[i][BCOMP] = bMap[index[i] & bmask];
1731c1f859d4Smrg      rgba[i][ACOMP] = aMap[index[i] & amask];
1732c1f859d4Smrg   }
1733c1f859d4Smrg}
1734c1f859d4Smrg
1735c1f859d4Smrg
1736c1f859d4Smrgvoid
1737c1f859d4Smrg_mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n,
1738c1f859d4Smrg                           GLfloat depthValues[])
1739c1f859d4Smrg{
1740c1f859d4Smrg   const GLfloat scale = ctx->Pixel.DepthScale;
1741c1f859d4Smrg   const GLfloat bias = ctx->Pixel.DepthBias;
1742c1f859d4Smrg   GLuint i;
1743c1f859d4Smrg   for (i = 0; i < n; i++) {
1744c1f859d4Smrg      GLfloat d = depthValues[i] * scale + bias;
1745c1f859d4Smrg      depthValues[i] = CLAMP(d, 0.0F, 1.0F);
1746c1f859d4Smrg   }
1747c1f859d4Smrg}
1748c1f859d4Smrg
1749c1f859d4Smrg
1750c1f859d4Smrgvoid
1751c1f859d4Smrg_mesa_scale_and_bias_depth_uint(const GLcontext *ctx, GLuint n,
1752c1f859d4Smrg                                GLuint depthValues[])
1753c1f859d4Smrg{
1754c1f859d4Smrg   const GLdouble max = (double) 0xffffffff;
1755c1f859d4Smrg   const GLdouble scale = ctx->Pixel.DepthScale;
1756c1f859d4Smrg   const GLdouble bias = ctx->Pixel.DepthBias * max;
1757c1f859d4Smrg   GLuint i;
1758c1f859d4Smrg   for (i = 0; i < n; i++) {
1759c1f859d4Smrg      GLdouble d = (GLdouble) depthValues[i] * scale + bias;
1760c1f859d4Smrg      d = CLAMP(d, 0.0, max);
1761c1f859d4Smrg      depthValues[i] = (GLuint) d;
1762c1f859d4Smrg   }
1763c1f859d4Smrg}
1764c1f859d4Smrg
1765c1f859d4Smrg
1766c1f859d4Smrg
1767c1f859d4Smrg/*
1768c1f859d4Smrg * Update the min/max values from an array of fragment colors.
1769c1f859d4Smrg */
1770c1f859d4Smrgstatic void
1771c1f859d4Smrgupdate_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4])
1772c1f859d4Smrg{
1773c1f859d4Smrg   GLuint i;
1774c1f859d4Smrg   for (i = 0; i < n; i++) {
1775c1f859d4Smrg      /* update mins */
1776c1f859d4Smrg      if (rgba[i][RCOMP] < ctx->MinMax.Min[RCOMP])
1777c1f859d4Smrg         ctx->MinMax.Min[RCOMP] = rgba[i][RCOMP];
1778c1f859d4Smrg      if (rgba[i][GCOMP] < ctx->MinMax.Min[GCOMP])
1779c1f859d4Smrg         ctx->MinMax.Min[GCOMP] = rgba[i][GCOMP];
1780c1f859d4Smrg      if (rgba[i][BCOMP] < ctx->MinMax.Min[BCOMP])
1781c1f859d4Smrg         ctx->MinMax.Min[BCOMP] = rgba[i][BCOMP];
1782c1f859d4Smrg      if (rgba[i][ACOMP] < ctx->MinMax.Min[ACOMP])
1783c1f859d4Smrg         ctx->MinMax.Min[ACOMP] = rgba[i][ACOMP];
1784c1f859d4Smrg
1785c1f859d4Smrg      /* update maxs */
1786c1f859d4Smrg      if (rgba[i][RCOMP] > ctx->MinMax.Max[RCOMP])
1787c1f859d4Smrg         ctx->MinMax.Max[RCOMP] = rgba[i][RCOMP];
1788c1f859d4Smrg      if (rgba[i][GCOMP] > ctx->MinMax.Max[GCOMP])
1789c1f859d4Smrg         ctx->MinMax.Max[GCOMP] = rgba[i][GCOMP];
1790c1f859d4Smrg      if (rgba[i][BCOMP] > ctx->MinMax.Max[BCOMP])
1791c1f859d4Smrg         ctx->MinMax.Max[BCOMP] = rgba[i][BCOMP];
1792c1f859d4Smrg      if (rgba[i][ACOMP] > ctx->MinMax.Max[ACOMP])
1793c1f859d4Smrg         ctx->MinMax.Max[ACOMP] = rgba[i][ACOMP];
1794c1f859d4Smrg   }
1795c1f859d4Smrg}
1796c1f859d4Smrg
1797c1f859d4Smrg
1798c1f859d4Smrg/*
1799c1f859d4Smrg * Update the histogram values from an array of fragment colors.
1800c1f859d4Smrg */
1801c1f859d4Smrgstatic void
1802c1f859d4Smrgupdate_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4])
1803c1f859d4Smrg{
1804c1f859d4Smrg   const GLint max = ctx->Histogram.Width - 1;
1805c1f859d4Smrg   GLfloat w = (GLfloat) max;
1806c1f859d4Smrg   GLuint i;
1807c1f859d4Smrg
1808c1f859d4Smrg   if (ctx->Histogram.Width == 0)
1809c1f859d4Smrg      return;
1810c1f859d4Smrg
1811c1f859d4Smrg   for (i = 0; i < n; i++) {
1812c1f859d4Smrg      GLint ri = IROUND(rgba[i][RCOMP] * w);
1813c1f859d4Smrg      GLint gi = IROUND(rgba[i][GCOMP] * w);
1814c1f859d4Smrg      GLint bi = IROUND(rgba[i][BCOMP] * w);
1815c1f859d4Smrg      GLint ai = IROUND(rgba[i][ACOMP] * w);
1816c1f859d4Smrg      ri = CLAMP(ri, 0, max);
1817c1f859d4Smrg      gi = CLAMP(gi, 0, max);
1818c1f859d4Smrg      bi = CLAMP(bi, 0, max);
1819c1f859d4Smrg      ai = CLAMP(ai, 0, max);
1820c1f859d4Smrg      ctx->Histogram.Count[ri][RCOMP]++;
1821c1f859d4Smrg      ctx->Histogram.Count[gi][GCOMP]++;
1822c1f859d4Smrg      ctx->Histogram.Count[bi][BCOMP]++;
1823c1f859d4Smrg      ctx->Histogram.Count[ai][ACOMP]++;
1824c1f859d4Smrg   }
1825c1f859d4Smrg}
1826c1f859d4Smrg
1827c1f859d4Smrg
18287117f1b4Smrg/**
18297117f1b4Smrg * Apply various pixel transfer operations to an array of RGBA pixels
18307117f1b4Smrg * as indicated by the transferOps bitmask
18317117f1b4Smrg */
18327117f1b4Smrgvoid
18337117f1b4Smrg_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLbitfield transferOps,
18347117f1b4Smrg                              GLuint n, GLfloat rgba[][4])
18357117f1b4Smrg{
18367117f1b4Smrg   /* scale & bias */
18377117f1b4Smrg   if (transferOps & IMAGE_SCALE_BIAS_BIT) {
18387117f1b4Smrg      _mesa_scale_and_bias_rgba(n, rgba,
18397117f1b4Smrg                                ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
18407117f1b4Smrg                                ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
18417117f1b4Smrg                                ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
18427117f1b4Smrg                                ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
18437117f1b4Smrg   }
18447117f1b4Smrg   /* color map lookup */
18457117f1b4Smrg   if (transferOps & IMAGE_MAP_COLOR_BIT) {
18467117f1b4Smrg      _mesa_map_rgba( ctx, n, rgba );
18477117f1b4Smrg   }
18487117f1b4Smrg   /* GL_COLOR_TABLE lookup */
18497117f1b4Smrg   if (transferOps & IMAGE_COLOR_TABLE_BIT) {
18507117f1b4Smrg      _mesa_lookup_rgba_float(&ctx->ColorTable[COLORTABLE_PRECONVOLUTION], n, rgba);
18517117f1b4Smrg   }
18527117f1b4Smrg   /* convolution */
18537117f1b4Smrg   if (transferOps & IMAGE_CONVOLUTION_BIT) {
18547117f1b4Smrg      /* this has to be done in the calling code */
18557117f1b4Smrg      _mesa_problem(ctx, "IMAGE_CONVOLUTION_BIT set in _mesa_apply_transfer_ops");
18567117f1b4Smrg   }
18577117f1b4Smrg   /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
18587117f1b4Smrg   if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
18597117f1b4Smrg      _mesa_scale_and_bias_rgba(n, rgba,
18607117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[RCOMP],
18617117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[GCOMP],
18627117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[BCOMP],
18637117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[ACOMP],
18647117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[RCOMP],
18657117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[GCOMP],
18667117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[BCOMP],
18677117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[ACOMP]);
18687117f1b4Smrg   }
18697117f1b4Smrg   /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
18707117f1b4Smrg   if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
18717117f1b4Smrg      _mesa_lookup_rgba_float(&ctx->ColorTable[COLORTABLE_POSTCONVOLUTION], n, rgba);
18727117f1b4Smrg   }
18737117f1b4Smrg   /* color matrix transform */
18747117f1b4Smrg   if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
18757117f1b4Smrg      _mesa_transform_rgba(ctx, n, rgba);
18767117f1b4Smrg   }
18777117f1b4Smrg   /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
18787117f1b4Smrg   if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
18797117f1b4Smrg      _mesa_lookup_rgba_float(&ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX], n, rgba);
18807117f1b4Smrg   }
18817117f1b4Smrg   /* update histogram count */
18827117f1b4Smrg   if (transferOps & IMAGE_HISTOGRAM_BIT) {
1883c1f859d4Smrg      update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
18847117f1b4Smrg   }
18857117f1b4Smrg   /* update min/max values */
18867117f1b4Smrg   if (transferOps & IMAGE_MIN_MAX_BIT) {
1887c1f859d4Smrg      update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
18887117f1b4Smrg   }
18897117f1b4Smrg   /* clamping to [0,1] */
18907117f1b4Smrg   if (transferOps & IMAGE_CLAMP_BIT) {
18917117f1b4Smrg      GLuint i;
18927117f1b4Smrg      for (i = 0; i < n; i++) {
18937117f1b4Smrg         rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
18947117f1b4Smrg         rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
18957117f1b4Smrg         rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
18967117f1b4Smrg         rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
18977117f1b4Smrg      }
18987117f1b4Smrg   }
18997117f1b4Smrg}
19007117f1b4Smrg
19017117f1b4Smrg
19027117f1b4Smrg/*
19037117f1b4Smrg * Apply color index shift and offset to an array of pixels.
19047117f1b4Smrg */
19057117f1b4Smrgstatic void
19067117f1b4Smrgshift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
19077117f1b4Smrg{
19087117f1b4Smrg   GLint shift = ctx->Pixel.IndexShift;
19097117f1b4Smrg   GLint offset = ctx->Pixel.IndexOffset;
19107117f1b4Smrg   GLuint i;
19117117f1b4Smrg   if (shift > 0) {
19127117f1b4Smrg      for (i=0;i<n;i++) {
19137117f1b4Smrg         indexes[i] = (indexes[i] << shift) + offset;
19147117f1b4Smrg      }
19157117f1b4Smrg   }
19167117f1b4Smrg   else if (shift < 0) {
19177117f1b4Smrg      shift = -shift;
19187117f1b4Smrg      for (i=0;i<n;i++) {
19197117f1b4Smrg         indexes[i] = (indexes[i] >> shift) + offset;
19207117f1b4Smrg      }
19217117f1b4Smrg   }
19227117f1b4Smrg   else {
19237117f1b4Smrg      for (i=0;i<n;i++) {
19247117f1b4Smrg         indexes[i] = indexes[i] + offset;
19257117f1b4Smrg      }
19267117f1b4Smrg   }
19277117f1b4Smrg}
19287117f1b4Smrg
19297117f1b4Smrg
19307117f1b4Smrg
19317117f1b4Smrg/**
19327117f1b4Smrg * Apply color index shift, offset and table lookup to an array
19337117f1b4Smrg * of color indexes;
19347117f1b4Smrg */
19357117f1b4Smrgvoid
19367117f1b4Smrg_mesa_apply_ci_transfer_ops(const GLcontext *ctx, GLbitfield transferOps,
19377117f1b4Smrg                            GLuint n, GLuint indexes[])
19387117f1b4Smrg{
19397117f1b4Smrg   if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
19407117f1b4Smrg      shift_and_offset_ci(ctx, n, indexes);
19417117f1b4Smrg   }
19427117f1b4Smrg   if (transferOps & IMAGE_MAP_COLOR_BIT) {
19437117f1b4Smrg      const GLuint mask = ctx->PixelMaps.ItoI.Size - 1;
19447117f1b4Smrg      GLuint i;
19457117f1b4Smrg      for (i = 0; i < n; i++) {
19467117f1b4Smrg         const GLuint j = indexes[i] & mask;
19477117f1b4Smrg         indexes[i] = IROUND(ctx->PixelMaps.ItoI.Map[j]);
19487117f1b4Smrg      }
19497117f1b4Smrg   }
19507117f1b4Smrg}
19517117f1b4Smrg
19527117f1b4Smrg
19537117f1b4Smrg/**
19547117f1b4Smrg * Apply stencil index shift, offset and table lookup to an array
19557117f1b4Smrg * of stencil values.
19567117f1b4Smrg */
19577117f1b4Smrgvoid
19587117f1b4Smrg_mesa_apply_stencil_transfer_ops(const GLcontext *ctx, GLuint n,
19597117f1b4Smrg                                 GLstencil stencil[])
19607117f1b4Smrg{
19617117f1b4Smrg   if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
19627117f1b4Smrg      const GLint offset = ctx->Pixel.IndexOffset;
19637117f1b4Smrg      GLint shift = ctx->Pixel.IndexShift;
19647117f1b4Smrg      GLuint i;
19657117f1b4Smrg      if (shift > 0) {
19667117f1b4Smrg         for (i = 0; i < n; i++) {
19677117f1b4Smrg            stencil[i] = (stencil[i] << shift) + offset;
19687117f1b4Smrg         }
19697117f1b4Smrg      }
19707117f1b4Smrg      else if (shift < 0) {
19717117f1b4Smrg         shift = -shift;
19727117f1b4Smrg         for (i = 0; i < n; i++) {
19737117f1b4Smrg            stencil[i] = (stencil[i] >> shift) + offset;
19747117f1b4Smrg         }
19757117f1b4Smrg      }
19767117f1b4Smrg      else {
19777117f1b4Smrg         for (i = 0; i < n; i++) {
19787117f1b4Smrg            stencil[i] = stencil[i] + offset;
19797117f1b4Smrg         }
19807117f1b4Smrg      }
19817117f1b4Smrg   }
19827117f1b4Smrg   if (ctx->Pixel.MapStencilFlag) {
19837117f1b4Smrg      GLuint mask = ctx->PixelMaps.StoS.Size - 1;
19847117f1b4Smrg      GLuint i;
19857117f1b4Smrg      for (i = 0; i < n; i++) {
1986c1f859d4Smrg         stencil[i] = (GLstencil)ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
19877117f1b4Smrg      }
19887117f1b4Smrg   }
19897117f1b4Smrg}
19907117f1b4Smrg
19917117f1b4Smrg
19927117f1b4Smrg/**
19937117f1b4Smrg * Used to pack an array [][4] of RGBA float colors as specified
19947117f1b4Smrg * by the dstFormat, dstType and dstPacking.  Used by glReadPixels,
19957117f1b4Smrg * glGetConvolutionFilter(), etc.
19967117f1b4Smrg * Note: the rgba values will be modified by this function when any pixel
19977117f1b4Smrg * transfer ops are enabled.
19987117f1b4Smrg */
19997117f1b4Smrgvoid
20007117f1b4Smrg_mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
20017117f1b4Smrg                           GLenum dstFormat, GLenum dstType,
20027117f1b4Smrg                           GLvoid *dstAddr,
20037117f1b4Smrg                           const struct gl_pixelstore_attrib *dstPacking,
20047117f1b4Smrg                           GLbitfield transferOps)
20057117f1b4Smrg{
20067117f1b4Smrg   GLfloat luminance[MAX_WIDTH];
20077117f1b4Smrg   const GLint comps = _mesa_components_in_format(dstFormat);
20087117f1b4Smrg   GLuint i;
20097117f1b4Smrg
20104a49301eSmrg   /* XXX
20114a49301eSmrg    * This test should probably go away.  Have the caller set/clear the
20124a49301eSmrg    * IMAGE_CLAMP_BIT as needed.
20134a49301eSmrg    */
20147117f1b4Smrg   if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
20157117f1b4Smrg      /* need to clamp to [0, 1] */
20167117f1b4Smrg      transferOps |= IMAGE_CLAMP_BIT;
20177117f1b4Smrg   }
20187117f1b4Smrg
20197117f1b4Smrg   if (transferOps) {
20207117f1b4Smrg      _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
20217117f1b4Smrg      if ((transferOps & IMAGE_MIN_MAX_BIT) && ctx->MinMax.Sink) {
20227117f1b4Smrg         return;
20237117f1b4Smrg      }
20247117f1b4Smrg   }
20257117f1b4Smrg
20267117f1b4Smrg   if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
20277117f1b4Smrg      /* compute luminance values */
2028c1f859d4Smrg      if (transferOps & IMAGE_CLAMP_BIT) {
20297117f1b4Smrg         for (i = 0; i < n; i++) {
20307117f1b4Smrg            GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
20317117f1b4Smrg            luminance[i] = CLAMP(sum, 0.0F, 1.0F);
20327117f1b4Smrg         }
20337117f1b4Smrg      }
20347117f1b4Smrg      else {
20357117f1b4Smrg         for (i = 0; i < n; i++) {
20367117f1b4Smrg            luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
20377117f1b4Smrg         }
20387117f1b4Smrg      }
20397117f1b4Smrg   }
20407117f1b4Smrg
20417117f1b4Smrg   /*
20427117f1b4Smrg    * Pack/store the pixels.  Ugh!  Lots of cases!!!
20437117f1b4Smrg    */
20447117f1b4Smrg   switch (dstType) {
20457117f1b4Smrg      case GL_UNSIGNED_BYTE:
20467117f1b4Smrg         {
20477117f1b4Smrg            GLubyte *dst = (GLubyte *) dstAddr;
20487117f1b4Smrg            switch (dstFormat) {
20497117f1b4Smrg               case GL_RED:
20507117f1b4Smrg                  for (i=0;i<n;i++)
20517117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
20527117f1b4Smrg                  break;
20537117f1b4Smrg               case GL_GREEN:
20547117f1b4Smrg                  for (i=0;i<n;i++)
20557117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
20567117f1b4Smrg                  break;
20577117f1b4Smrg               case GL_BLUE:
20587117f1b4Smrg                  for (i=0;i<n;i++)
20597117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
20607117f1b4Smrg                  break;
20617117f1b4Smrg               case GL_ALPHA:
20627117f1b4Smrg                  for (i=0;i<n;i++)
20637117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
20647117f1b4Smrg                  break;
20657117f1b4Smrg               case GL_LUMINANCE:
20667117f1b4Smrg                  for (i=0;i<n;i++)
20677117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(luminance[i]);
20687117f1b4Smrg                  break;
20697117f1b4Smrg               case GL_LUMINANCE_ALPHA:
20707117f1b4Smrg                  for (i=0;i<n;i++) {
20717117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_UBYTE(luminance[i]);
20727117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
20737117f1b4Smrg                  }
20747117f1b4Smrg                  break;
20757117f1b4Smrg               case GL_RGB:
20767117f1b4Smrg                  for (i=0;i<n;i++) {
20777117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
20787117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
20797117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
20807117f1b4Smrg                  }
20817117f1b4Smrg                  break;
20827117f1b4Smrg               case GL_RGBA:
20837117f1b4Smrg                  for (i=0;i<n;i++) {
20847117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
20857117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
20867117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
20877117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
20887117f1b4Smrg                  }
20897117f1b4Smrg                  break;
20907117f1b4Smrg               case GL_BGR:
20917117f1b4Smrg                  for (i=0;i<n;i++) {
20927117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
20937117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
20947117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
20957117f1b4Smrg                  }
20967117f1b4Smrg                  break;
20977117f1b4Smrg               case GL_BGRA:
20987117f1b4Smrg                  for (i=0;i<n;i++) {
20997117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
21007117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
21017117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
21027117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
21037117f1b4Smrg                  }
21047117f1b4Smrg                  break;
21057117f1b4Smrg               case GL_ABGR_EXT:
21067117f1b4Smrg                  for (i=0;i<n;i++) {
21077117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
21087117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
21097117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
21107117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
21117117f1b4Smrg                  }
21127117f1b4Smrg                  break;
21134a49301eSmrg               case GL_DUDV_ATI:
21144a49301eSmrg               case GL_DU8DV8_ATI:
21154a49301eSmrg                  for (i=0;i<n;i++) {
21164a49301eSmrg                     dst[i*2+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
21174a49301eSmrg                     dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
21184a49301eSmrg                  }
21194a49301eSmrg                  break;
21207117f1b4Smrg               default:
21217117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
21227117f1b4Smrg            }
21237117f1b4Smrg         }
21247117f1b4Smrg         break;
21257117f1b4Smrg      case GL_BYTE:
21267117f1b4Smrg         {
21277117f1b4Smrg            GLbyte *dst = (GLbyte *) dstAddr;
21287117f1b4Smrg            switch (dstFormat) {
21297117f1b4Smrg               case GL_RED:
21307117f1b4Smrg                  for (i=0;i<n;i++)
21317117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21327117f1b4Smrg                  break;
21337117f1b4Smrg               case GL_GREEN:
21347117f1b4Smrg                  for (i=0;i<n;i++)
21357117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21367117f1b4Smrg                  break;
21377117f1b4Smrg               case GL_BLUE:
21387117f1b4Smrg                  for (i=0;i<n;i++)
21397117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
21407117f1b4Smrg                  break;
21417117f1b4Smrg               case GL_ALPHA:
21427117f1b4Smrg                  for (i=0;i<n;i++)
21437117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
21447117f1b4Smrg                  break;
21457117f1b4Smrg               case GL_LUMINANCE:
21467117f1b4Smrg                  for (i=0;i<n;i++)
21477117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(luminance[i]);
21487117f1b4Smrg                  break;
21497117f1b4Smrg               case GL_LUMINANCE_ALPHA:
21507117f1b4Smrg                  for (i=0;i<n;i++) {
21517117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_BYTE(luminance[i]);
21527117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
21537117f1b4Smrg                  }
21547117f1b4Smrg                  break;
21557117f1b4Smrg               case GL_RGB:
21567117f1b4Smrg                  for (i=0;i<n;i++) {
21577117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21587117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21597117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
21607117f1b4Smrg                  }
21617117f1b4Smrg                  break;
21627117f1b4Smrg               case GL_RGBA:
21637117f1b4Smrg                  for (i=0;i<n;i++) {
21647117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21657117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21667117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
21677117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
21687117f1b4Smrg                  }
21697117f1b4Smrg                  break;
21707117f1b4Smrg               case GL_BGR:
21717117f1b4Smrg                  for (i=0;i<n;i++) {
21727117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
21737117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21747117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21757117f1b4Smrg                  }
21767117f1b4Smrg                  break;
21777117f1b4Smrg               case GL_BGRA:
21787117f1b4Smrg                  for (i=0;i<n;i++) {
21797117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
21807117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21817117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21827117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
21837117f1b4Smrg                  }
21847117f1b4Smrg		  break;
21857117f1b4Smrg               case GL_ABGR_EXT:
21867117f1b4Smrg                  for (i=0;i<n;i++) {
21877117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
21887117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
21897117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21907117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21917117f1b4Smrg                  }
21927117f1b4Smrg                  break;
21934a49301eSmrg               case GL_DUDV_ATI:
21944a49301eSmrg               case GL_DU8DV8_ATI:
21954a49301eSmrg                  for (i=0;i<n;i++) {
21964a49301eSmrg                     dst[i*2+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
21974a49301eSmrg                     dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
21984a49301eSmrg                  }
21994a49301eSmrg                  break;
22007117f1b4Smrg               default:
22017117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
22027117f1b4Smrg            }
22037117f1b4Smrg         }
22047117f1b4Smrg         break;
22057117f1b4Smrg      case GL_UNSIGNED_SHORT:
22067117f1b4Smrg         {
22077117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
22087117f1b4Smrg            switch (dstFormat) {
22097117f1b4Smrg               case GL_RED:
22107117f1b4Smrg                  for (i=0;i<n;i++)
22117117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][RCOMP]);
22127117f1b4Smrg                  break;
22137117f1b4Smrg               case GL_GREEN:
22147117f1b4Smrg                  for (i=0;i<n;i++)
22157117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][GCOMP]);
22167117f1b4Smrg                  break;
22177117f1b4Smrg               case GL_BLUE:
22187117f1b4Smrg                  for (i=0;i<n;i++)
22197117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][BCOMP]);
22207117f1b4Smrg                  break;
22217117f1b4Smrg               case GL_ALPHA:
22227117f1b4Smrg                  for (i=0;i<n;i++)
22237117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][ACOMP]);
22247117f1b4Smrg                  break;
22257117f1b4Smrg               case GL_LUMINANCE:
22267117f1b4Smrg                  for (i=0;i<n;i++)
22277117f1b4Smrg                     UNCLAMPED_FLOAT_TO_USHORT(dst[i], luminance[i]);
22287117f1b4Smrg                  break;
22297117f1b4Smrg               case GL_LUMINANCE_ALPHA:
22307117f1b4Smrg                  for (i=0;i<n;i++) {
22317117f1b4Smrg                     UNCLAMPED_FLOAT_TO_USHORT(dst[i*2+0], luminance[i]);
22327117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*2+1], rgba[i][ACOMP]);
22337117f1b4Smrg                  }
22347117f1b4Smrg                  break;
22357117f1b4Smrg               case GL_RGB:
22367117f1b4Smrg                  for (i=0;i<n;i++) {
22377117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][RCOMP]);
22387117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]);
22397117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][BCOMP]);
22407117f1b4Smrg                  }
22417117f1b4Smrg                  break;
22427117f1b4Smrg               case GL_RGBA:
22437117f1b4Smrg                  for (i=0;i<n;i++) {
22447117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][RCOMP]);
22457117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]);
22467117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][BCOMP]);
22477117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]);
22487117f1b4Smrg                  }
22497117f1b4Smrg                  break;
22507117f1b4Smrg               case GL_BGR:
22517117f1b4Smrg                  for (i=0;i<n;i++) {
22527117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][BCOMP]);
22537117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]);
22547117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][RCOMP]);
22557117f1b4Smrg                  }
22567117f1b4Smrg                  break;
22577117f1b4Smrg               case GL_BGRA:
22587117f1b4Smrg                  for (i=0;i<n;i++) {
22597117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][BCOMP]);
22607117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]);
22617117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][RCOMP]);
22627117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]);
22637117f1b4Smrg                  }
22647117f1b4Smrg                  break;
22657117f1b4Smrg               case GL_ABGR_EXT:
22667117f1b4Smrg                  for (i=0;i<n;i++) {
22677117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][ACOMP]);
22687117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][BCOMP]);
22697117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][GCOMP]);
22707117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]);
22717117f1b4Smrg                  }
22727117f1b4Smrg                  break;
22734a49301eSmrg               case GL_DUDV_ATI:
22744a49301eSmrg               case GL_DU8DV8_ATI:
22754a49301eSmrg                  for (i=0;i<n;i++) {
22764a49301eSmrg                     dst[i*2+0] = FLOAT_TO_USHORT(rgba[i][RCOMP]);
22774a49301eSmrg                     dst[i*2+1] = FLOAT_TO_USHORT(rgba[i][GCOMP]);
22784a49301eSmrg                  }
22794a49301eSmrg                  break;
22807117f1b4Smrg               default:
22817117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
22827117f1b4Smrg            }
22837117f1b4Smrg         }
22847117f1b4Smrg         break;
22857117f1b4Smrg      case GL_SHORT:
22867117f1b4Smrg         {
22877117f1b4Smrg            GLshort *dst = (GLshort *) dstAddr;
22887117f1b4Smrg            switch (dstFormat) {
22897117f1b4Smrg               case GL_RED:
22907117f1b4Smrg                  for (i=0;i<n;i++)
22917117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
22927117f1b4Smrg                  break;
22937117f1b4Smrg               case GL_GREEN:
22947117f1b4Smrg                  for (i=0;i<n;i++)
22957117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
22967117f1b4Smrg                  break;
22977117f1b4Smrg               case GL_BLUE:
22987117f1b4Smrg                  for (i=0;i<n;i++)
22997117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
23007117f1b4Smrg                  break;
23017117f1b4Smrg               case GL_ALPHA:
23027117f1b4Smrg                  for (i=0;i<n;i++)
23037117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
23047117f1b4Smrg                  break;
23057117f1b4Smrg               case GL_LUMINANCE:
23067117f1b4Smrg                  for (i=0;i<n;i++)
23077117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(luminance[i]);
23087117f1b4Smrg                  break;
23097117f1b4Smrg               case GL_LUMINANCE_ALPHA:
23107117f1b4Smrg                  for (i=0;i<n;i++) {
23117117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_SHORT(luminance[i]);
23127117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
23137117f1b4Smrg                  }
23147117f1b4Smrg                  break;
23157117f1b4Smrg               case GL_RGB:
23167117f1b4Smrg                  for (i=0;i<n;i++) {
23177117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
23187117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
23197117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
23207117f1b4Smrg                  }
23217117f1b4Smrg                  break;
23227117f1b4Smrg               case GL_RGBA:
23237117f1b4Smrg                  for (i=0;i<n;i++) {
23247117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
23257117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
23267117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
23277117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
23287117f1b4Smrg                  }
23297117f1b4Smrg                  break;
23307117f1b4Smrg               case GL_BGR:
23317117f1b4Smrg                  for (i=0;i<n;i++) {
23327117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
23337117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
23347117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
23357117f1b4Smrg                  }
23367117f1b4Smrg                  break;
23377117f1b4Smrg               case GL_BGRA:
23387117f1b4Smrg                  for (i=0;i<n;i++) {
23397117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
23407117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
23417117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
23427117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
23437117f1b4Smrg                  }
23447117f1b4Smrg		  break;
23457117f1b4Smrg               case GL_ABGR_EXT:
23467117f1b4Smrg                  for (i=0;i<n;i++) {
23477117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
23487117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
23497117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
23507117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
23517117f1b4Smrg                  }
23527117f1b4Smrg                  break;
23534a49301eSmrg               case GL_DUDV_ATI:
23544a49301eSmrg               case GL_DU8DV8_ATI:
23554a49301eSmrg                  for (i=0;i<n;i++) {
23564a49301eSmrg                     dst[i*2+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
23574a49301eSmrg                     dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
23584a49301eSmrg                  }
23594a49301eSmrg                  break;
23607117f1b4Smrg               default:
23617117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
23627117f1b4Smrg            }
23637117f1b4Smrg         }
23647117f1b4Smrg         break;
23657117f1b4Smrg      case GL_UNSIGNED_INT:
23667117f1b4Smrg         {
23677117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
23687117f1b4Smrg            switch (dstFormat) {
23697117f1b4Smrg               case GL_RED:
23707117f1b4Smrg                  for (i=0;i<n;i++)
23717117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][RCOMP]);
23727117f1b4Smrg                  break;
23737117f1b4Smrg               case GL_GREEN:
23747117f1b4Smrg                  for (i=0;i<n;i++)
23757117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][GCOMP]);
23767117f1b4Smrg                  break;
23777117f1b4Smrg               case GL_BLUE:
23787117f1b4Smrg                  for (i=0;i<n;i++)
23797117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][BCOMP]);
23807117f1b4Smrg                  break;
23817117f1b4Smrg               case GL_ALPHA:
23827117f1b4Smrg                  for (i=0;i<n;i++)
23837117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][ACOMP]);
23847117f1b4Smrg                  break;
23857117f1b4Smrg               case GL_LUMINANCE:
23867117f1b4Smrg                  for (i=0;i<n;i++)
23877117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(luminance[i]);
23887117f1b4Smrg                  break;
23897117f1b4Smrg               case GL_LUMINANCE_ALPHA:
23907117f1b4Smrg                  for (i=0;i<n;i++) {
23917117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_UINT(luminance[i]);
23927117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_UINT(rgba[i][ACOMP]);
23937117f1b4Smrg                  }
23947117f1b4Smrg                  break;
23957117f1b4Smrg               case GL_RGB:
23967117f1b4Smrg                  for (i=0;i<n;i++) {
23977117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
23987117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
23997117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UINT(rgba[i][BCOMP]);
24007117f1b4Smrg                  }
24017117f1b4Smrg                  break;
24027117f1b4Smrg               case GL_RGBA:
24037117f1b4Smrg                  for (i=0;i<n;i++) {
24047117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
24057117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
24067117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UINT(rgba[i][BCOMP]);
24077117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]);
24087117f1b4Smrg                  }
24097117f1b4Smrg                  break;
24107117f1b4Smrg               case GL_BGR:
24117117f1b4Smrg                  for (i=0;i<n;i++) {
24127117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UINT(rgba[i][BCOMP]);
24137117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
24147117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UINT(rgba[i][RCOMP]);
24157117f1b4Smrg                  }
24167117f1b4Smrg                  break;
24177117f1b4Smrg               case GL_BGRA:
24187117f1b4Smrg                  for (i=0;i<n;i++) {
24197117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UINT(rgba[i][BCOMP]);
24207117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
24217117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UINT(rgba[i][RCOMP]);
24227117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]);
24237117f1b4Smrg                  }
24247117f1b4Smrg                  break;
24257117f1b4Smrg               case GL_ABGR_EXT:
24267117f1b4Smrg                  for (i=0;i<n;i++) {
24277117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UINT(rgba[i][ACOMP]);
24287117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UINT(rgba[i][BCOMP]);
24297117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UINT(rgba[i][GCOMP]);
24307117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]);
24317117f1b4Smrg                  }
24327117f1b4Smrg                  break;
24334a49301eSmrg               case GL_DUDV_ATI:
24344a49301eSmrg               case GL_DU8DV8_ATI:
24354a49301eSmrg                  for (i=0;i<n;i++) {
24364a49301eSmrg                     dst[i*2+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
24374a49301eSmrg                     dst[i*2+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
24384a49301eSmrg                  }
24394a49301eSmrg                  break;
24407117f1b4Smrg               default:
24417117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
24427117f1b4Smrg            }
24437117f1b4Smrg         }
24447117f1b4Smrg         break;
24457117f1b4Smrg      case GL_INT:
24467117f1b4Smrg         {
24477117f1b4Smrg            GLint *dst = (GLint *) dstAddr;
24487117f1b4Smrg            switch (dstFormat) {
24497117f1b4Smrg               case GL_RED:
24507117f1b4Smrg                  for (i=0;i<n;i++)
24517117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][RCOMP]);
24527117f1b4Smrg                  break;
24537117f1b4Smrg               case GL_GREEN:
24547117f1b4Smrg                  for (i=0;i<n;i++)
24557117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][GCOMP]);
24567117f1b4Smrg                  break;
24577117f1b4Smrg               case GL_BLUE:
24587117f1b4Smrg                  for (i=0;i<n;i++)
24597117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][BCOMP]);
24607117f1b4Smrg                  break;
24617117f1b4Smrg               case GL_ALPHA:
24627117f1b4Smrg                  for (i=0;i<n;i++)
24637117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][ACOMP]);
24647117f1b4Smrg                  break;
24657117f1b4Smrg               case GL_LUMINANCE:
24667117f1b4Smrg                  for (i=0;i<n;i++)
24677117f1b4Smrg                     dst[i] = FLOAT_TO_INT(luminance[i]);
24687117f1b4Smrg                  break;
24697117f1b4Smrg               case GL_LUMINANCE_ALPHA:
24707117f1b4Smrg                  for (i=0;i<n;i++) {
24717117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_INT(luminance[i]);
24727117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_INT(rgba[i][ACOMP]);
24737117f1b4Smrg                  }
24747117f1b4Smrg                  break;
24757117f1b4Smrg               case GL_RGB:
24767117f1b4Smrg                  for (i=0;i<n;i++) {
24777117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
24787117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
24797117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_INT(rgba[i][BCOMP]);
24807117f1b4Smrg                  }
24817117f1b4Smrg                  break;
24827117f1b4Smrg               case GL_RGBA:
24837117f1b4Smrg                  for (i=0;i<n;i++) {
24847117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
24857117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
24867117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_INT(rgba[i][BCOMP]);
24877117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]);
24887117f1b4Smrg                  }
24897117f1b4Smrg                  break;
24907117f1b4Smrg               case GL_BGR:
24917117f1b4Smrg                  for (i=0;i<n;i++) {
24927117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_INT(rgba[i][BCOMP]);
24937117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
24947117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_INT(rgba[i][RCOMP]);
24957117f1b4Smrg                  }
24967117f1b4Smrg                  break;
24977117f1b4Smrg               case GL_BGRA:
24987117f1b4Smrg                  for (i=0;i<n;i++) {
24997117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_INT(rgba[i][BCOMP]);
25007117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
25017117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_INT(rgba[i][RCOMP]);
25027117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]);
25037117f1b4Smrg                  }
25047117f1b4Smrg                  break;
25057117f1b4Smrg               case GL_ABGR_EXT:
25067117f1b4Smrg                  for (i=0;i<n;i++) {
25077117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_INT(rgba[i][ACOMP]);
25087117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_INT(rgba[i][BCOMP]);
25097117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_INT(rgba[i][GCOMP]);
25107117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]);
25117117f1b4Smrg                  }
25127117f1b4Smrg                  break;
25134a49301eSmrg               case GL_DUDV_ATI:
25144a49301eSmrg               case GL_DU8DV8_ATI:
25154a49301eSmrg                  for (i=0;i<n;i++) {
25164a49301eSmrg                     dst[i*2+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
25174a49301eSmrg                     dst[i*2+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
25184a49301eSmrg                  }
25194a49301eSmrg                  break;
25207117f1b4Smrg               default:
25217117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
25227117f1b4Smrg            }
25237117f1b4Smrg         }
25247117f1b4Smrg         break;
25257117f1b4Smrg      case GL_FLOAT:
25267117f1b4Smrg         {
25277117f1b4Smrg            GLfloat *dst = (GLfloat *) dstAddr;
25287117f1b4Smrg            switch (dstFormat) {
25297117f1b4Smrg               case GL_RED:
25307117f1b4Smrg                  for (i=0;i<n;i++)
25317117f1b4Smrg                     dst[i] = rgba[i][RCOMP];
25327117f1b4Smrg                  break;
25337117f1b4Smrg               case GL_GREEN:
25347117f1b4Smrg                  for (i=0;i<n;i++)
25357117f1b4Smrg                     dst[i] = rgba[i][GCOMP];
25367117f1b4Smrg                  break;
25377117f1b4Smrg               case GL_BLUE:
25387117f1b4Smrg                  for (i=0;i<n;i++)
25397117f1b4Smrg                     dst[i] = rgba[i][BCOMP];
25407117f1b4Smrg                  break;
25417117f1b4Smrg               case GL_ALPHA:
25427117f1b4Smrg                  for (i=0;i<n;i++)
25437117f1b4Smrg                     dst[i] = rgba[i][ACOMP];
25447117f1b4Smrg                  break;
25457117f1b4Smrg               case GL_LUMINANCE:
25467117f1b4Smrg                  for (i=0;i<n;i++)
25477117f1b4Smrg                     dst[i] = luminance[i];
25487117f1b4Smrg                  break;
25497117f1b4Smrg               case GL_LUMINANCE_ALPHA:
25507117f1b4Smrg                  for (i=0;i<n;i++) {
25517117f1b4Smrg                     dst[i*2+0] = luminance[i];
25527117f1b4Smrg                     dst[i*2+1] = rgba[i][ACOMP];
25537117f1b4Smrg                  }
25547117f1b4Smrg                  break;
25557117f1b4Smrg               case GL_RGB:
25567117f1b4Smrg                  for (i=0;i<n;i++) {
25577117f1b4Smrg                     dst[i*3+0] = rgba[i][RCOMP];
25587117f1b4Smrg                     dst[i*3+1] = rgba[i][GCOMP];
25597117f1b4Smrg                     dst[i*3+2] = rgba[i][BCOMP];
25607117f1b4Smrg                  }
25617117f1b4Smrg                  break;
25627117f1b4Smrg               case GL_RGBA:
25637117f1b4Smrg                  for (i=0;i<n;i++) {
25647117f1b4Smrg                     dst[i*4+0] = rgba[i][RCOMP];
25657117f1b4Smrg                     dst[i*4+1] = rgba[i][GCOMP];
25667117f1b4Smrg                     dst[i*4+2] = rgba[i][BCOMP];
25677117f1b4Smrg                     dst[i*4+3] = rgba[i][ACOMP];
25687117f1b4Smrg                  }
25697117f1b4Smrg                  break;
25707117f1b4Smrg               case GL_BGR:
25717117f1b4Smrg                  for (i=0;i<n;i++) {
25727117f1b4Smrg                     dst[i*3+0] = rgba[i][BCOMP];
25737117f1b4Smrg                     dst[i*3+1] = rgba[i][GCOMP];
25747117f1b4Smrg                     dst[i*3+2] = rgba[i][RCOMP];
25757117f1b4Smrg                  }
25767117f1b4Smrg                  break;
25777117f1b4Smrg               case GL_BGRA:
25787117f1b4Smrg                  for (i=0;i<n;i++) {
25797117f1b4Smrg                     dst[i*4+0] = rgba[i][BCOMP];
25807117f1b4Smrg                     dst[i*4+1] = rgba[i][GCOMP];
25817117f1b4Smrg                     dst[i*4+2] = rgba[i][RCOMP];
25827117f1b4Smrg                     dst[i*4+3] = rgba[i][ACOMP];
25837117f1b4Smrg                  }
25847117f1b4Smrg                  break;
25857117f1b4Smrg               case GL_ABGR_EXT:
25867117f1b4Smrg                  for (i=0;i<n;i++) {
25877117f1b4Smrg                     dst[i*4+0] = rgba[i][ACOMP];
25887117f1b4Smrg                     dst[i*4+1] = rgba[i][BCOMP];
25897117f1b4Smrg                     dst[i*4+2] = rgba[i][GCOMP];
25907117f1b4Smrg                     dst[i*4+3] = rgba[i][RCOMP];
25917117f1b4Smrg                  }
25927117f1b4Smrg                  break;
25934a49301eSmrg               case GL_DUDV_ATI:
25944a49301eSmrg               case GL_DU8DV8_ATI:
25954a49301eSmrg                  for (i=0;i<n;i++) {
25964a49301eSmrg                     dst[i*2+0] = rgba[i][RCOMP];
25974a49301eSmrg                     dst[i*2+1] = rgba[i][GCOMP];
25984a49301eSmrg                  }
25994a49301eSmrg                  break;
26007117f1b4Smrg               default:
26017117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
26027117f1b4Smrg            }
26037117f1b4Smrg         }
26047117f1b4Smrg         break;
26057117f1b4Smrg      case GL_HALF_FLOAT_ARB:
26067117f1b4Smrg         {
26077117f1b4Smrg            GLhalfARB *dst = (GLhalfARB *) dstAddr;
26087117f1b4Smrg            switch (dstFormat) {
26097117f1b4Smrg               case GL_RED:
26107117f1b4Smrg                  for (i=0;i<n;i++)
26117117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][RCOMP]);
26127117f1b4Smrg                  break;
26137117f1b4Smrg               case GL_GREEN:
26147117f1b4Smrg                  for (i=0;i<n;i++)
26157117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][GCOMP]);
26167117f1b4Smrg                  break;
26177117f1b4Smrg               case GL_BLUE:
26187117f1b4Smrg                  for (i=0;i<n;i++)
26197117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][BCOMP]);
26207117f1b4Smrg                  break;
26217117f1b4Smrg               case GL_ALPHA:
26227117f1b4Smrg                  for (i=0;i<n;i++)
26237117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][ACOMP]);
26247117f1b4Smrg                  break;
26257117f1b4Smrg               case GL_LUMINANCE:
26267117f1b4Smrg                  for (i=0;i<n;i++)
26277117f1b4Smrg                     dst[i] = _mesa_float_to_half(luminance[i]);
26287117f1b4Smrg                  break;
26297117f1b4Smrg               case GL_LUMINANCE_ALPHA:
26307117f1b4Smrg                  for (i=0;i<n;i++) {
26317117f1b4Smrg                     dst[i*2+0] = _mesa_float_to_half(luminance[i]);
26327117f1b4Smrg                     dst[i*2+1] = _mesa_float_to_half(rgba[i][ACOMP]);
26337117f1b4Smrg                  }
26347117f1b4Smrg                  break;
26357117f1b4Smrg               case GL_RGB:
26367117f1b4Smrg                  for (i=0;i<n;i++) {
26377117f1b4Smrg                     dst[i*3+0] = _mesa_float_to_half(rgba[i][RCOMP]);
26387117f1b4Smrg                     dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]);
26397117f1b4Smrg                     dst[i*3+2] = _mesa_float_to_half(rgba[i][BCOMP]);
26407117f1b4Smrg                  }
26417117f1b4Smrg                  break;
26427117f1b4Smrg               case GL_RGBA:
26437117f1b4Smrg                  for (i=0;i<n;i++) {
26447117f1b4Smrg                     dst[i*4+0] = _mesa_float_to_half(rgba[i][RCOMP]);
26457117f1b4Smrg                     dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]);
26467117f1b4Smrg                     dst[i*4+2] = _mesa_float_to_half(rgba[i][BCOMP]);
26477117f1b4Smrg                     dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]);
26487117f1b4Smrg                  }
26497117f1b4Smrg                  break;
26507117f1b4Smrg               case GL_BGR:
26517117f1b4Smrg                  for (i=0;i<n;i++) {
26527117f1b4Smrg                     dst[i*3+0] = _mesa_float_to_half(rgba[i][BCOMP]);
26537117f1b4Smrg                     dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]);
26547117f1b4Smrg                     dst[i*3+2] = _mesa_float_to_half(rgba[i][RCOMP]);
26557117f1b4Smrg                  }
26567117f1b4Smrg                  break;
26577117f1b4Smrg               case GL_BGRA:
26587117f1b4Smrg                  for (i=0;i<n;i++) {
26597117f1b4Smrg                     dst[i*4+0] = _mesa_float_to_half(rgba[i][BCOMP]);
26607117f1b4Smrg                     dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]);
26617117f1b4Smrg                     dst[i*4+2] = _mesa_float_to_half(rgba[i][RCOMP]);
26627117f1b4Smrg                     dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]);
26637117f1b4Smrg                  }
26647117f1b4Smrg                  break;
26657117f1b4Smrg               case GL_ABGR_EXT:
26667117f1b4Smrg                  for (i=0;i<n;i++) {
26677117f1b4Smrg                     dst[i*4+0] = _mesa_float_to_half(rgba[i][ACOMP]);
26687117f1b4Smrg                     dst[i*4+1] = _mesa_float_to_half(rgba[i][BCOMP]);
26697117f1b4Smrg                     dst[i*4+2] = _mesa_float_to_half(rgba[i][GCOMP]);
26707117f1b4Smrg                     dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]);
26717117f1b4Smrg                  }
26727117f1b4Smrg                  break;
26734a49301eSmrg               case GL_DUDV_ATI:
26744a49301eSmrg               case GL_DU8DV8_ATI:
26754a49301eSmrg                  for (i=0;i<n;i++) {
26764a49301eSmrg                     dst[i*2+0] = _mesa_float_to_half(rgba[i][RCOMP]);
26774a49301eSmrg                     dst[i*2+1] = _mesa_float_to_half(rgba[i][GCOMP]);
26784a49301eSmrg                  }
26794a49301eSmrg                  break;
26807117f1b4Smrg               default:
26817117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
26827117f1b4Smrg            }
26837117f1b4Smrg         }
26847117f1b4Smrg         break;
26857117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
26867117f1b4Smrg         if (dstFormat == GL_RGB) {
26877117f1b4Smrg            GLubyte *dst = (GLubyte *) dstAddr;
26887117f1b4Smrg            for (i=0;i<n;i++) {
26894a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F) << 5)
26904a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 7.0F) << 2)
26914a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 3.0F)     );
26927117f1b4Smrg            }
26937117f1b4Smrg         }
26947117f1b4Smrg         break;
26957117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
26967117f1b4Smrg         if (dstFormat == GL_RGB) {
26977117f1b4Smrg            GLubyte *dst = (GLubyte *) dstAddr;
26987117f1b4Smrg            for (i=0;i<n;i++) {
26994a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F)     )
27004a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 7.0F) << 3)
27014a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 3.0F) << 6);
27027117f1b4Smrg            }
27037117f1b4Smrg         }
27047117f1b4Smrg         break;
27057117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
27067117f1b4Smrg         if (dstFormat == GL_RGB) {
27077117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27087117f1b4Smrg            for (i=0;i<n;i++) {
27094a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11)
27104a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 63.0F) <<  5)
27114a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 31.0F)      );
27127117f1b4Smrg            }
27137117f1b4Smrg         }
27147117f1b4Smrg         break;
27157117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
27167117f1b4Smrg         if (dstFormat == GL_RGB) {
27177117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27187117f1b4Smrg            for (i=0;i<n;i++) {
27194a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F)      )
27204a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 63.0F) <<  5)
27214a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 31.0F) << 11);
27227117f1b4Smrg            }
27237117f1b4Smrg         }
27247117f1b4Smrg         break;
27257117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
27267117f1b4Smrg         if (dstFormat == GL_RGBA) {
27277117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27287117f1b4Smrg            for (i=0;i<n;i++) {
27294a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 15.0F) << 12)
27304a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  8)
27314a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  4)
27324a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 15.0F)      );
27337117f1b4Smrg            }
27347117f1b4Smrg         }
27357117f1b4Smrg         else if (dstFormat == GL_BGRA) {
27367117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27377117f1b4Smrg            for (i=0;i<n;i++) {
27384a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 15.0F) << 12)
27394a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  8)
27404a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 15.0F) <<  4)
27414a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 15.0F)      );
27427117f1b4Smrg            }
27437117f1b4Smrg         }
27447117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
27457117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27467117f1b4Smrg            for (i=0;i<n;i++) {
27474a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 15.0F) << 12)
27484a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  8)
27494a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  4)
27504a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 15.0F)      );
27517117f1b4Smrg            }
27527117f1b4Smrg         }
27537117f1b4Smrg         break;
27547117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
27557117f1b4Smrg         if (dstFormat == GL_RGBA) {
27567117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27577117f1b4Smrg            for (i=0;i<n;i++) {
27584a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 15.0F)      )
27594a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  4)
27604a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  8)
27614a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 15.0F) << 12);
27627117f1b4Smrg            }
27637117f1b4Smrg         }
27647117f1b4Smrg         else if (dstFormat == GL_BGRA) {
27657117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27667117f1b4Smrg            for (i=0;i<n;i++) {
27674a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 15.0F)      )
27684a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  4)
27694a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 15.0F) <<  8)
27704a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 15.0F) << 12);
27717117f1b4Smrg            }
27727117f1b4Smrg         }
27737117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
27747117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27757117f1b4Smrg            for (i=0;i<n;i++) {
27764a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 15.0F)      )
27774a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 15.0F) <<  4)
27784a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 15.0F) <<  8)
27794a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 15.0F) << 12);
27807117f1b4Smrg            }
27817117f1b4Smrg         }
27827117f1b4Smrg         break;
27837117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
27847117f1b4Smrg         if (dstFormat == GL_RGBA) {
27857117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27867117f1b4Smrg            for (i=0;i<n;i++) {
27874a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11)
27884a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  6)
27894a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 31.0F) <<  1)
27904a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *  1.0F)      );
27917117f1b4Smrg            }
27927117f1b4Smrg         }
27937117f1b4Smrg         else if (dstFormat == GL_BGRA) {
27947117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
27957117f1b4Smrg            for (i=0;i<n;i++) {
27964a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 31.0F) << 11)
27974a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  6)
27984a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 31.0F) <<  1)
27994a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *  1.0F)      );
28007117f1b4Smrg            }
28017117f1b4Smrg         }
28027117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
28037117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
28047117f1b4Smrg            for (i=0;i<n;i++) {
28054a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 31.0F) << 11)
28064a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 31.0F) <<  6)
28074a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  1)
28084a49301eSmrg                      | (IROUND(rgba[i][RCOMP] *  1.0F)      );
28097117f1b4Smrg            }
28107117f1b4Smrg         }
28117117f1b4Smrg         break;
28127117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
28137117f1b4Smrg         if (dstFormat == GL_RGBA) {
28147117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
28157117f1b4Smrg            for (i=0;i<n;i++) {
28164a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F)      )
28174a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  5)
28184a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 31.0F) << 10)
28194a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *  1.0F) << 15);
28207117f1b4Smrg            }
28217117f1b4Smrg         }
28227117f1b4Smrg         else if (dstFormat == GL_BGRA) {
28237117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
28247117f1b4Smrg            for (i=0;i<n;i++) {
28254a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 31.0F)      )
28264a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 31.0F) <<  5)
28274a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 31.0F) << 10)
28284a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *  1.0F) << 15);
28297117f1b4Smrg            }
28307117f1b4Smrg         }
28317117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
28327117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
28337117f1b4Smrg            for (i=0;i<n;i++) {
28344a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 31.0F)      )
28354a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 31.0F) <<  5)
28364a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 31.0F) << 10)
28374a49301eSmrg                      | (IROUND(rgba[i][RCOMP] *  1.0F) << 15);
28387117f1b4Smrg            }
28397117f1b4Smrg         }
28407117f1b4Smrg         break;
28417117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
28427117f1b4Smrg         if (dstFormat == GL_RGBA) {
28437117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
28447117f1b4Smrg            for (i=0;i<n;i++) {
28454a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 255.F) << 24)
28464a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 255.F) << 16)
28474a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 255.F) <<  8)
28484a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 255.F)      );
28497117f1b4Smrg            }
28507117f1b4Smrg         }
28517117f1b4Smrg         else if (dstFormat == GL_BGRA) {
28527117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
28537117f1b4Smrg            for (i=0;i<n;i++) {
28544a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 255.F) << 24)
28554a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 255.F) << 16)
28564a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 255.F) <<  8)
28574a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 255.F)      );
28587117f1b4Smrg            }
28597117f1b4Smrg         }
28607117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
28617117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
28627117f1b4Smrg            for (i=0;i<n;i++) {
28634a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 255.F) << 24)
28644a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 255.F) << 16)
28654a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 255.F) <<  8)
28664a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 255.F)      );
28677117f1b4Smrg            }
28687117f1b4Smrg         }
28697117f1b4Smrg         break;
28707117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
28717117f1b4Smrg         if (dstFormat == GL_RGBA) {
28727117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
28737117f1b4Smrg            for (i=0;i<n;i++) {
28744a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 255.0F)      )
28754a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 255.0F) <<  8)
28764a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 255.0F) << 16)
28774a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 255.0F) << 24);
28787117f1b4Smrg            }
28797117f1b4Smrg         }
28807117f1b4Smrg         else if (dstFormat == GL_BGRA) {
28817117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
28827117f1b4Smrg            for (i=0;i<n;i++) {
28834a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 255.0F)      )
28844a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 255.0F) <<  8)
28854a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 255.0F) << 16)
28864a49301eSmrg                      | (IROUND(rgba[i][ACOMP] * 255.0F) << 24);
28877117f1b4Smrg            }
28887117f1b4Smrg         }
28897117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
28907117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
28917117f1b4Smrg            for (i=0;i<n;i++) {
28924a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 255.0F)      )
28934a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 255.0F) <<  8)
28944a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 255.0F) << 16)
28954a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 255.0F) << 24);
28967117f1b4Smrg            }
28977117f1b4Smrg         }
28987117f1b4Smrg         break;
28997117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
29007117f1b4Smrg         if (dstFormat == GL_RGBA) {
29017117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
29027117f1b4Smrg            for (i=0;i<n;i++) {
29034a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 1023.0F) << 22)
29044a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 12)
29054a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 1023.0F) <<  2)
29064a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *    3.0F)      );
29077117f1b4Smrg            }
29087117f1b4Smrg         }
29097117f1b4Smrg         else if (dstFormat == GL_BGRA) {
29107117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
29117117f1b4Smrg            for (i=0;i<n;i++) {
29124a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 1023.0F) << 22)
29134a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 12)
29144a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 1023.0F) <<  2)
29154a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *    3.0F)      );
29167117f1b4Smrg            }
29177117f1b4Smrg         }
29187117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
29197117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
29207117f1b4Smrg            for (i=0;i<n;i++) {
29214a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 1023.0F) << 22)
29224a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 1023.0F) << 12)
29234a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 1023.0F) <<  2)
29244a49301eSmrg                      | (IROUND(rgba[i][RCOMP] *    3.0F)      );
29257117f1b4Smrg            }
29267117f1b4Smrg         }
29277117f1b4Smrg         break;
29287117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
29297117f1b4Smrg         if (dstFormat == GL_RGBA) {
29307117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
29317117f1b4Smrg            for (i=0;i<n;i++) {
29324a49301eSmrg               dst[i] = (IROUND(rgba[i][RCOMP] * 1023.0F)      )
29334a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 10)
29344a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 1023.0F) << 20)
29354a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *    3.0F) << 30);
29367117f1b4Smrg            }
29377117f1b4Smrg         }
29387117f1b4Smrg         else if (dstFormat == GL_BGRA) {
29397117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
29407117f1b4Smrg            for (i=0;i<n;i++) {
29414a49301eSmrg               dst[i] = (IROUND(rgba[i][BCOMP] * 1023.0F)      )
29424a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 10)
29434a49301eSmrg                      | (IROUND(rgba[i][RCOMP] * 1023.0F) << 20)
29444a49301eSmrg                      | (IROUND(rgba[i][ACOMP] *    3.0F) << 30);
29457117f1b4Smrg            }
29467117f1b4Smrg         }
29477117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
29487117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
29497117f1b4Smrg            for (i=0;i<n;i++) {
29504a49301eSmrg               dst[i] = (IROUND(rgba[i][ACOMP] * 1023.0F)      )
29514a49301eSmrg                      | (IROUND(rgba[i][BCOMP] * 1023.0F) << 10)
29524a49301eSmrg                      | (IROUND(rgba[i][GCOMP] * 1023.0F) << 20)
29534a49301eSmrg                      | (IROUND(rgba[i][RCOMP] *    3.0F) << 30);
29547117f1b4Smrg            }
29557117f1b4Smrg         }
29567117f1b4Smrg         break;
29577117f1b4Smrg      default:
29587117f1b4Smrg         _mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float");
29597117f1b4Smrg         return;
29607117f1b4Smrg   }
29617117f1b4Smrg
29627117f1b4Smrg   if (dstPacking->SwapBytes) {
29637117f1b4Smrg      GLint swapSize = _mesa_sizeof_packed_type(dstType);
29647117f1b4Smrg      if (swapSize == 2) {
29657117f1b4Smrg         if (dstPacking->SwapBytes) {
29667117f1b4Smrg            _mesa_swap2((GLushort *) dstAddr, n * comps);
29677117f1b4Smrg         }
29687117f1b4Smrg      }
29697117f1b4Smrg      else if (swapSize == 4) {
29707117f1b4Smrg         if (dstPacking->SwapBytes) {
29717117f1b4Smrg            _mesa_swap4((GLuint *) dstAddr, n * comps);
29727117f1b4Smrg         }
29737117f1b4Smrg      }
29747117f1b4Smrg   }
29757117f1b4Smrg}
29767117f1b4Smrg
29777117f1b4Smrg
29787117f1b4Smrg#define SWAP2BYTE(VALUE)			\
29797117f1b4Smrg   {						\
29807117f1b4Smrg      GLubyte *bytes = (GLubyte *) &(VALUE);	\
29817117f1b4Smrg      GLubyte tmp = bytes[0];			\
29827117f1b4Smrg      bytes[0] = bytes[1];			\
29837117f1b4Smrg      bytes[1] = tmp;				\
29847117f1b4Smrg   }
29857117f1b4Smrg
29867117f1b4Smrg#define SWAP4BYTE(VALUE)			\
29877117f1b4Smrg   {						\
29887117f1b4Smrg      GLubyte *bytes = (GLubyte *) &(VALUE);	\
29897117f1b4Smrg      GLubyte tmp = bytes[0];			\
29907117f1b4Smrg      bytes[0] = bytes[3];			\
29917117f1b4Smrg      bytes[3] = tmp;				\
29927117f1b4Smrg      tmp = bytes[1];				\
29937117f1b4Smrg      bytes[1] = bytes[2];			\
29947117f1b4Smrg      bytes[2] = tmp;				\
29957117f1b4Smrg   }
29967117f1b4Smrg
29977117f1b4Smrg
29987117f1b4Smrgstatic void
29997117f1b4Smrgextract_uint_indexes(GLuint n, GLuint indexes[],
30007117f1b4Smrg                     GLenum srcFormat, GLenum srcType, const GLvoid *src,
30017117f1b4Smrg                     const struct gl_pixelstore_attrib *unpack )
30027117f1b4Smrg{
30037117f1b4Smrg   ASSERT(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX);
30047117f1b4Smrg
30057117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
30067117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
30077117f1b4Smrg          srcType == GL_BYTE ||
30087117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
30097117f1b4Smrg          srcType == GL_SHORT ||
30107117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
30117117f1b4Smrg          srcType == GL_INT ||
30127117f1b4Smrg          srcType == GL_UNSIGNED_INT_24_8_EXT ||
30137117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
30147117f1b4Smrg          srcType == GL_FLOAT);
30157117f1b4Smrg
30167117f1b4Smrg   switch (srcType) {
30177117f1b4Smrg      case GL_BITMAP:
30187117f1b4Smrg         {
30197117f1b4Smrg            GLubyte *ubsrc = (GLubyte *) src;
30207117f1b4Smrg            if (unpack->LsbFirst) {
30217117f1b4Smrg               GLubyte mask = 1 << (unpack->SkipPixels & 0x7);
30227117f1b4Smrg               GLuint i;
30237117f1b4Smrg               for (i = 0; i < n; i++) {
30247117f1b4Smrg                  indexes[i] = (*ubsrc & mask) ? 1 : 0;
30257117f1b4Smrg                  if (mask == 128) {
30267117f1b4Smrg                     mask = 1;
30277117f1b4Smrg                     ubsrc++;
30287117f1b4Smrg                  }
30297117f1b4Smrg                  else {
30307117f1b4Smrg                     mask = mask << 1;
30317117f1b4Smrg                  }
30327117f1b4Smrg               }
30337117f1b4Smrg            }
30347117f1b4Smrg            else {
30357117f1b4Smrg               GLubyte mask = 128 >> (unpack->SkipPixels & 0x7);
30367117f1b4Smrg               GLuint i;
30377117f1b4Smrg               for (i = 0; i < n; i++) {
30387117f1b4Smrg                  indexes[i] = (*ubsrc & mask) ? 1 : 0;
30397117f1b4Smrg                  if (mask == 1) {
30407117f1b4Smrg                     mask = 128;
30417117f1b4Smrg                     ubsrc++;
30427117f1b4Smrg                  }
30437117f1b4Smrg                  else {
30447117f1b4Smrg                     mask = mask >> 1;
30457117f1b4Smrg                  }
30467117f1b4Smrg               }
30477117f1b4Smrg            }
30487117f1b4Smrg         }
30497117f1b4Smrg         break;
30507117f1b4Smrg      case GL_UNSIGNED_BYTE:
30517117f1b4Smrg         {
30527117f1b4Smrg            GLuint i;
30537117f1b4Smrg            const GLubyte *s = (const GLubyte *) src;
30547117f1b4Smrg            for (i = 0; i < n; i++)
30557117f1b4Smrg               indexes[i] = s[i];
30567117f1b4Smrg         }
30577117f1b4Smrg         break;
30587117f1b4Smrg      case GL_BYTE:
30597117f1b4Smrg         {
30607117f1b4Smrg            GLuint i;
30617117f1b4Smrg            const GLbyte *s = (const GLbyte *) src;
30627117f1b4Smrg            for (i = 0; i < n; i++)
30637117f1b4Smrg               indexes[i] = s[i];
30647117f1b4Smrg         }
30657117f1b4Smrg         break;
30667117f1b4Smrg      case GL_UNSIGNED_SHORT:
30677117f1b4Smrg         {
30687117f1b4Smrg            GLuint i;
30697117f1b4Smrg            const GLushort *s = (const GLushort *) src;
30707117f1b4Smrg            if (unpack->SwapBytes) {
30717117f1b4Smrg               for (i = 0; i < n; i++) {
30727117f1b4Smrg                  GLushort value = s[i];
30737117f1b4Smrg                  SWAP2BYTE(value);
30747117f1b4Smrg                  indexes[i] = value;
30757117f1b4Smrg               }
30767117f1b4Smrg            }
30777117f1b4Smrg            else {
30787117f1b4Smrg               for (i = 0; i < n; i++)
30797117f1b4Smrg                  indexes[i] = s[i];
30807117f1b4Smrg            }
30817117f1b4Smrg         }
30827117f1b4Smrg         break;
30837117f1b4Smrg      case GL_SHORT:
30847117f1b4Smrg         {
30857117f1b4Smrg            GLuint i;
30867117f1b4Smrg            const GLshort *s = (const GLshort *) src;
30877117f1b4Smrg            if (unpack->SwapBytes) {
30887117f1b4Smrg               for (i = 0; i < n; i++) {
30897117f1b4Smrg                  GLshort value = s[i];
30907117f1b4Smrg                  SWAP2BYTE(value);
30917117f1b4Smrg                  indexes[i] = value;
30927117f1b4Smrg               }
30937117f1b4Smrg            }
30947117f1b4Smrg            else {
30957117f1b4Smrg               for (i = 0; i < n; i++)
30967117f1b4Smrg                  indexes[i] = s[i];
30977117f1b4Smrg            }
30987117f1b4Smrg         }
30997117f1b4Smrg         break;
31007117f1b4Smrg      case GL_UNSIGNED_INT:
31017117f1b4Smrg         {
31027117f1b4Smrg            GLuint i;
31037117f1b4Smrg            const GLuint *s = (const GLuint *) src;
31047117f1b4Smrg            if (unpack->SwapBytes) {
31057117f1b4Smrg               for (i = 0; i < n; i++) {
31067117f1b4Smrg                  GLuint value = s[i];
31077117f1b4Smrg                  SWAP4BYTE(value);
31087117f1b4Smrg                  indexes[i] = value;
31097117f1b4Smrg               }
31107117f1b4Smrg            }
31117117f1b4Smrg            else {
31127117f1b4Smrg               for (i = 0; i < n; i++)
31137117f1b4Smrg                  indexes[i] = s[i];
31147117f1b4Smrg            }
31157117f1b4Smrg         }
31167117f1b4Smrg         break;
31177117f1b4Smrg      case GL_INT:
31187117f1b4Smrg         {
31197117f1b4Smrg            GLuint i;
31207117f1b4Smrg            const GLint *s = (const GLint *) src;
31217117f1b4Smrg            if (unpack->SwapBytes) {
31227117f1b4Smrg               for (i = 0; i < n; i++) {
31237117f1b4Smrg                  GLint value = s[i];
31247117f1b4Smrg                  SWAP4BYTE(value);
31257117f1b4Smrg                  indexes[i] = value;
31267117f1b4Smrg               }
31277117f1b4Smrg            }
31287117f1b4Smrg            else {
31297117f1b4Smrg               for (i = 0; i < n; i++)
31307117f1b4Smrg                  indexes[i] = s[i];
31317117f1b4Smrg            }
31327117f1b4Smrg         }
31337117f1b4Smrg         break;
31347117f1b4Smrg      case GL_FLOAT:
31357117f1b4Smrg         {
31367117f1b4Smrg            GLuint i;
31377117f1b4Smrg            const GLfloat *s = (const GLfloat *) src;
31387117f1b4Smrg            if (unpack->SwapBytes) {
31397117f1b4Smrg               for (i = 0; i < n; i++) {
31407117f1b4Smrg                  GLfloat value = s[i];
31417117f1b4Smrg                  SWAP4BYTE(value);
31427117f1b4Smrg                  indexes[i] = (GLuint) value;
31437117f1b4Smrg               }
31447117f1b4Smrg            }
31457117f1b4Smrg            else {
31467117f1b4Smrg               for (i = 0; i < n; i++)
31477117f1b4Smrg                  indexes[i] = (GLuint) s[i];
31487117f1b4Smrg            }
31497117f1b4Smrg         }
31507117f1b4Smrg         break;
31517117f1b4Smrg      case GL_HALF_FLOAT_ARB:
31527117f1b4Smrg         {
31537117f1b4Smrg            GLuint i;
31547117f1b4Smrg            const GLhalfARB *s = (const GLhalfARB *) src;
31557117f1b4Smrg            if (unpack->SwapBytes) {
31567117f1b4Smrg               for (i = 0; i < n; i++) {
31577117f1b4Smrg                  GLhalfARB value = s[i];
31587117f1b4Smrg                  SWAP2BYTE(value);
31597117f1b4Smrg                  indexes[i] = (GLuint) _mesa_half_to_float(value);
31607117f1b4Smrg               }
31617117f1b4Smrg            }
31627117f1b4Smrg            else {
31637117f1b4Smrg               for (i = 0; i < n; i++)
31647117f1b4Smrg                  indexes[i] = (GLuint) _mesa_half_to_float(s[i]);
31657117f1b4Smrg            }
31667117f1b4Smrg         }
31677117f1b4Smrg         break;
31687117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT:
31697117f1b4Smrg         {
31707117f1b4Smrg            GLuint i;
31717117f1b4Smrg            const GLuint *s = (const GLuint *) src;
31727117f1b4Smrg            if (unpack->SwapBytes) {
31737117f1b4Smrg               for (i = 0; i < n; i++) {
31747117f1b4Smrg                  GLuint value = s[i];
31757117f1b4Smrg                  SWAP4BYTE(value);
31767117f1b4Smrg                  indexes[i] = value & 0xff;  /* lower 8 bits */
31777117f1b4Smrg               }
31787117f1b4Smrg            }
31797117f1b4Smrg            else {
31807117f1b4Smrg               for (i = 0; i < n; i++)
31814a49301eSmrg                  indexes[i] = s[i] & 0xff;  /* lower 8 bits */
31827117f1b4Smrg            }
31837117f1b4Smrg         }
31847117f1b4Smrg         break;
31857117f1b4Smrg
31867117f1b4Smrg      default:
31877117f1b4Smrg         _mesa_problem(NULL, "bad srcType in extract_uint_indexes");
31887117f1b4Smrg         return;
31897117f1b4Smrg   }
31907117f1b4Smrg}
31917117f1b4Smrg
31927117f1b4Smrg
31937117f1b4Smrg/*
31947117f1b4Smrg * This function extracts floating point RGBA values from arbitrary
31957117f1b4Smrg * image data.  srcFormat and srcType are the format and type parameters
31967117f1b4Smrg * passed to glDrawPixels, glTexImage[123]D, glTexSubImage[123]D, etc.
31977117f1b4Smrg *
31987117f1b4Smrg * Refering to section 3.6.4 of the OpenGL 1.2 spec, this function
31997117f1b4Smrg * implements the "Conversion to floating point", "Conversion to RGB",
32007117f1b4Smrg * and "Final Expansion to RGBA" operations.
32017117f1b4Smrg *
32027117f1b4Smrg * Args:  n - number of pixels
32037117f1b4Smrg *        rgba - output colors
32047117f1b4Smrg *        srcFormat - format of incoming data
32057117f1b4Smrg *        srcType - data type of incoming data
32067117f1b4Smrg *        src - source data pointer
32077117f1b4Smrg *        swapBytes - perform byteswapping of incoming data?
32087117f1b4Smrg */
32097117f1b4Smrgstatic void
32107117f1b4Smrgextract_float_rgba(GLuint n, GLfloat rgba[][4],
32117117f1b4Smrg                   GLenum srcFormat, GLenum srcType, const GLvoid *src,
32127117f1b4Smrg                   GLboolean swapBytes)
32137117f1b4Smrg{
32147117f1b4Smrg   GLint redIndex, greenIndex, blueIndex, alphaIndex;
32157117f1b4Smrg   GLint stride;
32167117f1b4Smrg   GLint rComp, bComp, gComp, aComp;
32177117f1b4Smrg
32187117f1b4Smrg   ASSERT(srcFormat == GL_RED ||
32197117f1b4Smrg          srcFormat == GL_GREEN ||
32207117f1b4Smrg          srcFormat == GL_BLUE ||
32217117f1b4Smrg          srcFormat == GL_ALPHA ||
32227117f1b4Smrg          srcFormat == GL_LUMINANCE ||
32237117f1b4Smrg          srcFormat == GL_LUMINANCE_ALPHA ||
32247117f1b4Smrg          srcFormat == GL_INTENSITY ||
32257117f1b4Smrg          srcFormat == GL_RGB ||
32267117f1b4Smrg          srcFormat == GL_BGR ||
32277117f1b4Smrg          srcFormat == GL_RGBA ||
32287117f1b4Smrg          srcFormat == GL_BGRA ||
32294a49301eSmrg          srcFormat == GL_ABGR_EXT ||
32304a49301eSmrg          srcFormat == GL_DU8DV8_ATI ||
32314a49301eSmrg          srcFormat == GL_DUDV_ATI);
32327117f1b4Smrg
32337117f1b4Smrg   ASSERT(srcType == GL_UNSIGNED_BYTE ||
32347117f1b4Smrg          srcType == GL_BYTE ||
32357117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
32367117f1b4Smrg          srcType == GL_SHORT ||
32377117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
32387117f1b4Smrg          srcType == GL_INT ||
32397117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
32407117f1b4Smrg          srcType == GL_FLOAT ||
32417117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_3_3_2 ||
32427117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
32437117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5 ||
32447117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
32457117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
32467117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
32477117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
32487117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
32497117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
32507117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
32517117f1b4Smrg          srcType == GL_UNSIGNED_INT_10_10_10_2 ||
32527117f1b4Smrg          srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
32537117f1b4Smrg
32547117f1b4Smrg   rComp = gComp = bComp = aComp = -1;
32557117f1b4Smrg
32567117f1b4Smrg   switch (srcFormat) {
32577117f1b4Smrg      case GL_RED:
32587117f1b4Smrg         redIndex = 0;
32597117f1b4Smrg         greenIndex = blueIndex = alphaIndex = -1;
32607117f1b4Smrg         stride = 1;
32617117f1b4Smrg         break;
32627117f1b4Smrg      case GL_GREEN:
32637117f1b4Smrg         greenIndex = 0;
32647117f1b4Smrg         redIndex = blueIndex = alphaIndex = -1;
32657117f1b4Smrg         stride = 1;
32667117f1b4Smrg         break;
32677117f1b4Smrg      case GL_BLUE:
32687117f1b4Smrg         blueIndex = 0;
32697117f1b4Smrg         redIndex = greenIndex = alphaIndex = -1;
32707117f1b4Smrg         stride = 1;
32717117f1b4Smrg         break;
32727117f1b4Smrg      case GL_ALPHA:
32737117f1b4Smrg         redIndex = greenIndex = blueIndex = -1;
32747117f1b4Smrg         alphaIndex = 0;
32757117f1b4Smrg         stride = 1;
32767117f1b4Smrg         break;
32777117f1b4Smrg      case GL_LUMINANCE:
32787117f1b4Smrg         redIndex = greenIndex = blueIndex = 0;
32797117f1b4Smrg         alphaIndex = -1;
32807117f1b4Smrg         stride = 1;
32817117f1b4Smrg         break;
32827117f1b4Smrg      case GL_LUMINANCE_ALPHA:
32837117f1b4Smrg         redIndex = greenIndex = blueIndex = 0;
32847117f1b4Smrg         alphaIndex = 1;
32857117f1b4Smrg         stride = 2;
32867117f1b4Smrg         break;
32877117f1b4Smrg      case GL_INTENSITY:
32887117f1b4Smrg         redIndex = greenIndex = blueIndex = alphaIndex = 0;
32897117f1b4Smrg         stride = 1;
32907117f1b4Smrg         break;
32917117f1b4Smrg      case GL_RGB:
32927117f1b4Smrg         redIndex = 0;
32937117f1b4Smrg         greenIndex = 1;
32947117f1b4Smrg         blueIndex = 2;
32957117f1b4Smrg         alphaIndex = -1;
32967117f1b4Smrg         rComp = 0;
32977117f1b4Smrg         gComp = 1;
32987117f1b4Smrg         bComp = 2;
32997117f1b4Smrg         aComp = 3;
33007117f1b4Smrg         stride = 3;
33017117f1b4Smrg         break;
33027117f1b4Smrg      case GL_BGR:
33037117f1b4Smrg         redIndex = 2;
33047117f1b4Smrg         greenIndex = 1;
33057117f1b4Smrg         blueIndex = 0;
33067117f1b4Smrg         alphaIndex = -1;
33077117f1b4Smrg         rComp = 2;
33087117f1b4Smrg         gComp = 1;
33097117f1b4Smrg         bComp = 0;
33107117f1b4Smrg         aComp = 3;
33117117f1b4Smrg         stride = 3;
33127117f1b4Smrg         break;
33137117f1b4Smrg      case GL_RGBA:
33147117f1b4Smrg         redIndex = 0;
33157117f1b4Smrg         greenIndex = 1;
33167117f1b4Smrg         blueIndex = 2;
33177117f1b4Smrg         alphaIndex = 3;
33187117f1b4Smrg         rComp = 0;
33197117f1b4Smrg         gComp = 1;
33207117f1b4Smrg         bComp = 2;
33217117f1b4Smrg         aComp = 3;
33227117f1b4Smrg         stride = 4;
33237117f1b4Smrg         break;
33247117f1b4Smrg      case GL_BGRA:
33257117f1b4Smrg         redIndex = 2;
33267117f1b4Smrg         greenIndex = 1;
33277117f1b4Smrg         blueIndex = 0;
33287117f1b4Smrg         alphaIndex = 3;
33297117f1b4Smrg         rComp = 2;
33307117f1b4Smrg         gComp = 1;
33317117f1b4Smrg         bComp = 0;
33327117f1b4Smrg         aComp = 3;
33337117f1b4Smrg         stride = 4;
33347117f1b4Smrg         break;
33357117f1b4Smrg      case GL_ABGR_EXT:
33367117f1b4Smrg         redIndex = 3;
33377117f1b4Smrg         greenIndex = 2;
33387117f1b4Smrg         blueIndex = 1;
33397117f1b4Smrg         alphaIndex = 0;
33407117f1b4Smrg         rComp = 3;
33417117f1b4Smrg         gComp = 2;
33427117f1b4Smrg         bComp = 1;
33437117f1b4Smrg         aComp = 0;
33447117f1b4Smrg         stride = 4;
33457117f1b4Smrg         break;
33464a49301eSmrg      case GL_DU8DV8_ATI:
33474a49301eSmrg      case GL_DUDV_ATI:
33484a49301eSmrg         redIndex = 0;
33494a49301eSmrg         greenIndex = 1;
33504a49301eSmrg         blueIndex = -1;
33514a49301eSmrg         alphaIndex = -1;
33524a49301eSmrg         stride = 2;
33534a49301eSmrg         break;
33547117f1b4Smrg      default:
33557117f1b4Smrg         _mesa_problem(NULL, "bad srcFormat in extract float data");
33567117f1b4Smrg         return;
33577117f1b4Smrg   }
33587117f1b4Smrg
33597117f1b4Smrg
33607117f1b4Smrg#define PROCESS(INDEX, CHANNEL, DEFAULT, TYPE, CONVERSION)		\
33617117f1b4Smrg   if ((INDEX) < 0) {							\
33627117f1b4Smrg      GLuint i;								\
33637117f1b4Smrg      for (i = 0; i < n; i++) {						\
33647117f1b4Smrg         rgba[i][CHANNEL] = DEFAULT;					\
33657117f1b4Smrg      }									\
33667117f1b4Smrg   }									\
33677117f1b4Smrg   else if (swapBytes) {						\
33687117f1b4Smrg      const TYPE *s = (const TYPE *) src;				\
33697117f1b4Smrg      GLuint i;								\
33707117f1b4Smrg      for (i = 0; i < n; i++) {						\
33717117f1b4Smrg         TYPE value = s[INDEX];						\
33727117f1b4Smrg         if (sizeof(TYPE) == 2) {					\
33737117f1b4Smrg            SWAP2BYTE(value);						\
33747117f1b4Smrg         }								\
33757117f1b4Smrg         else if (sizeof(TYPE) == 4) {					\
33767117f1b4Smrg            SWAP4BYTE(value);						\
33777117f1b4Smrg         }								\
33787117f1b4Smrg         rgba[i][CHANNEL] = (GLfloat) CONVERSION(value);		\
33797117f1b4Smrg         s += stride;							\
33807117f1b4Smrg      }									\
33817117f1b4Smrg   }									\
33827117f1b4Smrg   else {								\
33837117f1b4Smrg      const TYPE *s = (const TYPE *) src;				\
33847117f1b4Smrg      GLuint i;								\
33857117f1b4Smrg      for (i = 0; i < n; i++) {						\
33867117f1b4Smrg         rgba[i][CHANNEL] = (GLfloat) CONVERSION(s[INDEX]);		\
33877117f1b4Smrg         s += stride;							\
33887117f1b4Smrg      }									\
33897117f1b4Smrg   }
33907117f1b4Smrg
33917117f1b4Smrg   switch (srcType) {
33927117f1b4Smrg      case GL_UNSIGNED_BYTE:
33937117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
33947117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
33957117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
33967117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLubyte, UBYTE_TO_FLOAT);
33977117f1b4Smrg         break;
33987117f1b4Smrg      case GL_BYTE:
33997117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
34007117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
34017117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
34027117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLbyte, BYTE_TO_FLOAT);
34037117f1b4Smrg         break;
34047117f1b4Smrg      case GL_UNSIGNED_SHORT:
34057117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
34067117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
34077117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
34087117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLushort, USHORT_TO_FLOAT);
34097117f1b4Smrg         break;
34107117f1b4Smrg      case GL_SHORT:
34117117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
34127117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
34137117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
34147117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLshort, SHORT_TO_FLOAT);
34157117f1b4Smrg         break;
34167117f1b4Smrg      case GL_UNSIGNED_INT:
34177117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
34187117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
34197117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
34207117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLuint, UINT_TO_FLOAT);
34217117f1b4Smrg         break;
34227117f1b4Smrg      case GL_INT:
34237117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLint, INT_TO_FLOAT);
34247117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLint, INT_TO_FLOAT);
34257117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLint, INT_TO_FLOAT);
34267117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLint, INT_TO_FLOAT);
34277117f1b4Smrg         break;
34287117f1b4Smrg      case GL_FLOAT:
34297117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLfloat, (GLfloat));
34307117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLfloat, (GLfloat));
34317117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLfloat, (GLfloat));
34327117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLfloat, (GLfloat));
34337117f1b4Smrg         break;
34347117f1b4Smrg      case GL_HALF_FLOAT_ARB:
34357117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
34367117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
34377117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
34387117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLhalfARB, _mesa_half_to_float);
34397117f1b4Smrg         break;
34407117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
34417117f1b4Smrg         {
34427117f1b4Smrg            const GLubyte *ubsrc = (const GLubyte *) src;
34437117f1b4Smrg            GLuint i;
34447117f1b4Smrg            for (i = 0; i < n; i ++) {
34457117f1b4Smrg               GLubyte p = ubsrc[i];
34467117f1b4Smrg               rgba[i][rComp] = ((p >> 5)      ) * (1.0F / 7.0F);
34477117f1b4Smrg               rgba[i][gComp] = ((p >> 2) & 0x7) * (1.0F / 7.0F);
34487117f1b4Smrg               rgba[i][bComp] = ((p     ) & 0x3) * (1.0F / 3.0F);
34497117f1b4Smrg               rgba[i][aComp] = 1.0F;
34507117f1b4Smrg            }
34517117f1b4Smrg         }
34527117f1b4Smrg         break;
34537117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
34547117f1b4Smrg         {
34557117f1b4Smrg            const GLubyte *ubsrc = (const GLubyte *) src;
34567117f1b4Smrg            GLuint i;
34577117f1b4Smrg            for (i = 0; i < n; i ++) {
34587117f1b4Smrg               GLubyte p = ubsrc[i];
34597117f1b4Smrg               rgba[i][rComp] = ((p     ) & 0x7) * (1.0F / 7.0F);
34607117f1b4Smrg               rgba[i][gComp] = ((p >> 3) & 0x7) * (1.0F / 7.0F);
34617117f1b4Smrg               rgba[i][bComp] = ((p >> 6)      ) * (1.0F / 3.0F);
34627117f1b4Smrg               rgba[i][aComp] = 1.0F;
34637117f1b4Smrg            }
34647117f1b4Smrg         }
34657117f1b4Smrg         break;
34667117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
34677117f1b4Smrg         if (swapBytes) {
34687117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
34697117f1b4Smrg            GLuint i;
34707117f1b4Smrg            for (i = 0; i < n; i ++) {
34717117f1b4Smrg               GLushort p = ussrc[i];
34727117f1b4Smrg               SWAP2BYTE(p);
34737117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
34747117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
34757117f1b4Smrg               rgba[i][bComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
34767117f1b4Smrg               rgba[i][aComp] = 1.0F;
34777117f1b4Smrg            }
34787117f1b4Smrg         }
34797117f1b4Smrg         else {
34807117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
34817117f1b4Smrg            GLuint i;
34827117f1b4Smrg            for (i = 0; i < n; i ++) {
34837117f1b4Smrg               GLushort p = ussrc[i];
34847117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
34857117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
34867117f1b4Smrg               rgba[i][bComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
34877117f1b4Smrg               rgba[i][aComp] = 1.0F;
34887117f1b4Smrg            }
34897117f1b4Smrg         }
34907117f1b4Smrg         break;
34917117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
34927117f1b4Smrg         if (swapBytes) {
34937117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
34947117f1b4Smrg            GLuint i;
34957117f1b4Smrg            for (i = 0; i < n; i ++) {
34967117f1b4Smrg               GLushort p = ussrc[i];
34977117f1b4Smrg               SWAP2BYTE(p);
34987117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
34997117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
35007117f1b4Smrg               rgba[i][bComp] = ((p >> 11)       ) * (1.0F / 31.0F);
35017117f1b4Smrg               rgba[i][aComp] = 1.0F;
35027117f1b4Smrg            }
35037117f1b4Smrg         }
35047117f1b4Smrg         else {
35057117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35067117f1b4Smrg            GLuint i;
35077117f1b4Smrg            for (i = 0; i < n; i ++) {
35087117f1b4Smrg               GLushort p = ussrc[i];
35097117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
35107117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
35117117f1b4Smrg               rgba[i][bComp] = ((p >> 11)       ) * (1.0F / 31.0F);
35127117f1b4Smrg               rgba[i][aComp] = 1.0F;
35137117f1b4Smrg            }
35147117f1b4Smrg         }
35157117f1b4Smrg         break;
35167117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
35177117f1b4Smrg         if (swapBytes) {
35187117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35197117f1b4Smrg            GLuint i;
35207117f1b4Smrg            for (i = 0; i < n; i ++) {
35217117f1b4Smrg               GLushort p = ussrc[i];
35227117f1b4Smrg               SWAP2BYTE(p);
35237117f1b4Smrg               rgba[i][rComp] = ((p >> 12)      ) * (1.0F / 15.0F);
35247117f1b4Smrg               rgba[i][gComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
35257117f1b4Smrg               rgba[i][bComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
35267117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
35277117f1b4Smrg            }
35287117f1b4Smrg         }
35297117f1b4Smrg         else {
35307117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35317117f1b4Smrg            GLuint i;
35327117f1b4Smrg            for (i = 0; i < n; i ++) {
35337117f1b4Smrg               GLushort p = ussrc[i];
35347117f1b4Smrg               rgba[i][rComp] = ((p >> 12)      ) * (1.0F / 15.0F);
35357117f1b4Smrg               rgba[i][gComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
35367117f1b4Smrg               rgba[i][bComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
35377117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
35387117f1b4Smrg            }
35397117f1b4Smrg         }
35407117f1b4Smrg         break;
35417117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
35427117f1b4Smrg         if (swapBytes) {
35437117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35447117f1b4Smrg            GLuint i;
35457117f1b4Smrg            for (i = 0; i < n; i ++) {
35467117f1b4Smrg               GLushort p = ussrc[i];
35477117f1b4Smrg               SWAP2BYTE(p);
35487117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
35497117f1b4Smrg               rgba[i][gComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
35507117f1b4Smrg               rgba[i][bComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
35517117f1b4Smrg               rgba[i][aComp] = ((p >> 12)      ) * (1.0F / 15.0F);
35527117f1b4Smrg            }
35537117f1b4Smrg         }
35547117f1b4Smrg         else {
35557117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35567117f1b4Smrg            GLuint i;
35577117f1b4Smrg            for (i = 0; i < n; i ++) {
35587117f1b4Smrg               GLushort p = ussrc[i];
35597117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
35607117f1b4Smrg               rgba[i][gComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
35617117f1b4Smrg               rgba[i][bComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
35627117f1b4Smrg               rgba[i][aComp] = ((p >> 12)      ) * (1.0F / 15.0F);
35637117f1b4Smrg            }
35647117f1b4Smrg         }
35657117f1b4Smrg         break;
35667117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
35677117f1b4Smrg         if (swapBytes) {
35687117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35697117f1b4Smrg            GLuint i;
35707117f1b4Smrg            for (i = 0; i < n; i ++) {
35717117f1b4Smrg               GLushort p = ussrc[i];
35727117f1b4Smrg               SWAP2BYTE(p);
35737117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
35747117f1b4Smrg               rgba[i][gComp] = ((p >>  6) & 0x1f) * (1.0F / 31.0F);
35757117f1b4Smrg               rgba[i][bComp] = ((p >>  1) & 0x1f) * (1.0F / 31.0F);
35767117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x1)  * (1.0F /  1.0F);
35777117f1b4Smrg            }
35787117f1b4Smrg         }
35797117f1b4Smrg         else {
35807117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35817117f1b4Smrg            GLuint i;
35827117f1b4Smrg            for (i = 0; i < n; i ++) {
35837117f1b4Smrg               GLushort p = ussrc[i];
35847117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
35857117f1b4Smrg               rgba[i][gComp] = ((p >>  6) & 0x1f) * (1.0F / 31.0F);
35867117f1b4Smrg               rgba[i][bComp] = ((p >>  1) & 0x1f) * (1.0F / 31.0F);
35877117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x1)  * (1.0F /  1.0F);
35887117f1b4Smrg            }
35897117f1b4Smrg         }
35907117f1b4Smrg         break;
35917117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
35927117f1b4Smrg         if (swapBytes) {
35937117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
35947117f1b4Smrg            GLuint i;
35957117f1b4Smrg            for (i = 0; i < n; i ++) {
35967117f1b4Smrg               GLushort p = ussrc[i];
35977117f1b4Smrg               SWAP2BYTE(p);
35987117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
35997117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x1f) * (1.0F / 31.0F);
36007117f1b4Smrg               rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
36017117f1b4Smrg               rgba[i][aComp] = ((p >> 15)       ) * (1.0F /  1.0F);
36027117f1b4Smrg            }
36037117f1b4Smrg         }
36047117f1b4Smrg         else {
36057117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
36067117f1b4Smrg            GLuint i;
36077117f1b4Smrg            for (i = 0; i < n; i ++) {
36087117f1b4Smrg               GLushort p = ussrc[i];
36097117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
36107117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x1f) * (1.0F / 31.0F);
36117117f1b4Smrg               rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
36127117f1b4Smrg               rgba[i][aComp] = ((p >> 15)       ) * (1.0F /  1.0F);
36137117f1b4Smrg            }
36147117f1b4Smrg         }
36157117f1b4Smrg         break;
36167117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
36177117f1b4Smrg         if (swapBytes) {
36187117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36197117f1b4Smrg            GLuint i;
36207117f1b4Smrg            for (i = 0; i < n; i ++) {
36217117f1b4Smrg               GLuint p = uisrc[i];
36227117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
36237117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
36247117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
36257117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
36267117f1b4Smrg            }
36277117f1b4Smrg         }
36287117f1b4Smrg         else {
36297117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36307117f1b4Smrg            GLuint i;
36317117f1b4Smrg            for (i = 0; i < n; i ++) {
36327117f1b4Smrg               GLuint p = uisrc[i];
36337117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
36347117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
36357117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
36367117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
36377117f1b4Smrg            }
36387117f1b4Smrg         }
36397117f1b4Smrg         break;
36407117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
36417117f1b4Smrg         if (swapBytes) {
36427117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36437117f1b4Smrg            GLuint i;
36447117f1b4Smrg            for (i = 0; i < n; i ++) {
36457117f1b4Smrg               GLuint p = uisrc[i];
36467117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
36477117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
36487117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
36497117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
36507117f1b4Smrg            }
36517117f1b4Smrg         }
36527117f1b4Smrg         else {
36537117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36547117f1b4Smrg            GLuint i;
36557117f1b4Smrg            for (i = 0; i < n; i ++) {
36567117f1b4Smrg               GLuint p = uisrc[i];
36577117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
36587117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
36597117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
36607117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
36617117f1b4Smrg            }
36627117f1b4Smrg         }
36637117f1b4Smrg         break;
36647117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
36657117f1b4Smrg         if (swapBytes) {
36667117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36677117f1b4Smrg            GLuint i;
36687117f1b4Smrg            for (i = 0; i < n; i ++) {
36697117f1b4Smrg               GLuint p = uisrc[i];
36707117f1b4Smrg               SWAP4BYTE(p);
36717117f1b4Smrg               rgba[i][rComp] = ((p >> 22)        ) * (1.0F / 1023.0F);
36727117f1b4Smrg               rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
36737117f1b4Smrg               rgba[i][bComp] = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F);
36747117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x3  ) * (1.0F /    3.0F);
36757117f1b4Smrg            }
36767117f1b4Smrg         }
36777117f1b4Smrg         else {
36787117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36797117f1b4Smrg            GLuint i;
36807117f1b4Smrg            for (i = 0; i < n; i ++) {
36817117f1b4Smrg               GLuint p = uisrc[i];
36827117f1b4Smrg               rgba[i][rComp] = ((p >> 22)        ) * (1.0F / 1023.0F);
36837117f1b4Smrg               rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
36847117f1b4Smrg               rgba[i][bComp] = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F);
36857117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x3  ) * (1.0F /    3.0F);
36867117f1b4Smrg            }
36877117f1b4Smrg         }
36887117f1b4Smrg         break;
36897117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
36907117f1b4Smrg         if (swapBytes) {
36917117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
36927117f1b4Smrg            GLuint i;
36937117f1b4Smrg            for (i = 0; i < n; i ++) {
36947117f1b4Smrg               GLuint p = uisrc[i];
36957117f1b4Smrg               SWAP4BYTE(p);
36967117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x3ff) * (1.0F / 1023.0F);
36977117f1b4Smrg               rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
36987117f1b4Smrg               rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
36997117f1b4Smrg               rgba[i][aComp] = ((p >> 30)        ) * (1.0F /    3.0F);
37007117f1b4Smrg            }
37017117f1b4Smrg         }
37027117f1b4Smrg         else {
37037117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
37047117f1b4Smrg            GLuint i;
37057117f1b4Smrg            for (i = 0; i < n; i ++) {
37067117f1b4Smrg               GLuint p = uisrc[i];
37077117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x3ff) * (1.0F / 1023.0F);
37087117f1b4Smrg               rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
37097117f1b4Smrg               rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
37107117f1b4Smrg               rgba[i][aComp] = ((p >> 30)        ) * (1.0F /    3.0F);
37117117f1b4Smrg            }
37127117f1b4Smrg         }
37137117f1b4Smrg         break;
37147117f1b4Smrg      default:
37157117f1b4Smrg         _mesa_problem(NULL, "bad srcType in extract float data");
37167117f1b4Smrg         break;
37177117f1b4Smrg   }
37187117f1b4Smrg}
37197117f1b4Smrg
37207117f1b4Smrg
37217117f1b4Smrg/*
37227117f1b4Smrg * Unpack a row of color image data from a client buffer according to
37237117f1b4Smrg * the pixel unpacking parameters.
37247117f1b4Smrg * Return GLchan values in the specified dest image format.
37257117f1b4Smrg * This is used by glDrawPixels and glTexImage?D().
37267117f1b4Smrg * \param ctx - the context
37277117f1b4Smrg *         n - number of pixels in the span
37287117f1b4Smrg *         dstFormat - format of destination color array
37297117f1b4Smrg *         dest - the destination color array
37307117f1b4Smrg *         srcFormat - source image format
37317117f1b4Smrg *         srcType - source image  data type
37327117f1b4Smrg *         source - source image pointer
37337117f1b4Smrg *         srcPacking - pixel unpacking parameters
37347117f1b4Smrg *         transferOps - bitmask of IMAGE_*_BIT values of operations to apply
37357117f1b4Smrg *
37367117f1b4Smrg * XXX perhaps expand this to process whole images someday.
37377117f1b4Smrg */
37387117f1b4Smrgvoid
37397117f1b4Smrg_mesa_unpack_color_span_chan( GLcontext *ctx,
37407117f1b4Smrg                              GLuint n, GLenum dstFormat, GLchan dest[],
37417117f1b4Smrg                              GLenum srcFormat, GLenum srcType,
37427117f1b4Smrg                              const GLvoid *source,
37437117f1b4Smrg                              const struct gl_pixelstore_attrib *srcPacking,
37447117f1b4Smrg                              GLbitfield transferOps )
37457117f1b4Smrg{
37467117f1b4Smrg   ASSERT(dstFormat == GL_ALPHA ||
37477117f1b4Smrg          dstFormat == GL_LUMINANCE ||
37487117f1b4Smrg          dstFormat == GL_LUMINANCE_ALPHA ||
37497117f1b4Smrg          dstFormat == GL_INTENSITY ||
37507117f1b4Smrg          dstFormat == GL_RGB ||
37517117f1b4Smrg          dstFormat == GL_RGBA ||
37527117f1b4Smrg          dstFormat == GL_COLOR_INDEX);
37537117f1b4Smrg
37547117f1b4Smrg   ASSERT(srcFormat == GL_RED ||
37557117f1b4Smrg          srcFormat == GL_GREEN ||
37567117f1b4Smrg          srcFormat == GL_BLUE ||
37577117f1b4Smrg          srcFormat == GL_ALPHA ||
37587117f1b4Smrg          srcFormat == GL_LUMINANCE ||
37597117f1b4Smrg          srcFormat == GL_LUMINANCE_ALPHA ||
37607117f1b4Smrg          srcFormat == GL_INTENSITY ||
37617117f1b4Smrg          srcFormat == GL_RGB ||
37627117f1b4Smrg          srcFormat == GL_BGR ||
37637117f1b4Smrg          srcFormat == GL_RGBA ||
37647117f1b4Smrg          srcFormat == GL_BGRA ||
37657117f1b4Smrg          srcFormat == GL_ABGR_EXT ||
37667117f1b4Smrg          srcFormat == GL_COLOR_INDEX);
37677117f1b4Smrg
37687117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
37697117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
37707117f1b4Smrg          srcType == GL_BYTE ||
37717117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
37727117f1b4Smrg          srcType == GL_SHORT ||
37737117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
37747117f1b4Smrg          srcType == GL_INT ||
37757117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
37767117f1b4Smrg          srcType == GL_FLOAT ||
37777117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_3_3_2 ||
37787117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
37797117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5 ||
37807117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
37817117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
37827117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
37837117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
37847117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
37857117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
37867117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
37877117f1b4Smrg          srcType == GL_UNSIGNED_INT_10_10_10_2 ||
37887117f1b4Smrg          srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
37897117f1b4Smrg
37907117f1b4Smrg   /* Try simple cases first */
37917117f1b4Smrg   if (transferOps == 0) {
37927117f1b4Smrg      if (srcType == CHAN_TYPE) {
37937117f1b4Smrg         if (dstFormat == GL_RGBA) {
37947117f1b4Smrg            if (srcFormat == GL_RGBA) {
37957117f1b4Smrg               _mesa_memcpy( dest, source, n * 4 * sizeof(GLchan) );
37967117f1b4Smrg               return;
37977117f1b4Smrg            }
37987117f1b4Smrg            else if (srcFormat == GL_RGB) {
37997117f1b4Smrg               GLuint i;
38007117f1b4Smrg               const GLchan *src = (const GLchan *) source;
38017117f1b4Smrg               GLchan *dst = dest;
38027117f1b4Smrg               for (i = 0; i < n; i++) {
38037117f1b4Smrg                  dst[0] = src[0];
38047117f1b4Smrg                  dst[1] = src[1];
38057117f1b4Smrg                  dst[2] = src[2];
38067117f1b4Smrg                  dst[3] = CHAN_MAX;
38077117f1b4Smrg                  src += 3;
38087117f1b4Smrg                  dst += 4;
38097117f1b4Smrg               }
38107117f1b4Smrg               return;
38117117f1b4Smrg            }
38127117f1b4Smrg         }
38137117f1b4Smrg         else if (dstFormat == GL_RGB) {
38147117f1b4Smrg            if (srcFormat == GL_RGB) {
38157117f1b4Smrg               _mesa_memcpy( dest, source, n * 3 * sizeof(GLchan) );
38167117f1b4Smrg               return;
38177117f1b4Smrg            }
38187117f1b4Smrg            else if (srcFormat == GL_RGBA) {
38197117f1b4Smrg               GLuint i;
38207117f1b4Smrg               const GLchan *src = (const GLchan *) source;
38217117f1b4Smrg               GLchan *dst = dest;
38227117f1b4Smrg               for (i = 0; i < n; i++) {
38237117f1b4Smrg                  dst[0] = src[0];
38247117f1b4Smrg                  dst[1] = src[1];
38257117f1b4Smrg                  dst[2] = src[2];
38267117f1b4Smrg                  src += 4;
38277117f1b4Smrg                  dst += 3;
38287117f1b4Smrg               }
38297117f1b4Smrg               return;
38307117f1b4Smrg            }
38317117f1b4Smrg         }
38327117f1b4Smrg         else if (dstFormat == srcFormat) {
38337117f1b4Smrg            GLint comps = _mesa_components_in_format(srcFormat);
38347117f1b4Smrg            assert(comps > 0);
38357117f1b4Smrg            _mesa_memcpy( dest, source, n * comps * sizeof(GLchan) );
38367117f1b4Smrg            return;
38377117f1b4Smrg         }
38387117f1b4Smrg      }
38397117f1b4Smrg      /*
38407117f1b4Smrg       * Common situation, loading 8bit RGBA/RGB source images
38417117f1b4Smrg       * into 16/32 bit destination. (OSMesa16/32)
38427117f1b4Smrg       */
38437117f1b4Smrg      else if (srcType == GL_UNSIGNED_BYTE) {
38447117f1b4Smrg         if (dstFormat == GL_RGBA) {
38457117f1b4Smrg            if (srcFormat == GL_RGB) {
38467117f1b4Smrg               GLuint i;
38477117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
38487117f1b4Smrg               GLchan *dst = dest;
38497117f1b4Smrg               for (i = 0; i < n; i++) {
38507117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
38517117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
38527117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
38537117f1b4Smrg                  dst[3] = CHAN_MAX;
38547117f1b4Smrg                  src += 3;
38557117f1b4Smrg                  dst += 4;
38567117f1b4Smrg               }
38577117f1b4Smrg               return;
38587117f1b4Smrg            }
38597117f1b4Smrg            else if (srcFormat == GL_RGBA) {
38607117f1b4Smrg               GLuint i;
38617117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
38627117f1b4Smrg               GLchan *dst = dest;
38637117f1b4Smrg               for (i = 0; i < n; i++) {
38647117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
38657117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
38667117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
38677117f1b4Smrg                  dst[3] = UBYTE_TO_CHAN(src[3]);
38687117f1b4Smrg                  src += 4;
38697117f1b4Smrg                  dst += 4;
38707117f1b4Smrg               }
38717117f1b4Smrg               return;
38727117f1b4Smrg             }
38737117f1b4Smrg         }
38747117f1b4Smrg         else if (dstFormat == GL_RGB) {
38757117f1b4Smrg            if (srcFormat == GL_RGB) {
38767117f1b4Smrg               GLuint i;
38777117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
38787117f1b4Smrg               GLchan *dst = dest;
38797117f1b4Smrg               for (i = 0; i < n; i++) {
38807117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
38817117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
38827117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
38837117f1b4Smrg                  src += 3;
38847117f1b4Smrg                  dst += 3;
38857117f1b4Smrg               }
38867117f1b4Smrg               return;
38877117f1b4Smrg            }
38887117f1b4Smrg            else if (srcFormat == GL_RGBA) {
38897117f1b4Smrg               GLuint i;
38907117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
38917117f1b4Smrg               GLchan *dst = dest;
38927117f1b4Smrg               for (i = 0; i < n; i++) {
38937117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
38947117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
38957117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
38967117f1b4Smrg                  src += 4;
38977117f1b4Smrg                  dst += 3;
38987117f1b4Smrg               }
38997117f1b4Smrg               return;
39007117f1b4Smrg            }
39017117f1b4Smrg         }
39027117f1b4Smrg      }
39037117f1b4Smrg   }
39047117f1b4Smrg
39057117f1b4Smrg
39067117f1b4Smrg   /* general solution begins here */
39077117f1b4Smrg   {
39087117f1b4Smrg      GLint dstComponents;
39097117f1b4Smrg      GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex;
39107117f1b4Smrg      GLint dstLuminanceIndex, dstIntensityIndex;
39117117f1b4Smrg      GLfloat rgba[MAX_WIDTH][4];
39127117f1b4Smrg
39137117f1b4Smrg      dstComponents = _mesa_components_in_format( dstFormat );
39147117f1b4Smrg      /* source & dest image formats should have been error checked by now */
39157117f1b4Smrg      assert(dstComponents > 0);
39167117f1b4Smrg
39177117f1b4Smrg      /*
39187117f1b4Smrg       * Extract image data and convert to RGBA floats
39197117f1b4Smrg       */
39207117f1b4Smrg      assert(n <= MAX_WIDTH);
39217117f1b4Smrg      if (srcFormat == GL_COLOR_INDEX) {
39227117f1b4Smrg         GLuint indexes[MAX_WIDTH];
39237117f1b4Smrg         extract_uint_indexes(n, indexes, srcFormat, srcType, source,
39247117f1b4Smrg                              srcPacking);
39257117f1b4Smrg
39267117f1b4Smrg         if (dstFormat == GL_COLOR_INDEX) {
39277117f1b4Smrg            GLuint i;
39287117f1b4Smrg            _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
39297117f1b4Smrg            /* convert to GLchan and return */
39307117f1b4Smrg            for (i = 0; i < n; i++) {
39317117f1b4Smrg               dest[i] = (GLchan) (indexes[i] & 0xff);
39327117f1b4Smrg            }
39337117f1b4Smrg            return;
39347117f1b4Smrg         }
39357117f1b4Smrg         else {
39367117f1b4Smrg            /* Convert indexes to RGBA */
39377117f1b4Smrg            if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
39387117f1b4Smrg               shift_and_offset_ci(ctx, n, indexes);
39397117f1b4Smrg            }
39407117f1b4Smrg            _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
39417117f1b4Smrg         }
39427117f1b4Smrg
39437117f1b4Smrg         /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
39447117f1b4Smrg          * with color indexes.
39457117f1b4Smrg          */
39467117f1b4Smrg         transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
39477117f1b4Smrg      }
39487117f1b4Smrg      else {
39497117f1b4Smrg         /* non-color index data */
39507117f1b4Smrg         extract_float_rgba(n, rgba, srcFormat, srcType, source,
39517117f1b4Smrg                            srcPacking->SwapBytes);
39527117f1b4Smrg      }
39537117f1b4Smrg
39547117f1b4Smrg      /* Need to clamp if returning GLubytes or GLushorts */
39557117f1b4Smrg#if CHAN_TYPE != GL_FLOAT
39567117f1b4Smrg      transferOps |= IMAGE_CLAMP_BIT;
39577117f1b4Smrg#endif
39587117f1b4Smrg
39597117f1b4Smrg      if (transferOps) {
39607117f1b4Smrg         _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
39617117f1b4Smrg      }
39627117f1b4Smrg
39637117f1b4Smrg      /* Now determine which color channels we need to produce.
39647117f1b4Smrg       * And determine the dest index (offset) within each color tuple.
39657117f1b4Smrg       */
39667117f1b4Smrg      switch (dstFormat) {
39677117f1b4Smrg         case GL_ALPHA:
39687117f1b4Smrg            dstAlphaIndex = 0;
39697117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
39707117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
39717117f1b4Smrg            break;
39727117f1b4Smrg         case GL_LUMINANCE:
39737117f1b4Smrg            dstLuminanceIndex = 0;
39747117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
39757117f1b4Smrg            dstIntensityIndex = -1;
39767117f1b4Smrg            break;
39777117f1b4Smrg         case GL_LUMINANCE_ALPHA:
39787117f1b4Smrg            dstLuminanceIndex = 0;
39797117f1b4Smrg            dstAlphaIndex = 1;
39807117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
39817117f1b4Smrg            dstIntensityIndex = -1;
39827117f1b4Smrg            break;
39837117f1b4Smrg         case GL_INTENSITY:
39847117f1b4Smrg            dstIntensityIndex = 0;
39857117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
39867117f1b4Smrg            dstLuminanceIndex = -1;
39877117f1b4Smrg            break;
39887117f1b4Smrg         case GL_RGB:
39897117f1b4Smrg            dstRedIndex = 0;
39907117f1b4Smrg            dstGreenIndex = 1;
39917117f1b4Smrg            dstBlueIndex = 2;
39927117f1b4Smrg            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
39937117f1b4Smrg            break;
39947117f1b4Smrg         case GL_RGBA:
39957117f1b4Smrg            dstRedIndex = 0;
39967117f1b4Smrg            dstGreenIndex = 1;
39977117f1b4Smrg            dstBlueIndex = 2;
39987117f1b4Smrg            dstAlphaIndex = 3;
39997117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
40007117f1b4Smrg            break;
40017117f1b4Smrg         default:
40027117f1b4Smrg            _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_chan_span()");
40037117f1b4Smrg            return;
40047117f1b4Smrg      }
40057117f1b4Smrg
40067117f1b4Smrg
40077117f1b4Smrg      /* Now return the GLchan data in the requested dstFormat */
40087117f1b4Smrg
40097117f1b4Smrg      if (dstRedIndex >= 0) {
40107117f1b4Smrg         GLchan *dst = dest;
40117117f1b4Smrg         GLuint i;
40127117f1b4Smrg         for (i = 0; i < n; i++) {
40137117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstRedIndex], rgba[i][RCOMP]);
40147117f1b4Smrg            dst += dstComponents;
40157117f1b4Smrg         }
40167117f1b4Smrg      }
40177117f1b4Smrg
40187117f1b4Smrg      if (dstGreenIndex >= 0) {
40197117f1b4Smrg         GLchan *dst = dest;
40207117f1b4Smrg         GLuint i;
40217117f1b4Smrg         for (i = 0; i < n; i++) {
40227117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstGreenIndex], rgba[i][GCOMP]);
40237117f1b4Smrg            dst += dstComponents;
40247117f1b4Smrg         }
40257117f1b4Smrg      }
40267117f1b4Smrg
40277117f1b4Smrg      if (dstBlueIndex >= 0) {
40287117f1b4Smrg         GLchan *dst = dest;
40297117f1b4Smrg         GLuint i;
40307117f1b4Smrg         for (i = 0; i < n; i++) {
40317117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstBlueIndex], rgba[i][BCOMP]);
40327117f1b4Smrg            dst += dstComponents;
40337117f1b4Smrg         }
40347117f1b4Smrg      }
40357117f1b4Smrg
40367117f1b4Smrg      if (dstAlphaIndex >= 0) {
40377117f1b4Smrg         GLchan *dst = dest;
40387117f1b4Smrg         GLuint i;
40397117f1b4Smrg         for (i = 0; i < n; i++) {
40407117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstAlphaIndex], rgba[i][ACOMP]);
40417117f1b4Smrg            dst += dstComponents;
40427117f1b4Smrg         }
40437117f1b4Smrg      }
40447117f1b4Smrg
40457117f1b4Smrg      if (dstIntensityIndex >= 0) {
40467117f1b4Smrg         GLchan *dst = dest;
40477117f1b4Smrg         GLuint i;
40487117f1b4Smrg         assert(dstIntensityIndex == 0);
40497117f1b4Smrg         assert(dstComponents == 1);
40507117f1b4Smrg         for (i = 0; i < n; i++) {
40517117f1b4Smrg            /* Intensity comes from red channel */
40527117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[i], rgba[i][RCOMP]);
40537117f1b4Smrg         }
40547117f1b4Smrg      }
40557117f1b4Smrg
40567117f1b4Smrg      if (dstLuminanceIndex >= 0) {
40577117f1b4Smrg         GLchan *dst = dest;
40587117f1b4Smrg         GLuint i;
40597117f1b4Smrg         assert(dstLuminanceIndex == 0);
40607117f1b4Smrg         for (i = 0; i < n; i++) {
40617117f1b4Smrg            /* Luminance comes from red channel */
40627117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[0], rgba[i][RCOMP]);
40637117f1b4Smrg            dst += dstComponents;
40647117f1b4Smrg         }
40657117f1b4Smrg      }
40667117f1b4Smrg   }
40677117f1b4Smrg}
40687117f1b4Smrg
40697117f1b4Smrg
40707117f1b4Smrg/**
40717117f1b4Smrg * Same as _mesa_unpack_color_span_chan(), but return GLfloat data
40727117f1b4Smrg * instead of GLchan.
40737117f1b4Smrg */
40747117f1b4Smrgvoid
40757117f1b4Smrg_mesa_unpack_color_span_float( GLcontext *ctx,
40767117f1b4Smrg                               GLuint n, GLenum dstFormat, GLfloat dest[],
40777117f1b4Smrg                               GLenum srcFormat, GLenum srcType,
40787117f1b4Smrg                               const GLvoid *source,
40797117f1b4Smrg                               const struct gl_pixelstore_attrib *srcPacking,
40807117f1b4Smrg                               GLbitfield transferOps )
40817117f1b4Smrg{
40827117f1b4Smrg   ASSERT(dstFormat == GL_ALPHA ||
40837117f1b4Smrg          dstFormat == GL_LUMINANCE ||
40847117f1b4Smrg          dstFormat == GL_LUMINANCE_ALPHA ||
40857117f1b4Smrg          dstFormat == GL_INTENSITY ||
40867117f1b4Smrg          dstFormat == GL_RGB ||
40877117f1b4Smrg          dstFormat == GL_RGBA ||
40887117f1b4Smrg          dstFormat == GL_COLOR_INDEX);
40897117f1b4Smrg
40907117f1b4Smrg   ASSERT(srcFormat == GL_RED ||
40917117f1b4Smrg          srcFormat == GL_GREEN ||
40927117f1b4Smrg          srcFormat == GL_BLUE ||
40937117f1b4Smrg          srcFormat == GL_ALPHA ||
40947117f1b4Smrg          srcFormat == GL_LUMINANCE ||
40957117f1b4Smrg          srcFormat == GL_LUMINANCE_ALPHA ||
40967117f1b4Smrg          srcFormat == GL_INTENSITY ||
40977117f1b4Smrg          srcFormat == GL_RGB ||
40987117f1b4Smrg          srcFormat == GL_BGR ||
40997117f1b4Smrg          srcFormat == GL_RGBA ||
41007117f1b4Smrg          srcFormat == GL_BGRA ||
41017117f1b4Smrg          srcFormat == GL_ABGR_EXT ||
41027117f1b4Smrg          srcFormat == GL_COLOR_INDEX);
41037117f1b4Smrg
41047117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
41057117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
41067117f1b4Smrg          srcType == GL_BYTE ||
41077117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
41087117f1b4Smrg          srcType == GL_SHORT ||
41097117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
41107117f1b4Smrg          srcType == GL_INT ||
41117117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
41127117f1b4Smrg          srcType == GL_FLOAT ||
41137117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_3_3_2 ||
41147117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
41157117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5 ||
41167117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
41177117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
41187117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
41197117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
41207117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
41217117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
41227117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
41237117f1b4Smrg          srcType == GL_UNSIGNED_INT_10_10_10_2 ||
41247117f1b4Smrg          srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
41257117f1b4Smrg
41267117f1b4Smrg   /* general solution, no special cases, yet */
41277117f1b4Smrg   {
41287117f1b4Smrg      GLint dstComponents;
41297117f1b4Smrg      GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex;
41307117f1b4Smrg      GLint dstLuminanceIndex, dstIntensityIndex;
41317117f1b4Smrg      GLfloat rgba[MAX_WIDTH][4];
41327117f1b4Smrg
41337117f1b4Smrg      dstComponents = _mesa_components_in_format( dstFormat );
41347117f1b4Smrg      /* source & dest image formats should have been error checked by now */
41357117f1b4Smrg      assert(dstComponents > 0);
41367117f1b4Smrg
41377117f1b4Smrg      /*
41387117f1b4Smrg       * Extract image data and convert to RGBA floats
41397117f1b4Smrg       */
41407117f1b4Smrg      assert(n <= MAX_WIDTH);
41417117f1b4Smrg      if (srcFormat == GL_COLOR_INDEX) {
41427117f1b4Smrg         GLuint indexes[MAX_WIDTH];
41437117f1b4Smrg         extract_uint_indexes(n, indexes, srcFormat, srcType, source,
41447117f1b4Smrg                              srcPacking);
41457117f1b4Smrg
41467117f1b4Smrg         if (dstFormat == GL_COLOR_INDEX) {
41477117f1b4Smrg            GLuint i;
41487117f1b4Smrg            _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
41497117f1b4Smrg            /* convert to GLchan and return */
41507117f1b4Smrg            for (i = 0; i < n; i++) {
41517117f1b4Smrg               dest[i] = (GLchan) (indexes[i] & 0xff);
41527117f1b4Smrg            }
41537117f1b4Smrg            return;
41547117f1b4Smrg         }
41557117f1b4Smrg         else {
41567117f1b4Smrg            /* Convert indexes to RGBA */
41577117f1b4Smrg            if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
41587117f1b4Smrg               shift_and_offset_ci(ctx, n, indexes);
41597117f1b4Smrg            }
41607117f1b4Smrg            _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
41617117f1b4Smrg         }
41627117f1b4Smrg
41637117f1b4Smrg         /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
41647117f1b4Smrg          * with color indexes.
41657117f1b4Smrg          */
41667117f1b4Smrg         transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
41677117f1b4Smrg      }
41687117f1b4Smrg      else {
41697117f1b4Smrg         /* non-color index data */
41707117f1b4Smrg         extract_float_rgba(n, rgba, srcFormat, srcType, source,
41717117f1b4Smrg                            srcPacking->SwapBytes);
41727117f1b4Smrg      }
41737117f1b4Smrg
41747117f1b4Smrg      if (transferOps) {
41757117f1b4Smrg         _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
41767117f1b4Smrg      }
41777117f1b4Smrg
41787117f1b4Smrg      /* Now determine which color channels we need to produce.
41797117f1b4Smrg       * And determine the dest index (offset) within each color tuple.
41807117f1b4Smrg       */
41817117f1b4Smrg      switch (dstFormat) {
41827117f1b4Smrg         case GL_ALPHA:
41837117f1b4Smrg            dstAlphaIndex = 0;
41847117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
41857117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
41867117f1b4Smrg            break;
41877117f1b4Smrg         case GL_LUMINANCE:
41887117f1b4Smrg            dstLuminanceIndex = 0;
41897117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
41907117f1b4Smrg            dstIntensityIndex = -1;
41917117f1b4Smrg            break;
41927117f1b4Smrg         case GL_LUMINANCE_ALPHA:
41937117f1b4Smrg            dstLuminanceIndex = 0;
41947117f1b4Smrg            dstAlphaIndex = 1;
41957117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
41967117f1b4Smrg            dstIntensityIndex = -1;
41977117f1b4Smrg            break;
41987117f1b4Smrg         case GL_INTENSITY:
41997117f1b4Smrg            dstIntensityIndex = 0;
42007117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
42017117f1b4Smrg            dstLuminanceIndex = -1;
42027117f1b4Smrg            break;
42037117f1b4Smrg         case GL_RGB:
42047117f1b4Smrg            dstRedIndex = 0;
42057117f1b4Smrg            dstGreenIndex = 1;
42067117f1b4Smrg            dstBlueIndex = 2;
42077117f1b4Smrg            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
42087117f1b4Smrg            break;
42097117f1b4Smrg         case GL_RGBA:
42107117f1b4Smrg            dstRedIndex = 0;
42117117f1b4Smrg            dstGreenIndex = 1;
42127117f1b4Smrg            dstBlueIndex = 2;
42137117f1b4Smrg            dstAlphaIndex = 3;
42147117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
42157117f1b4Smrg            break;
42167117f1b4Smrg         default:
42177117f1b4Smrg            _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_color_span_float()");
42187117f1b4Smrg            return;
42197117f1b4Smrg      }
42207117f1b4Smrg
42217117f1b4Smrg      /* Now pack results in the requested dstFormat */
42227117f1b4Smrg      if (dstRedIndex >= 0) {
42237117f1b4Smrg         GLfloat *dst = dest;
42247117f1b4Smrg         GLuint i;
42257117f1b4Smrg         for (i = 0; i < n; i++) {
42267117f1b4Smrg            dst[dstRedIndex] = rgba[i][RCOMP];
42277117f1b4Smrg            dst += dstComponents;
42287117f1b4Smrg         }
42297117f1b4Smrg      }
42307117f1b4Smrg
42317117f1b4Smrg      if (dstGreenIndex >= 0) {
42327117f1b4Smrg         GLfloat *dst = dest;
42337117f1b4Smrg         GLuint i;
42347117f1b4Smrg         for (i = 0; i < n; i++) {
42357117f1b4Smrg            dst[dstGreenIndex] = rgba[i][GCOMP];
42367117f1b4Smrg            dst += dstComponents;
42377117f1b4Smrg         }
42387117f1b4Smrg      }
42397117f1b4Smrg
42407117f1b4Smrg      if (dstBlueIndex >= 0) {
42417117f1b4Smrg         GLfloat *dst = dest;
42427117f1b4Smrg         GLuint i;
42437117f1b4Smrg         for (i = 0; i < n; i++) {
42447117f1b4Smrg            dst[dstBlueIndex] = rgba[i][BCOMP];
42457117f1b4Smrg            dst += dstComponents;
42467117f1b4Smrg         }
42477117f1b4Smrg      }
42487117f1b4Smrg
42497117f1b4Smrg      if (dstAlphaIndex >= 0) {
42507117f1b4Smrg         GLfloat *dst = dest;
42517117f1b4Smrg         GLuint i;
42527117f1b4Smrg         for (i = 0; i < n; i++) {
42537117f1b4Smrg            dst[dstAlphaIndex] = rgba[i][ACOMP];
42547117f1b4Smrg            dst += dstComponents;
42557117f1b4Smrg         }
42567117f1b4Smrg      }
42577117f1b4Smrg
42587117f1b4Smrg      if (dstIntensityIndex >= 0) {
42597117f1b4Smrg         GLfloat *dst = dest;
42607117f1b4Smrg         GLuint i;
42617117f1b4Smrg         assert(dstIntensityIndex == 0);
42627117f1b4Smrg         assert(dstComponents == 1);
42637117f1b4Smrg         for (i = 0; i < n; i++) {
42647117f1b4Smrg            /* Intensity comes from red channel */
42657117f1b4Smrg            dst[i] = rgba[i][RCOMP];
42667117f1b4Smrg         }
42677117f1b4Smrg      }
42687117f1b4Smrg
42697117f1b4Smrg      if (dstLuminanceIndex >= 0) {
42707117f1b4Smrg         GLfloat *dst = dest;
42717117f1b4Smrg         GLuint i;
42727117f1b4Smrg         assert(dstLuminanceIndex == 0);
42737117f1b4Smrg         for (i = 0; i < n; i++) {
42747117f1b4Smrg            /* Luminance comes from red channel */
42757117f1b4Smrg            dst[0] = rgba[i][RCOMP];
42767117f1b4Smrg            dst += dstComponents;
42777117f1b4Smrg         }
42787117f1b4Smrg      }
42797117f1b4Smrg   }
42807117f1b4Smrg}
42817117f1b4Smrg
42824a49301eSmrg/**
42834a49301eSmrg * Similar to _mesa_unpack_color_span_float(), but for dudv data instead of rgba,
42844a49301eSmrg * directly return GLbyte data, no transfer ops apply.
42854a49301eSmrg */
42864a49301eSmrgvoid
42874a49301eSmrg_mesa_unpack_dudv_span_byte( GLcontext *ctx,
42884a49301eSmrg                             GLuint n, GLenum dstFormat, GLbyte dest[],
42894a49301eSmrg                             GLenum srcFormat, GLenum srcType,
42904a49301eSmrg                             const GLvoid *source,
42914a49301eSmrg                             const struct gl_pixelstore_attrib *srcPacking,
42924a49301eSmrg                             GLbitfield transferOps )
42934a49301eSmrg{
42944a49301eSmrg   ASSERT(dstFormat == GL_DUDV_ATI);
42954a49301eSmrg   ASSERT(srcFormat == GL_DUDV_ATI);
42964a49301eSmrg
42974a49301eSmrg   ASSERT(srcType == GL_UNSIGNED_BYTE ||
42984a49301eSmrg          srcType == GL_BYTE ||
42994a49301eSmrg          srcType == GL_UNSIGNED_SHORT ||
43004a49301eSmrg          srcType == GL_SHORT ||
43014a49301eSmrg          srcType == GL_UNSIGNED_INT ||
43024a49301eSmrg          srcType == GL_INT ||
43034a49301eSmrg          srcType == GL_HALF_FLOAT_ARB ||
43044a49301eSmrg          srcType == GL_FLOAT);
43054a49301eSmrg
43064a49301eSmrg   /* general solution */
43074a49301eSmrg   {
43084a49301eSmrg      GLint dstComponents;
43094a49301eSmrg      GLfloat rgba[MAX_WIDTH][4];
43104a49301eSmrg      GLbyte *dst = dest;
43114a49301eSmrg      GLuint i;
43124a49301eSmrg
43134a49301eSmrg      dstComponents = _mesa_components_in_format( dstFormat );
43144a49301eSmrg      /* source & dest image formats should have been error checked by now */
43154a49301eSmrg      assert(dstComponents > 0);
43164a49301eSmrg
43174a49301eSmrg      /*
43184a49301eSmrg       * Extract image data and convert to RGBA floats
43194a49301eSmrg       */
43204a49301eSmrg      assert(n <= MAX_WIDTH);
43214a49301eSmrg      extract_float_rgba(n, rgba, srcFormat, srcType, source,
43224a49301eSmrg                         srcPacking->SwapBytes);
43234a49301eSmrg
43244a49301eSmrg
43254a49301eSmrg      /* Now determine which color channels we need to produce.
43264a49301eSmrg       * And determine the dest index (offset) within each color tuple.
43274a49301eSmrg       */
43284a49301eSmrg
43294a49301eSmrg      /* Now pack results in the requested dstFormat */
43304a49301eSmrg      for (i = 0; i < n; i++) {
43314a49301eSmrg         /* not sure - need clamp[-1,1] here? */
43324a49301eSmrg         dst[0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
43334a49301eSmrg         dst[1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
43344a49301eSmrg         dst += dstComponents;
43354a49301eSmrg      }
43364a49301eSmrg   }
43374a49301eSmrg}
43387117f1b4Smrg
43397117f1b4Smrg/*
43407117f1b4Smrg * Unpack a row of color index data from a client buffer according to
43417117f1b4Smrg * the pixel unpacking parameters.
43427117f1b4Smrg * This is (or will be) used by glDrawPixels, glTexImage[123]D, etc.
43437117f1b4Smrg *
43447117f1b4Smrg * Args:  ctx - the context
43457117f1b4Smrg *        n - number of pixels
43467117f1b4Smrg *        dstType - destination data type
43477117f1b4Smrg *        dest - destination array
43487117f1b4Smrg *        srcType - source pixel type
43497117f1b4Smrg *        source - source data pointer
43507117f1b4Smrg *        srcPacking - pixel unpacking parameters
43517117f1b4Smrg *        transferOps - the pixel transfer operations to apply
43527117f1b4Smrg */
43537117f1b4Smrgvoid
43547117f1b4Smrg_mesa_unpack_index_span( const GLcontext *ctx, GLuint n,
43557117f1b4Smrg                         GLenum dstType, GLvoid *dest,
43567117f1b4Smrg                         GLenum srcType, const GLvoid *source,
43577117f1b4Smrg                         const struct gl_pixelstore_attrib *srcPacking,
43587117f1b4Smrg                         GLbitfield transferOps )
43597117f1b4Smrg{
43607117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
43617117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
43627117f1b4Smrg          srcType == GL_BYTE ||
43637117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
43647117f1b4Smrg          srcType == GL_SHORT ||
43657117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
43667117f1b4Smrg          srcType == GL_INT ||
43677117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
43687117f1b4Smrg          srcType == GL_FLOAT);
43697117f1b4Smrg
43707117f1b4Smrg   ASSERT(dstType == GL_UNSIGNED_BYTE ||
43717117f1b4Smrg          dstType == GL_UNSIGNED_SHORT ||
43727117f1b4Smrg          dstType == GL_UNSIGNED_INT);
43737117f1b4Smrg
43747117f1b4Smrg
43757117f1b4Smrg   transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
43767117f1b4Smrg
43777117f1b4Smrg   /*
43787117f1b4Smrg    * Try simple cases first
43797117f1b4Smrg    */
43807117f1b4Smrg   if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE
43817117f1b4Smrg       && dstType == GL_UNSIGNED_BYTE) {
43827117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLubyte));
43837117f1b4Smrg   }
43847117f1b4Smrg   else if (transferOps == 0 && srcType == GL_UNSIGNED_INT
43857117f1b4Smrg            && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) {
43867117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLuint));
43877117f1b4Smrg   }
43887117f1b4Smrg   else {
43897117f1b4Smrg      /*
43907117f1b4Smrg       * general solution
43917117f1b4Smrg       */
43927117f1b4Smrg      GLuint indexes[MAX_WIDTH];
43937117f1b4Smrg      assert(n <= MAX_WIDTH);
43947117f1b4Smrg
43957117f1b4Smrg      extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
43967117f1b4Smrg                           srcPacking);
43977117f1b4Smrg
43987117f1b4Smrg      if (transferOps)
43997117f1b4Smrg         _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
44007117f1b4Smrg
44017117f1b4Smrg      /* convert to dest type */
44027117f1b4Smrg      switch (dstType) {
44037117f1b4Smrg         case GL_UNSIGNED_BYTE:
44047117f1b4Smrg            {
44057117f1b4Smrg               GLubyte *dst = (GLubyte *) dest;
44067117f1b4Smrg               GLuint i;
44077117f1b4Smrg               for (i = 0; i < n; i++) {
44087117f1b4Smrg                  dst[i] = (GLubyte) (indexes[i] & 0xff);
44097117f1b4Smrg               }
44107117f1b4Smrg            }
44117117f1b4Smrg            break;
44127117f1b4Smrg         case GL_UNSIGNED_SHORT:
44137117f1b4Smrg            {
44147117f1b4Smrg               GLuint *dst = (GLuint *) dest;
44157117f1b4Smrg               GLuint i;
44167117f1b4Smrg               for (i = 0; i < n; i++) {
44177117f1b4Smrg                  dst[i] = (GLushort) (indexes[i] & 0xffff);
44187117f1b4Smrg               }
44197117f1b4Smrg            }
44207117f1b4Smrg            break;
44217117f1b4Smrg         case GL_UNSIGNED_INT:
44227117f1b4Smrg            _mesa_memcpy(dest, indexes, n * sizeof(GLuint));
44237117f1b4Smrg            break;
44247117f1b4Smrg         default:
44257117f1b4Smrg            _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span");
44267117f1b4Smrg      }
44277117f1b4Smrg   }
44287117f1b4Smrg}
44297117f1b4Smrg
44307117f1b4Smrg
44317117f1b4Smrgvoid
44327117f1b4Smrg_mesa_pack_index_span( const GLcontext *ctx, GLuint n,
44337117f1b4Smrg                       GLenum dstType, GLvoid *dest, const GLuint *source,
44347117f1b4Smrg                       const struct gl_pixelstore_attrib *dstPacking,
44357117f1b4Smrg                       GLbitfield transferOps )
44367117f1b4Smrg{
44377117f1b4Smrg   GLuint indexes[MAX_WIDTH];
44387117f1b4Smrg
44397117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
44407117f1b4Smrg
44417117f1b4Smrg   transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
44427117f1b4Smrg
44437117f1b4Smrg   if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) {
44447117f1b4Smrg      /* make a copy of input */
44457117f1b4Smrg      _mesa_memcpy(indexes, source, n * sizeof(GLuint));
44467117f1b4Smrg      _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
44477117f1b4Smrg      source = indexes;
44487117f1b4Smrg   }
44497117f1b4Smrg
44507117f1b4Smrg   switch (dstType) {
44517117f1b4Smrg   case GL_UNSIGNED_BYTE:
44527117f1b4Smrg      {
44537117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
44547117f1b4Smrg         GLuint i;
44557117f1b4Smrg         for (i = 0; i < n; i++) {
44567117f1b4Smrg            *dst++ = (GLubyte) source[i];
44577117f1b4Smrg         }
44587117f1b4Smrg      }
44597117f1b4Smrg      break;
44607117f1b4Smrg   case GL_BYTE:
44617117f1b4Smrg      {
44627117f1b4Smrg         GLbyte *dst = (GLbyte *) dest;
44637117f1b4Smrg         GLuint i;
44647117f1b4Smrg         for (i = 0; i < n; i++) {
44657117f1b4Smrg            dst[i] = (GLbyte) source[i];
44667117f1b4Smrg         }
44677117f1b4Smrg      }
44687117f1b4Smrg      break;
44697117f1b4Smrg   case GL_UNSIGNED_SHORT:
44707117f1b4Smrg      {
44717117f1b4Smrg         GLushort *dst = (GLushort *) dest;
44727117f1b4Smrg         GLuint i;
44737117f1b4Smrg         for (i = 0; i < n; i++) {
44747117f1b4Smrg            dst[i] = (GLushort) source[i];
44757117f1b4Smrg         }
44767117f1b4Smrg         if (dstPacking->SwapBytes) {
44777117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
44787117f1b4Smrg         }
44797117f1b4Smrg      }
44807117f1b4Smrg      break;
44817117f1b4Smrg   case GL_SHORT:
44827117f1b4Smrg      {
44837117f1b4Smrg         GLshort *dst = (GLshort *) dest;
44847117f1b4Smrg         GLuint i;
44857117f1b4Smrg         for (i = 0; i < n; i++) {
44867117f1b4Smrg            dst[i] = (GLshort) source[i];
44877117f1b4Smrg         }
44887117f1b4Smrg         if (dstPacking->SwapBytes) {
44897117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
44907117f1b4Smrg         }
44917117f1b4Smrg      }
44927117f1b4Smrg      break;
44937117f1b4Smrg   case GL_UNSIGNED_INT:
44947117f1b4Smrg      {
44957117f1b4Smrg         GLuint *dst = (GLuint *) dest;
44967117f1b4Smrg         GLuint i;
44977117f1b4Smrg         for (i = 0; i < n; i++) {
44987117f1b4Smrg            dst[i] = (GLuint) source[i];
44997117f1b4Smrg         }
45007117f1b4Smrg         if (dstPacking->SwapBytes) {
45017117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
45027117f1b4Smrg         }
45037117f1b4Smrg      }
45047117f1b4Smrg      break;
45057117f1b4Smrg   case GL_INT:
45067117f1b4Smrg      {
45077117f1b4Smrg         GLint *dst = (GLint *) dest;
45087117f1b4Smrg         GLuint i;
45097117f1b4Smrg         for (i = 0; i < n; i++) {
45107117f1b4Smrg            dst[i] = (GLint) source[i];
45117117f1b4Smrg         }
45127117f1b4Smrg         if (dstPacking->SwapBytes) {
45137117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
45147117f1b4Smrg         }
45157117f1b4Smrg      }
45167117f1b4Smrg      break;
45177117f1b4Smrg   case GL_FLOAT:
45187117f1b4Smrg      {
45197117f1b4Smrg         GLfloat *dst = (GLfloat *) dest;
45207117f1b4Smrg         GLuint i;
45217117f1b4Smrg         for (i = 0; i < n; i++) {
45227117f1b4Smrg            dst[i] = (GLfloat) source[i];
45237117f1b4Smrg         }
45247117f1b4Smrg         if (dstPacking->SwapBytes) {
45257117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
45267117f1b4Smrg         }
45277117f1b4Smrg      }
45287117f1b4Smrg      break;
45297117f1b4Smrg   case GL_HALF_FLOAT_ARB:
45307117f1b4Smrg      {
45317117f1b4Smrg         GLhalfARB *dst = (GLhalfARB *) dest;
45327117f1b4Smrg         GLuint i;
45337117f1b4Smrg         for (i = 0; i < n; i++) {
45347117f1b4Smrg            dst[i] = _mesa_float_to_half((GLfloat) source[i]);
45357117f1b4Smrg         }
45367117f1b4Smrg         if (dstPacking->SwapBytes) {
45377117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
45387117f1b4Smrg         }
45397117f1b4Smrg      }
45407117f1b4Smrg      break;
45417117f1b4Smrg   default:
45427117f1b4Smrg      _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
45437117f1b4Smrg   }
45447117f1b4Smrg}
45457117f1b4Smrg
45467117f1b4Smrg
45477117f1b4Smrg/*
45487117f1b4Smrg * Unpack a row of stencil data from a client buffer according to
45497117f1b4Smrg * the pixel unpacking parameters.
45507117f1b4Smrg * This is (or will be) used by glDrawPixels
45517117f1b4Smrg *
45527117f1b4Smrg * Args:  ctx - the context
45537117f1b4Smrg *        n - number of pixels
45547117f1b4Smrg *        dstType - destination data type
45557117f1b4Smrg *        dest - destination array
45567117f1b4Smrg *        srcType - source pixel type
45577117f1b4Smrg *        source - source data pointer
45587117f1b4Smrg *        srcPacking - pixel unpacking parameters
45597117f1b4Smrg *        transferOps - apply offset/bias/lookup ops?
45607117f1b4Smrg */
45617117f1b4Smrgvoid
45627117f1b4Smrg_mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
45637117f1b4Smrg                           GLenum dstType, GLvoid *dest,
45647117f1b4Smrg                           GLenum srcType, const GLvoid *source,
45657117f1b4Smrg                           const struct gl_pixelstore_attrib *srcPacking,
45667117f1b4Smrg                           GLbitfield transferOps )
45677117f1b4Smrg{
45687117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
45697117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
45707117f1b4Smrg          srcType == GL_BYTE ||
45717117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
45727117f1b4Smrg          srcType == GL_SHORT ||
45737117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
45747117f1b4Smrg          srcType == GL_INT ||
45757117f1b4Smrg          srcType == GL_UNSIGNED_INT_24_8_EXT ||
45767117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
45777117f1b4Smrg          srcType == GL_FLOAT);
45787117f1b4Smrg
45797117f1b4Smrg   ASSERT(dstType == GL_UNSIGNED_BYTE ||
45807117f1b4Smrg          dstType == GL_UNSIGNED_SHORT ||
45817117f1b4Smrg          dstType == GL_UNSIGNED_INT);
45827117f1b4Smrg
45837117f1b4Smrg   /* only shift and offset apply to stencil */
45847117f1b4Smrg   transferOps &= IMAGE_SHIFT_OFFSET_BIT;
45857117f1b4Smrg
45867117f1b4Smrg   /*
45877117f1b4Smrg    * Try simple cases first
45887117f1b4Smrg    */
45897117f1b4Smrg   if (transferOps == 0 &&
45907117f1b4Smrg       !ctx->Pixel.MapStencilFlag &&
45917117f1b4Smrg       srcType == GL_UNSIGNED_BYTE &&
45927117f1b4Smrg       dstType == GL_UNSIGNED_BYTE) {
45937117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLubyte));
45947117f1b4Smrg   }
45957117f1b4Smrg   else if (transferOps == 0 &&
45967117f1b4Smrg            !ctx->Pixel.MapStencilFlag &&
45977117f1b4Smrg            srcType == GL_UNSIGNED_INT &&
45987117f1b4Smrg            dstType == GL_UNSIGNED_INT &&
45997117f1b4Smrg            !srcPacking->SwapBytes) {
46007117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLuint));
46017117f1b4Smrg   }
46027117f1b4Smrg   else {
46037117f1b4Smrg      /*
46047117f1b4Smrg       * general solution
46057117f1b4Smrg       */
46067117f1b4Smrg      GLuint indexes[MAX_WIDTH];
46077117f1b4Smrg      assert(n <= MAX_WIDTH);
46087117f1b4Smrg
46097117f1b4Smrg      extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
46107117f1b4Smrg                           srcPacking);
46117117f1b4Smrg
46127117f1b4Smrg      if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
46137117f1b4Smrg         /* shift and offset indexes */
46147117f1b4Smrg         shift_and_offset_ci(ctx, n, indexes);
46157117f1b4Smrg      }
46167117f1b4Smrg
46177117f1b4Smrg      if (ctx->Pixel.MapStencilFlag) {
46187117f1b4Smrg         /* Apply stencil lookup table */
46197117f1b4Smrg         const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
46207117f1b4Smrg         GLuint i;
46217117f1b4Smrg         for (i = 0; i < n; i++) {
4622c1f859d4Smrg            indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
46237117f1b4Smrg         }
46247117f1b4Smrg      }
46257117f1b4Smrg
46267117f1b4Smrg      /* convert to dest type */
46277117f1b4Smrg      switch (dstType) {
46287117f1b4Smrg         case GL_UNSIGNED_BYTE:
46297117f1b4Smrg            {
46307117f1b4Smrg               GLubyte *dst = (GLubyte *) dest;
46317117f1b4Smrg               GLuint i;
46327117f1b4Smrg               for (i = 0; i < n; i++) {
46337117f1b4Smrg                  dst[i] = (GLubyte) (indexes[i] & 0xff);
46347117f1b4Smrg               }
46357117f1b4Smrg            }
46367117f1b4Smrg            break;
46377117f1b4Smrg         case GL_UNSIGNED_SHORT:
46387117f1b4Smrg            {
46397117f1b4Smrg               GLuint *dst = (GLuint *) dest;
46407117f1b4Smrg               GLuint i;
46417117f1b4Smrg               for (i = 0; i < n; i++) {
46427117f1b4Smrg                  dst[i] = (GLushort) (indexes[i] & 0xffff);
46437117f1b4Smrg               }
46447117f1b4Smrg            }
46457117f1b4Smrg            break;
46467117f1b4Smrg         case GL_UNSIGNED_INT:
46477117f1b4Smrg            _mesa_memcpy(dest, indexes, n * sizeof(GLuint));
46487117f1b4Smrg            break;
46497117f1b4Smrg         default:
46507117f1b4Smrg            _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
46517117f1b4Smrg      }
46527117f1b4Smrg   }
46537117f1b4Smrg}
46547117f1b4Smrg
46557117f1b4Smrg
46567117f1b4Smrgvoid
46577117f1b4Smrg_mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
46587117f1b4Smrg                         GLenum dstType, GLvoid *dest, const GLstencil *source,
46597117f1b4Smrg                         const struct gl_pixelstore_attrib *dstPacking )
46607117f1b4Smrg{
46617117f1b4Smrg   GLstencil stencil[MAX_WIDTH];
46627117f1b4Smrg
46637117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
46647117f1b4Smrg
46657117f1b4Smrg   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
46667117f1b4Smrg       ctx->Pixel.MapStencilFlag) {
46677117f1b4Smrg      /* make a copy of input */
46687117f1b4Smrg      _mesa_memcpy(stencil, source, n * sizeof(GLstencil));
46697117f1b4Smrg      _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
46707117f1b4Smrg      source = stencil;
46717117f1b4Smrg   }
46727117f1b4Smrg
46737117f1b4Smrg   switch (dstType) {
46747117f1b4Smrg   case GL_UNSIGNED_BYTE:
46757117f1b4Smrg      if (sizeof(GLstencil) == 1) {
46767117f1b4Smrg         _mesa_memcpy( dest, source, n );
46777117f1b4Smrg      }
46787117f1b4Smrg      else {
46797117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
46807117f1b4Smrg         GLuint i;
46817117f1b4Smrg         for (i=0;i<n;i++) {
46827117f1b4Smrg            dst[i] = (GLubyte) source[i];
46837117f1b4Smrg         }
46847117f1b4Smrg      }
46857117f1b4Smrg      break;
46867117f1b4Smrg   case GL_BYTE:
46877117f1b4Smrg      {
46887117f1b4Smrg         GLbyte *dst = (GLbyte *) dest;
46897117f1b4Smrg         GLuint i;
46907117f1b4Smrg         for (i=0;i<n;i++) {
46917117f1b4Smrg            dst[i] = (GLbyte) (source[i] & 0x7f);
46927117f1b4Smrg         }
46937117f1b4Smrg      }
46947117f1b4Smrg      break;
46957117f1b4Smrg   case GL_UNSIGNED_SHORT:
46967117f1b4Smrg      {
46977117f1b4Smrg         GLushort *dst = (GLushort *) dest;
46987117f1b4Smrg         GLuint i;
46997117f1b4Smrg         for (i=0;i<n;i++) {
47007117f1b4Smrg            dst[i] = (GLushort) source[i];
47017117f1b4Smrg         }
47027117f1b4Smrg         if (dstPacking->SwapBytes) {
47037117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
47047117f1b4Smrg         }
47057117f1b4Smrg      }
47067117f1b4Smrg      break;
47077117f1b4Smrg   case GL_SHORT:
47087117f1b4Smrg      {
47097117f1b4Smrg         GLshort *dst = (GLshort *) dest;
47107117f1b4Smrg         GLuint i;
47117117f1b4Smrg         for (i=0;i<n;i++) {
47127117f1b4Smrg            dst[i] = (GLshort) source[i];
47137117f1b4Smrg         }
47147117f1b4Smrg         if (dstPacking->SwapBytes) {
47157117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
47167117f1b4Smrg         }
47177117f1b4Smrg      }
47187117f1b4Smrg      break;
47197117f1b4Smrg   case GL_UNSIGNED_INT:
47207117f1b4Smrg      {
47217117f1b4Smrg         GLuint *dst = (GLuint *) dest;
47227117f1b4Smrg         GLuint i;
47237117f1b4Smrg         for (i=0;i<n;i++) {
47247117f1b4Smrg            dst[i] = (GLuint) source[i];
47257117f1b4Smrg         }
47267117f1b4Smrg         if (dstPacking->SwapBytes) {
47277117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
47287117f1b4Smrg         }
47297117f1b4Smrg      }
47307117f1b4Smrg      break;
47317117f1b4Smrg   case GL_INT:
47327117f1b4Smrg      {
47337117f1b4Smrg         GLint *dst = (GLint *) dest;
47347117f1b4Smrg         GLuint i;
47357117f1b4Smrg         for (i=0;i<n;i++) {
47367117f1b4Smrg            dst[i] = (GLint) source[i];
47377117f1b4Smrg         }
47387117f1b4Smrg         if (dstPacking->SwapBytes) {
47397117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
47407117f1b4Smrg         }
47417117f1b4Smrg      }
47427117f1b4Smrg      break;
47437117f1b4Smrg   case GL_FLOAT:
47447117f1b4Smrg      {
47457117f1b4Smrg         GLfloat *dst = (GLfloat *) dest;
47467117f1b4Smrg         GLuint i;
47477117f1b4Smrg         for (i=0;i<n;i++) {
47487117f1b4Smrg            dst[i] = (GLfloat) source[i];
47497117f1b4Smrg         }
47507117f1b4Smrg         if (dstPacking->SwapBytes) {
47517117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
47527117f1b4Smrg         }
47537117f1b4Smrg      }
47547117f1b4Smrg      break;
47557117f1b4Smrg   case GL_HALF_FLOAT_ARB:
47567117f1b4Smrg      {
47577117f1b4Smrg         GLhalfARB *dst = (GLhalfARB *) dest;
47587117f1b4Smrg         GLuint i;
47597117f1b4Smrg         for (i=0;i<n;i++) {
47607117f1b4Smrg            dst[i] = _mesa_float_to_half( (float) source[i] );
47617117f1b4Smrg         }
47627117f1b4Smrg         if (dstPacking->SwapBytes) {
47637117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
47647117f1b4Smrg         }
47657117f1b4Smrg      }
47667117f1b4Smrg      break;
47677117f1b4Smrg   case GL_BITMAP:
47687117f1b4Smrg      if (dstPacking->LsbFirst) {
47697117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
47707117f1b4Smrg         GLint shift = 0;
47717117f1b4Smrg         GLuint i;
47727117f1b4Smrg         for (i = 0; i < n; i++) {
47737117f1b4Smrg            if (shift == 0)
47747117f1b4Smrg               *dst = 0;
47757117f1b4Smrg            *dst |= ((source[i] != 0) << shift);
47767117f1b4Smrg            shift++;
47777117f1b4Smrg            if (shift == 8) {
47787117f1b4Smrg               shift = 0;
47797117f1b4Smrg               dst++;
47807117f1b4Smrg            }
47817117f1b4Smrg         }
47827117f1b4Smrg      }
47837117f1b4Smrg      else {
47847117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
47857117f1b4Smrg         GLint shift = 7;
47867117f1b4Smrg         GLuint i;
47877117f1b4Smrg         for (i = 0; i < n; i++) {
47887117f1b4Smrg            if (shift == 7)
47897117f1b4Smrg               *dst = 0;
47907117f1b4Smrg            *dst |= ((source[i] != 0) << shift);
47917117f1b4Smrg            shift--;
47927117f1b4Smrg            if (shift < 0) {
47937117f1b4Smrg               shift = 7;
47947117f1b4Smrg               dst++;
47957117f1b4Smrg            }
47967117f1b4Smrg         }
47977117f1b4Smrg      }
47987117f1b4Smrg      break;
47997117f1b4Smrg   default:
48007117f1b4Smrg      _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
48017117f1b4Smrg   }
48027117f1b4Smrg}
48037117f1b4Smrg
48047117f1b4Smrg#define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT)                              \
48057117f1b4Smrg    do {                                                                \
48067117f1b4Smrg        GLuint i;                                                       \
48077117f1b4Smrg        const GLTYPE *src = (const GLTYPE *)source;                     \
48087117f1b4Smrg        for (i = 0; i < n; i++) {                                       \
48097117f1b4Smrg            GLTYPE value = src[i];                                      \
48107117f1b4Smrg            if (srcPacking->SwapBytes) {                                \
48117117f1b4Smrg                if (sizeof(GLTYPE) == 2) {                              \
48127117f1b4Smrg                    SWAP2BYTE(value);                                   \
48137117f1b4Smrg                } else if (sizeof(GLTYPE) == 4) {                       \
48147117f1b4Smrg                    SWAP4BYTE(value);                                   \
48157117f1b4Smrg                }                                                       \
48167117f1b4Smrg            }                                                           \
48177117f1b4Smrg            depthValues[i] = GLTYPE2FLOAT(value);                       \
48187117f1b4Smrg        }                                                               \
48197117f1b4Smrg    } while (0)
48207117f1b4Smrg
48217117f1b4Smrg
48227117f1b4Smrg/**
48237117f1b4Smrg * Unpack a row of depth/z values from memory, returning GLushort, GLuint
48247117f1b4Smrg * or GLfloat values.
48257117f1b4Smrg * The glPixelTransfer (scale/bias) params will be applied.
48267117f1b4Smrg *
48277117f1b4Smrg * \param dstType  one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT
4828c1f859d4Smrg * \param depthMax  max value for returned GLushort or GLuint values
4829c1f859d4Smrg *                  (ignored for GLfloat).
48307117f1b4Smrg */
48317117f1b4Smrgvoid
48327117f1b4Smrg_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
4833c1f859d4Smrg                         GLenum dstType, GLvoid *dest, GLuint depthMax,
48347117f1b4Smrg                         GLenum srcType, const GLvoid *source,
48357117f1b4Smrg                         const struct gl_pixelstore_attrib *srcPacking )
48367117f1b4Smrg{
48377117f1b4Smrg   GLfloat depthTemp[MAX_WIDTH], *depthValues;
48387117f1b4Smrg   GLboolean needClamp = GL_FALSE;
48397117f1b4Smrg
48407117f1b4Smrg   /* Look for special cases first.
48417117f1b4Smrg    * Not only are these faster, they're less prone to numeric conversion
48427117f1b4Smrg    * problems.  Otherwise, converting from an int type to a float then
48437117f1b4Smrg    * back to an int type can introduce errors that will show up as
48447117f1b4Smrg    * artifacts in things like depth peeling which uses glCopyTexImage.
48457117f1b4Smrg    */
48467117f1b4Smrg   if (ctx->Pixel.DepthScale == 1.0 && ctx->Pixel.DepthBias == 0.0) {
48477117f1b4Smrg      if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) {
48487117f1b4Smrg         const GLuint *src = (const GLuint *) source;
48497117f1b4Smrg         GLushort *dst = (GLushort *) dest;
48507117f1b4Smrg         GLuint i;
48517117f1b4Smrg         for (i = 0; i < n; i++) {
48527117f1b4Smrg            dst[i] = src[i] >> 16;
48537117f1b4Smrg         }
48547117f1b4Smrg         return;
48557117f1b4Smrg      }
48567117f1b4Smrg      if (srcType == GL_UNSIGNED_SHORT
48577117f1b4Smrg          && dstType == GL_UNSIGNED_INT
4858c1f859d4Smrg          && depthMax == 0xffffffff) {
48597117f1b4Smrg         const GLushort *src = (const GLushort *) source;
48607117f1b4Smrg         GLuint *dst = (GLuint *) dest;
48617117f1b4Smrg         GLuint i;
48627117f1b4Smrg         for (i = 0; i < n; i++) {
48637117f1b4Smrg            dst[i] = src[i] | (src[i] << 16);
48647117f1b4Smrg         }
48657117f1b4Smrg         return;
48667117f1b4Smrg      }
48674a49301eSmrg      if (srcType == GL_UNSIGNED_INT_24_8
48684a49301eSmrg          && dstType == GL_UNSIGNED_INT
48694a49301eSmrg          && depthMax == 0xffffff) {
48704a49301eSmrg         const GLuint *src = (const GLuint *) source;
48714a49301eSmrg         GLuint *dst = (GLuint *) dest;
48724a49301eSmrg         GLuint i;
48734a49301eSmrg         for (i = 0; i < n; i++) {
48744a49301eSmrg            dst[i] = src[i] >> 8;
48754a49301eSmrg         }
48764a49301eSmrg         return;
48774a49301eSmrg      }
48787117f1b4Smrg      /* XXX may want to add additional cases here someday */
48797117f1b4Smrg   }
48807117f1b4Smrg
48817117f1b4Smrg   /* general case path follows */
48827117f1b4Smrg
48837117f1b4Smrg   if (dstType == GL_FLOAT) {
48847117f1b4Smrg      depthValues = (GLfloat *) dest;
48857117f1b4Smrg   }
48867117f1b4Smrg   else {
48877117f1b4Smrg      depthValues = depthTemp;
48887117f1b4Smrg   }
48897117f1b4Smrg
48907117f1b4Smrg   /* Convert incoming values to GLfloat.  Some conversions will require
48917117f1b4Smrg    * clamping, below.
48927117f1b4Smrg    */
48937117f1b4Smrg   switch (srcType) {
48947117f1b4Smrg      case GL_BYTE:
48957117f1b4Smrg         DEPTH_VALUES(GLbyte, BYTE_TO_FLOAT);
48967117f1b4Smrg         needClamp = GL_TRUE;
48977117f1b4Smrg         break;
48987117f1b4Smrg      case GL_UNSIGNED_BYTE:
48997117f1b4Smrg         DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT);
49007117f1b4Smrg         break;
49017117f1b4Smrg      case GL_SHORT:
49027117f1b4Smrg         DEPTH_VALUES(GLshort, SHORT_TO_FLOAT);
49037117f1b4Smrg         needClamp = GL_TRUE;
49047117f1b4Smrg         break;
49057117f1b4Smrg      case GL_UNSIGNED_SHORT:
49067117f1b4Smrg         DEPTH_VALUES(GLushort, USHORT_TO_FLOAT);
49077117f1b4Smrg         break;
49087117f1b4Smrg      case GL_INT:
49097117f1b4Smrg         DEPTH_VALUES(GLint, INT_TO_FLOAT);
49107117f1b4Smrg         needClamp = GL_TRUE;
49117117f1b4Smrg         break;
49127117f1b4Smrg      case GL_UNSIGNED_INT:
49137117f1b4Smrg         DEPTH_VALUES(GLuint, UINT_TO_FLOAT);
49147117f1b4Smrg         break;
49157117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
4916c1f859d4Smrg         if (dstType == GL_UNSIGNED_INT_24_8_EXT &&
4917c1f859d4Smrg             depthMax == 0xffffff &&
49187117f1b4Smrg             ctx->Pixel.DepthScale == 1.0 &&
49197117f1b4Smrg             ctx->Pixel.DepthBias == 0.0) {
49207117f1b4Smrg            const GLuint *src = (const GLuint *) source;
49217117f1b4Smrg            GLuint *zValues = (GLuint *) dest;
49227117f1b4Smrg            GLuint i;
49237117f1b4Smrg            for (i = 0; i < n; i++) {
49247117f1b4Smrg                GLuint value = src[i];
49257117f1b4Smrg                if (srcPacking->SwapBytes) {
49267117f1b4Smrg                    SWAP4BYTE(value);
49277117f1b4Smrg                }
49287117f1b4Smrg                zValues[i] = value & 0xffffff00;
49297117f1b4Smrg            }
49307117f1b4Smrg            return;
49317117f1b4Smrg         }
49327117f1b4Smrg         else {
49337117f1b4Smrg            const GLuint *src = (const GLuint *) source;
49347117f1b4Smrg            const GLfloat scale = 1.0f / 0xffffff;
49357117f1b4Smrg            GLuint i;
49367117f1b4Smrg            for (i = 0; i < n; i++) {
49377117f1b4Smrg                GLuint value = src[i];
49387117f1b4Smrg                if (srcPacking->SwapBytes) {
49397117f1b4Smrg                    SWAP4BYTE(value);
49407117f1b4Smrg                }
49417117f1b4Smrg                depthValues[i] = (value >> 8) * scale;
49427117f1b4Smrg            }
49437117f1b4Smrg         }
49447117f1b4Smrg         break;
49457117f1b4Smrg      case GL_FLOAT:
49467117f1b4Smrg         DEPTH_VALUES(GLfloat, 1*);
49477117f1b4Smrg         needClamp = GL_TRUE;
49487117f1b4Smrg         break;
49497117f1b4Smrg      case GL_HALF_FLOAT_ARB:
49507117f1b4Smrg         {
49517117f1b4Smrg            GLuint i;
49527117f1b4Smrg            const GLhalfARB *src = (const GLhalfARB *) source;
49537117f1b4Smrg            for (i = 0; i < n; i++) {
49547117f1b4Smrg               GLhalfARB value = src[i];
49557117f1b4Smrg               if (srcPacking->SwapBytes) {
49567117f1b4Smrg                  SWAP2BYTE(value);
49577117f1b4Smrg               }
49587117f1b4Smrg               depthValues[i] = _mesa_half_to_float(value);
49597117f1b4Smrg            }
49607117f1b4Smrg            needClamp = GL_TRUE;
49617117f1b4Smrg         }
49627117f1b4Smrg         break;
49637117f1b4Smrg      default:
49647117f1b4Smrg         _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
49657117f1b4Smrg         return;
49667117f1b4Smrg   }
49677117f1b4Smrg
49687117f1b4Smrg   /* apply depth scale and bias */
49697117f1b4Smrg   {
49707117f1b4Smrg      const GLfloat scale = ctx->Pixel.DepthScale;
49717117f1b4Smrg      const GLfloat bias = ctx->Pixel.DepthBias;
49727117f1b4Smrg      if (scale != 1.0 || bias != 0.0) {
49737117f1b4Smrg         GLuint i;
49747117f1b4Smrg         for (i = 0; i < n; i++) {
49757117f1b4Smrg            depthValues[i] = depthValues[i] * scale + bias;
49767117f1b4Smrg         }
49777117f1b4Smrg         needClamp = GL_TRUE;
49787117f1b4Smrg      }
49797117f1b4Smrg   }
49807117f1b4Smrg
49817117f1b4Smrg   /* clamp to [0, 1] */
49827117f1b4Smrg   if (needClamp) {
49837117f1b4Smrg      GLuint i;
49847117f1b4Smrg      for (i = 0; i < n; i++) {
4985c1f859d4Smrg         depthValues[i] = (GLfloat)CLAMP(depthValues[i], 0.0, 1.0);
49867117f1b4Smrg      }
49877117f1b4Smrg   }
49887117f1b4Smrg
49897117f1b4Smrg   /*
49907117f1b4Smrg    * Convert values to dstType
49917117f1b4Smrg    */
49927117f1b4Smrg   if (dstType == GL_UNSIGNED_INT) {
49937117f1b4Smrg      GLuint *zValues = (GLuint *) dest;
49947117f1b4Smrg      GLuint i;
4995c1f859d4Smrg      if (depthMax <= 0xffffff) {
49967117f1b4Smrg         /* no overflow worries */
49977117f1b4Smrg         for (i = 0; i < n; i++) {
4998c1f859d4Smrg            zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax);
49997117f1b4Smrg         }
50007117f1b4Smrg      }
50017117f1b4Smrg      else {
50027117f1b4Smrg         /* need to use double precision to prevent overflow problems */
50037117f1b4Smrg         for (i = 0; i < n; i++) {
5004c1f859d4Smrg            GLdouble z = depthValues[i] * (GLfloat) depthMax;
50057117f1b4Smrg            if (z >= (GLdouble) 0xffffffff)
50067117f1b4Smrg               zValues[i] = 0xffffffff;
50077117f1b4Smrg            else
50087117f1b4Smrg               zValues[i] = (GLuint) z;
50097117f1b4Smrg         }
50107117f1b4Smrg      }
50117117f1b4Smrg   }
50127117f1b4Smrg   else if (dstType == GL_UNSIGNED_SHORT) {
50137117f1b4Smrg      GLushort *zValues = (GLushort *) dest;
50147117f1b4Smrg      GLuint i;
5015c1f859d4Smrg      ASSERT(depthMax <= 0xffff);
50167117f1b4Smrg      for (i = 0; i < n; i++) {
5017c1f859d4Smrg         zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax);
50187117f1b4Smrg      }
50197117f1b4Smrg   }
50207117f1b4Smrg   else {
50217117f1b4Smrg      ASSERT(dstType == GL_FLOAT);
5022c1f859d4Smrg      /*ASSERT(depthMax == 1.0F);*/
50237117f1b4Smrg   }
50247117f1b4Smrg}
50257117f1b4Smrg
50267117f1b4Smrg
50277117f1b4Smrg/*
50287117f1b4Smrg * Pack an array of depth values.  The values are floats in [0,1].
50297117f1b4Smrg */
50307117f1b4Smrgvoid
50317117f1b4Smrg_mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest,
50327117f1b4Smrg                       GLenum dstType, const GLfloat *depthSpan,
50337117f1b4Smrg                       const struct gl_pixelstore_attrib *dstPacking )
50347117f1b4Smrg{
50357117f1b4Smrg   GLfloat depthCopy[MAX_WIDTH];
50367117f1b4Smrg
50377117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
50387117f1b4Smrg
50397117f1b4Smrg   if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
50407117f1b4Smrg      _mesa_memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
50417117f1b4Smrg      _mesa_scale_and_bias_depth(ctx, n, depthCopy);
50427117f1b4Smrg      depthSpan = depthCopy;
50437117f1b4Smrg   }
50447117f1b4Smrg
50457117f1b4Smrg   switch (dstType) {
50467117f1b4Smrg   case GL_UNSIGNED_BYTE:
50477117f1b4Smrg      {
50487117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
50497117f1b4Smrg         GLuint i;
50507117f1b4Smrg         for (i = 0; i < n; i++) {
50517117f1b4Smrg            dst[i] = FLOAT_TO_UBYTE( depthSpan[i] );
50527117f1b4Smrg         }
50537117f1b4Smrg      }
50547117f1b4Smrg      break;
50557117f1b4Smrg   case GL_BYTE:
50567117f1b4Smrg      {
50577117f1b4Smrg         GLbyte *dst = (GLbyte *) dest;
50587117f1b4Smrg         GLuint i;
50597117f1b4Smrg         for (i = 0; i < n; i++) {
50607117f1b4Smrg            dst[i] = FLOAT_TO_BYTE( depthSpan[i] );
50617117f1b4Smrg         }
50627117f1b4Smrg      }
50637117f1b4Smrg      break;
50647117f1b4Smrg   case GL_UNSIGNED_SHORT:
50657117f1b4Smrg      {
50667117f1b4Smrg         GLushort *dst = (GLushort *) dest;
50677117f1b4Smrg         GLuint i;
50687117f1b4Smrg         for (i = 0; i < n; i++) {
50697117f1b4Smrg            CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]);
50707117f1b4Smrg         }
50717117f1b4Smrg         if (dstPacking->SwapBytes) {
50727117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
50737117f1b4Smrg         }
50747117f1b4Smrg      }
50757117f1b4Smrg      break;
50767117f1b4Smrg   case GL_SHORT:
50777117f1b4Smrg      {
50787117f1b4Smrg         GLshort *dst = (GLshort *) dest;
50797117f1b4Smrg         GLuint i;
50807117f1b4Smrg         for (i = 0; i < n; i++) {
50817117f1b4Smrg            dst[i] = FLOAT_TO_SHORT( depthSpan[i] );
50827117f1b4Smrg         }
50837117f1b4Smrg         if (dstPacking->SwapBytes) {
50847117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
50857117f1b4Smrg         }
50867117f1b4Smrg      }
50877117f1b4Smrg      break;
50887117f1b4Smrg   case GL_UNSIGNED_INT:
50897117f1b4Smrg      {
50907117f1b4Smrg         GLuint *dst = (GLuint *) dest;
50917117f1b4Smrg         GLuint i;
50927117f1b4Smrg         for (i = 0; i < n; i++) {
50937117f1b4Smrg            dst[i] = FLOAT_TO_UINT( depthSpan[i] );
50947117f1b4Smrg         }
50957117f1b4Smrg         if (dstPacking->SwapBytes) {
50967117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
50977117f1b4Smrg         }
50987117f1b4Smrg      }
50997117f1b4Smrg      break;
51007117f1b4Smrg   case GL_INT:
51017117f1b4Smrg      {
51027117f1b4Smrg         GLint *dst = (GLint *) dest;
51037117f1b4Smrg         GLuint i;
51047117f1b4Smrg         for (i = 0; i < n; i++) {
51057117f1b4Smrg            dst[i] = FLOAT_TO_INT( depthSpan[i] );
51067117f1b4Smrg         }
51077117f1b4Smrg         if (dstPacking->SwapBytes) {
51087117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
51097117f1b4Smrg         }
51107117f1b4Smrg      }
51117117f1b4Smrg      break;
51127117f1b4Smrg   case GL_FLOAT:
51137117f1b4Smrg      {
51147117f1b4Smrg         GLfloat *dst = (GLfloat *) dest;
51157117f1b4Smrg         GLuint i;
51167117f1b4Smrg         for (i = 0; i < n; i++) {
51177117f1b4Smrg            dst[i] = depthSpan[i];
51187117f1b4Smrg         }
51197117f1b4Smrg         if (dstPacking->SwapBytes) {
51207117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
51217117f1b4Smrg         }
51227117f1b4Smrg      }
51237117f1b4Smrg      break;
51247117f1b4Smrg   case GL_HALF_FLOAT_ARB:
51257117f1b4Smrg      {
51267117f1b4Smrg         GLhalfARB *dst = (GLhalfARB *) dest;
51277117f1b4Smrg         GLuint i;
51287117f1b4Smrg         for (i = 0; i < n; i++) {
51297117f1b4Smrg            dst[i] = _mesa_float_to_half(depthSpan[i]);
51307117f1b4Smrg         }
51317117f1b4Smrg         if (dstPacking->SwapBytes) {
51327117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
51337117f1b4Smrg         }
51347117f1b4Smrg      }
51357117f1b4Smrg      break;
51367117f1b4Smrg   default:
51377117f1b4Smrg      _mesa_problem(ctx, "bad type in _mesa_pack_depth_span");
51387117f1b4Smrg   }
51397117f1b4Smrg}
51407117f1b4Smrg
51417117f1b4Smrg
51427117f1b4Smrg
51437117f1b4Smrg/**
51447117f1b4Smrg * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8.
51457117f1b4Smrg */
51467117f1b4Smrgvoid
51477117f1b4Smrg_mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest,
51487117f1b4Smrg                              const GLfloat *depthVals,
51497117f1b4Smrg                              const GLstencil *stencilVals,
51507117f1b4Smrg                              const struct gl_pixelstore_attrib *dstPacking)
51517117f1b4Smrg{
51527117f1b4Smrg   GLfloat depthCopy[MAX_WIDTH];
51537117f1b4Smrg   GLstencil stencilCopy[MAX_WIDTH];
51547117f1b4Smrg   GLuint i;
51557117f1b4Smrg
51567117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
51577117f1b4Smrg
51587117f1b4Smrg   if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
51597117f1b4Smrg      _mesa_memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
51607117f1b4Smrg      _mesa_scale_and_bias_depth(ctx, n, depthCopy);
51617117f1b4Smrg      depthVals = depthCopy;
51627117f1b4Smrg   }
51637117f1b4Smrg
51647117f1b4Smrg   if (ctx->Pixel.IndexShift ||
51657117f1b4Smrg       ctx->Pixel.IndexOffset ||
51667117f1b4Smrg       ctx->Pixel.MapStencilFlag) {
51677117f1b4Smrg      _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
51687117f1b4Smrg      _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
51697117f1b4Smrg      stencilVals = stencilCopy;
51707117f1b4Smrg   }
51717117f1b4Smrg
51727117f1b4Smrg   for (i = 0; i < n; i++) {
51737117f1b4Smrg      GLuint z = (GLuint) (depthVals[i] * 0xffffff);
51747117f1b4Smrg      dest[i] = (z << 8) | (stencilVals[i] & 0xff);
51757117f1b4Smrg   }
51767117f1b4Smrg
51777117f1b4Smrg   if (dstPacking->SwapBytes) {
51787117f1b4Smrg      _mesa_swap4(dest, n);
51797117f1b4Smrg   }
51807117f1b4Smrg}
51817117f1b4Smrg
51827117f1b4Smrg
51837117f1b4Smrg
51847117f1b4Smrg
51857117f1b4Smrg/**
51867117f1b4Smrg * Unpack image data.  Apply byte swapping, byte flipping (bitmap).
51877117f1b4Smrg * Return all image data in a contiguous block.  This is used when we
51887117f1b4Smrg * compile glDrawPixels, glTexImage, etc into a display list.  We
51897117f1b4Smrg * need a copy of the data in a standard format.
51907117f1b4Smrg */
51917117f1b4Smrgvoid *
51927117f1b4Smrg_mesa_unpack_image( GLuint dimensions,
51937117f1b4Smrg                    GLsizei width, GLsizei height, GLsizei depth,
51947117f1b4Smrg                    GLenum format, GLenum type, const GLvoid *pixels,
51957117f1b4Smrg                    const struct gl_pixelstore_attrib *unpack )
51967117f1b4Smrg{
51977117f1b4Smrg   GLint bytesPerRow, compsPerRow;
51987117f1b4Smrg   GLboolean flipBytes, swap2, swap4;
51997117f1b4Smrg
52007117f1b4Smrg   if (!pixels)
52017117f1b4Smrg      return NULL;  /* not necessarily an error */
52027117f1b4Smrg
52037117f1b4Smrg   if (width <= 0 || height <= 0 || depth <= 0)
52047117f1b4Smrg      return NULL;  /* generate error later */
52057117f1b4Smrg
52067117f1b4Smrg   if (type == GL_BITMAP) {
52077117f1b4Smrg      bytesPerRow = (width + 7) >> 3;
52087117f1b4Smrg      flipBytes = unpack->LsbFirst;
52097117f1b4Smrg      swap2 = swap4 = GL_FALSE;
52107117f1b4Smrg      compsPerRow = 0;
52117117f1b4Smrg   }
52127117f1b4Smrg   else {
52137117f1b4Smrg      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
52147117f1b4Smrg      GLint components = _mesa_components_in_format(format);
52157117f1b4Smrg      GLint bytesPerComp;
52167117f1b4Smrg
52177117f1b4Smrg      if (_mesa_type_is_packed(type))
52187117f1b4Smrg          components = 1;
52197117f1b4Smrg
52207117f1b4Smrg      if (bytesPerPixel <= 0 || components <= 0)
52217117f1b4Smrg         return NULL;   /* bad format or type.  generate error later */
52227117f1b4Smrg      bytesPerRow = bytesPerPixel * width;
52237117f1b4Smrg      bytesPerComp = bytesPerPixel / components;
52247117f1b4Smrg      flipBytes = GL_FALSE;
52257117f1b4Smrg      swap2 = (bytesPerComp == 2) && unpack->SwapBytes;
52267117f1b4Smrg      swap4 = (bytesPerComp == 4) && unpack->SwapBytes;
52277117f1b4Smrg      compsPerRow = components * width;
52287117f1b4Smrg      assert(compsPerRow >= width);
52297117f1b4Smrg   }
52307117f1b4Smrg
52317117f1b4Smrg   {
52327117f1b4Smrg      GLubyte *destBuffer
52337117f1b4Smrg         = (GLubyte *) _mesa_malloc(bytesPerRow * height * depth);
52347117f1b4Smrg      GLubyte *dst;
52357117f1b4Smrg      GLint img, row;
52367117f1b4Smrg      if (!destBuffer)
52377117f1b4Smrg         return NULL;   /* generate GL_OUT_OF_MEMORY later */
52387117f1b4Smrg
52397117f1b4Smrg      dst = destBuffer;
52407117f1b4Smrg      for (img = 0; img < depth; img++) {
52417117f1b4Smrg         for (row = 0; row < height; row++) {
52427117f1b4Smrg            const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels,
52437117f1b4Smrg                               width, height, format, type, img, row, 0);
52447117f1b4Smrg
52457117f1b4Smrg            if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) {
52467117f1b4Smrg               GLint i;
52477117f1b4Smrg               flipBytes = GL_FALSE;
52487117f1b4Smrg               if (unpack->LsbFirst) {
52497117f1b4Smrg                  GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7);
52507117f1b4Smrg                  GLubyte dstMask = 128;
52517117f1b4Smrg                  const GLubyte *s = src;
52527117f1b4Smrg                  GLubyte *d = dst;
52537117f1b4Smrg                  *d = 0;
52547117f1b4Smrg                  for (i = 0; i < width; i++) {
52557117f1b4Smrg                     if (*s & srcMask) {
52567117f1b4Smrg                        *d |= dstMask;
52577117f1b4Smrg                     }
52587117f1b4Smrg                     if (srcMask == 128) {
52597117f1b4Smrg                        srcMask = 1;
52607117f1b4Smrg                        s++;
52617117f1b4Smrg                     }
52627117f1b4Smrg                     else {
52637117f1b4Smrg                        srcMask = srcMask << 1;
52647117f1b4Smrg                     }
52657117f1b4Smrg                     if (dstMask == 1) {
52667117f1b4Smrg                        dstMask = 128;
52677117f1b4Smrg                        d++;
52687117f1b4Smrg                        *d = 0;
52697117f1b4Smrg                     }
52707117f1b4Smrg                     else {
52717117f1b4Smrg                        dstMask = dstMask >> 1;
52727117f1b4Smrg                     }
52737117f1b4Smrg                  }
52747117f1b4Smrg               }
52757117f1b4Smrg               else {
52767117f1b4Smrg                  GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7);
52777117f1b4Smrg                  GLubyte dstMask = 128;
52787117f1b4Smrg                  const GLubyte *s = src;
52797117f1b4Smrg                  GLubyte *d = dst;
52807117f1b4Smrg                  *d = 0;
52817117f1b4Smrg                  for (i = 0; i < width; i++) {
52827117f1b4Smrg                     if (*s & srcMask) {
52837117f1b4Smrg                        *d |= dstMask;
52847117f1b4Smrg                     }
52857117f1b4Smrg                     if (srcMask == 1) {
52867117f1b4Smrg                        srcMask = 128;
52877117f1b4Smrg                        s++;
52887117f1b4Smrg                     }
52897117f1b4Smrg                     else {
52907117f1b4Smrg                        srcMask = srcMask >> 1;
52917117f1b4Smrg                     }
52927117f1b4Smrg                     if (dstMask == 1) {
52937117f1b4Smrg                        dstMask = 128;
52947117f1b4Smrg                        d++;
52957117f1b4Smrg                        *d = 0;
52967117f1b4Smrg                     }
52977117f1b4Smrg                     else {
52987117f1b4Smrg                        dstMask = dstMask >> 1;
52997117f1b4Smrg                     }
53007117f1b4Smrg                  }
53017117f1b4Smrg               }
53027117f1b4Smrg            }
53037117f1b4Smrg            else {
53047117f1b4Smrg               _mesa_memcpy(dst, src, bytesPerRow);
53057117f1b4Smrg            }
53067117f1b4Smrg
53077117f1b4Smrg            /* byte flipping/swapping */
53087117f1b4Smrg            if (flipBytes) {
53097117f1b4Smrg               flip_bytes((GLubyte *) dst, bytesPerRow);
53107117f1b4Smrg            }
53117117f1b4Smrg            else if (swap2) {
53127117f1b4Smrg               _mesa_swap2((GLushort*) dst, compsPerRow);
53137117f1b4Smrg            }
53147117f1b4Smrg            else if (swap4) {
53157117f1b4Smrg               _mesa_swap4((GLuint*) dst, compsPerRow);
53167117f1b4Smrg            }
53177117f1b4Smrg            dst += bytesPerRow;
53187117f1b4Smrg         }
53197117f1b4Smrg      }
53207117f1b4Smrg      return destBuffer;
53217117f1b4Smrg   }
53227117f1b4Smrg}
53237117f1b4Smrg
53247117f1b4Smrg#endif /* _HAVE_FULL_GL */
53257117f1b4Smrg
53267117f1b4Smrg
53277117f1b4Smrg
53287117f1b4Smrg/**
53297117f1b4Smrg * Convert an array of RGBA colors from one datatype to another.
53307117f1b4Smrg * NOTE: src may equal dst.  In that case, we use a temporary buffer.
53317117f1b4Smrg */
53327117f1b4Smrgvoid
53337117f1b4Smrg_mesa_convert_colors(GLenum srcType, const GLvoid *src,
53347117f1b4Smrg                     GLenum dstType, GLvoid *dst,
53357117f1b4Smrg                     GLuint count, const GLubyte mask[])
53367117f1b4Smrg{
53377117f1b4Smrg   GLuint tempBuffer[MAX_WIDTH][4];
53387117f1b4Smrg   const GLboolean useTemp = (src == dst);
53397117f1b4Smrg
53407117f1b4Smrg   ASSERT(srcType != dstType);
53417117f1b4Smrg
53427117f1b4Smrg   switch (srcType) {
53437117f1b4Smrg   case GL_UNSIGNED_BYTE:
53447117f1b4Smrg      if (dstType == GL_UNSIGNED_SHORT) {
53457117f1b4Smrg         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
53467117f1b4Smrg         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
53477117f1b4Smrg         GLuint i;
53487117f1b4Smrg         for (i = 0; i < count; i++) {
53497117f1b4Smrg            if (!mask || mask[i]) {
53507117f1b4Smrg               dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]);
53517117f1b4Smrg               dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]);
53527117f1b4Smrg               dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]);
53537117f1b4Smrg               dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]);
53547117f1b4Smrg            }
53557117f1b4Smrg         }
53567117f1b4Smrg         if (useTemp)
53577117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
53587117f1b4Smrg      }
53597117f1b4Smrg      else {
53607117f1b4Smrg         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
53617117f1b4Smrg         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
53627117f1b4Smrg         GLuint i;
53637117f1b4Smrg         ASSERT(dstType == GL_FLOAT);
53647117f1b4Smrg         for (i = 0; i < count; i++) {
53657117f1b4Smrg            if (!mask || mask[i]) {
53667117f1b4Smrg               dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]);
53677117f1b4Smrg               dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]);
53687117f1b4Smrg               dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]);
53697117f1b4Smrg               dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]);
53707117f1b4Smrg            }
53717117f1b4Smrg         }
53727117f1b4Smrg         if (useTemp)
53737117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
53747117f1b4Smrg      }
53757117f1b4Smrg      break;
53767117f1b4Smrg   case GL_UNSIGNED_SHORT:
53777117f1b4Smrg      if (dstType == GL_UNSIGNED_BYTE) {
53787117f1b4Smrg         const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
53797117f1b4Smrg         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);
53807117f1b4Smrg         GLuint i;
53817117f1b4Smrg         for (i = 0; i < count; i++) {
53827117f1b4Smrg            if (!mask || mask[i]) {
53837117f1b4Smrg               dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]);
53847117f1b4Smrg               dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]);
53857117f1b4Smrg               dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]);
53867117f1b4Smrg               dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]);
53877117f1b4Smrg            }
53887117f1b4Smrg         }
53897117f1b4Smrg         if (useTemp)
53907117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
53917117f1b4Smrg      }
53927117f1b4Smrg      else {
53937117f1b4Smrg         const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
53947117f1b4Smrg         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
53957117f1b4Smrg         GLuint i;
53967117f1b4Smrg         ASSERT(dstType == GL_FLOAT);
53977117f1b4Smrg         for (i = 0; i < count; i++) {
53987117f1b4Smrg            if (!mask || mask[i]) {
53997117f1b4Smrg               dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]);
54007117f1b4Smrg               dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]);
54017117f1b4Smrg               dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]);
54027117f1b4Smrg               dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]);
54037117f1b4Smrg            }
54047117f1b4Smrg         }
54057117f1b4Smrg         if (useTemp)
54067117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
54077117f1b4Smrg      }
54087117f1b4Smrg      break;
54097117f1b4Smrg   case GL_FLOAT:
54107117f1b4Smrg      if (dstType == GL_UNSIGNED_BYTE) {
54117117f1b4Smrg         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
54127117f1b4Smrg         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);
54137117f1b4Smrg         GLuint i;
54147117f1b4Smrg         for (i = 0; i < count; i++) {
54157117f1b4Smrg            if (!mask || mask[i]) {
54167117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][RCOMP], src4[i][RCOMP]);
54177117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][GCOMP], src4[i][GCOMP]);
54187117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][BCOMP], src4[i][BCOMP]);
54197117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][ACOMP], src4[i][ACOMP]);
54207117f1b4Smrg            }
54217117f1b4Smrg         }
54227117f1b4Smrg         if (useTemp)
54237117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
54247117f1b4Smrg      }
54257117f1b4Smrg      else {
54267117f1b4Smrg         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
54277117f1b4Smrg         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
54287117f1b4Smrg         GLuint i;
54297117f1b4Smrg         ASSERT(dstType == GL_UNSIGNED_SHORT);
54307117f1b4Smrg         for (i = 0; i < count; i++) {
54317117f1b4Smrg            if (!mask || mask[i]) {
54327117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]);
54337117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]);
54347117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]);
54357117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]);
54367117f1b4Smrg            }
54377117f1b4Smrg         }
54387117f1b4Smrg         if (useTemp)
54397117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
54407117f1b4Smrg      }
54417117f1b4Smrg      break;
54427117f1b4Smrg   default:
54437117f1b4Smrg      _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors");
54447117f1b4Smrg   }
54457117f1b4Smrg}
54467117f1b4Smrg
54477117f1b4Smrg
54487117f1b4Smrg
54497117f1b4Smrg
54507117f1b4Smrg/**
54517117f1b4Smrg * Perform basic clipping for glDrawPixels.  The image's position and size
54527117f1b4Smrg * and the unpack SkipPixels and SkipRows are adjusted so that the image
54537117f1b4Smrg * region is entirely within the window and scissor bounds.
54547117f1b4Smrg * NOTE: this will only work when glPixelZoom is (1, 1) or (1, -1).
54557117f1b4Smrg * If Pixel.ZoomY is -1, *destY will be changed to be the first row which
54567117f1b4Smrg * we'll actually write.  Beforehand, *destY-1 is the first drawing row.
54577117f1b4Smrg *
54587117f1b4Smrg * \return  GL_TRUE if image is ready for drawing or
54597117f1b4Smrg *          GL_FALSE if image was completely clipped away (draw nothing)
54607117f1b4Smrg */
54617117f1b4SmrgGLboolean
54627117f1b4Smrg_mesa_clip_drawpixels(const GLcontext *ctx,
54637117f1b4Smrg                      GLint *destX, GLint *destY,
54647117f1b4Smrg                      GLsizei *width, GLsizei *height,
54657117f1b4Smrg                      struct gl_pixelstore_attrib *unpack)
54667117f1b4Smrg{
54677117f1b4Smrg   const GLframebuffer *buffer = ctx->DrawBuffer;
54687117f1b4Smrg
54697117f1b4Smrg   if (unpack->RowLength == 0) {
54707117f1b4Smrg      unpack->RowLength = *width;
54717117f1b4Smrg   }
54727117f1b4Smrg
54737117f1b4Smrg   ASSERT(ctx->Pixel.ZoomX == 1.0F);
54747117f1b4Smrg   ASSERT(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F);
54757117f1b4Smrg
54767117f1b4Smrg   /* left clipping */
54777117f1b4Smrg   if (*destX < buffer->_Xmin) {
54787117f1b4Smrg      unpack->SkipPixels += (buffer->_Xmin - *destX);
54797117f1b4Smrg      *width -= (buffer->_Xmin - *destX);
54807117f1b4Smrg      *destX = buffer->_Xmin;
54817117f1b4Smrg   }
54827117f1b4Smrg   /* right clipping */
54837117f1b4Smrg   if (*destX + *width > buffer->_Xmax)
54847117f1b4Smrg      *width -= (*destX + *width - buffer->_Xmax);
54857117f1b4Smrg
54867117f1b4Smrg   if (*width <= 0)
54877117f1b4Smrg      return GL_FALSE;
54887117f1b4Smrg
54897117f1b4Smrg   if (ctx->Pixel.ZoomY == 1.0F) {
54907117f1b4Smrg      /* bottom clipping */
54917117f1b4Smrg      if (*destY < buffer->_Ymin) {
54927117f1b4Smrg         unpack->SkipRows += (buffer->_Ymin - *destY);
54937117f1b4Smrg         *height -= (buffer->_Ymin - *destY);
54947117f1b4Smrg         *destY = buffer->_Ymin;
54957117f1b4Smrg      }
54967117f1b4Smrg      /* top clipping */
54977117f1b4Smrg      if (*destY + *height > buffer->_Ymax)
54987117f1b4Smrg         *height -= (*destY + *height - buffer->_Ymax);
54997117f1b4Smrg   }
55007117f1b4Smrg   else { /* upside down */
55017117f1b4Smrg      /* top clipping */
55027117f1b4Smrg      if (*destY > buffer->_Ymax) {
55037117f1b4Smrg         unpack->SkipRows += (*destY - buffer->_Ymax);
55047117f1b4Smrg         *height -= (*destY - buffer->_Ymax);
55057117f1b4Smrg         *destY = buffer->_Ymax;
55067117f1b4Smrg      }
55077117f1b4Smrg      /* bottom clipping */
55087117f1b4Smrg      if (*destY - *height < buffer->_Ymin)
55097117f1b4Smrg         *height -= (buffer->_Ymin - (*destY - *height));
55107117f1b4Smrg      /* adjust destY so it's the first row to write to */
55117117f1b4Smrg      (*destY)--;
55127117f1b4Smrg   }
55137117f1b4Smrg
55147117f1b4Smrg   if (*height <= 0)
55154a49301eSmrg      return GL_FALSE;
55167117f1b4Smrg
55177117f1b4Smrg   return GL_TRUE;
55187117f1b4Smrg}
55197117f1b4Smrg
55207117f1b4Smrg
55217117f1b4Smrg/**
55227117f1b4Smrg * Perform clipping for glReadPixels.  The image's window position
55237117f1b4Smrg * and size, and the pack skipPixels, skipRows and rowLength are adjusted
55247117f1b4Smrg * so that the image region is entirely within the window bounds.
55257117f1b4Smrg * Note: this is different from _mesa_clip_drawpixels() in that the
55267117f1b4Smrg * scissor box is ignored, and we use the bounds of the current readbuffer
55277117f1b4Smrg * surface.
55287117f1b4Smrg *
55297117f1b4Smrg * \return  GL_TRUE if image is ready for drawing or
55307117f1b4Smrg *          GL_FALSE if image was completely clipped away (draw nothing)
55317117f1b4Smrg */
55327117f1b4SmrgGLboolean
55337117f1b4Smrg_mesa_clip_readpixels(const GLcontext *ctx,
55347117f1b4Smrg                      GLint *srcX, GLint *srcY,
55357117f1b4Smrg                      GLsizei *width, GLsizei *height,
55367117f1b4Smrg                      struct gl_pixelstore_attrib *pack)
55377117f1b4Smrg{
55387117f1b4Smrg   const GLframebuffer *buffer = ctx->ReadBuffer;
55397117f1b4Smrg
55407117f1b4Smrg   if (pack->RowLength == 0) {
55417117f1b4Smrg      pack->RowLength = *width;
55427117f1b4Smrg   }
55437117f1b4Smrg
55447117f1b4Smrg   /* left clipping */
55457117f1b4Smrg   if (*srcX < 0) {
55467117f1b4Smrg      pack->SkipPixels += (0 - *srcX);
55477117f1b4Smrg      *width -= (0 - *srcX);
55487117f1b4Smrg      *srcX = 0;
55497117f1b4Smrg   }
55507117f1b4Smrg   /* right clipping */
55517117f1b4Smrg   if (*srcX + *width > (GLsizei) buffer->Width)
55527117f1b4Smrg      *width -= (*srcX + *width - buffer->Width);
55537117f1b4Smrg
55547117f1b4Smrg   if (*width <= 0)
55557117f1b4Smrg      return GL_FALSE;
55567117f1b4Smrg
55577117f1b4Smrg   /* bottom clipping */
55587117f1b4Smrg   if (*srcY < 0) {
55597117f1b4Smrg      pack->SkipRows += (0 - *srcY);
55607117f1b4Smrg      *height -= (0 - *srcY);
55617117f1b4Smrg      *srcY = 0;
55627117f1b4Smrg   }
55637117f1b4Smrg   /* top clipping */
55647117f1b4Smrg   if (*srcY + *height > (GLsizei) buffer->Height)
55657117f1b4Smrg      *height -= (*srcY + *height - buffer->Height);
55667117f1b4Smrg
55677117f1b4Smrg   if (*height <= 0)
55684a49301eSmrg      return GL_FALSE;
55697117f1b4Smrg
55707117f1b4Smrg   return GL_TRUE;
55717117f1b4Smrg}
55727117f1b4Smrg
55737117f1b4Smrg
5574c1f859d4Smrg/**
5575c1f859d4Smrg * Do clipping for a glCopyTexSubImage call.
5576c1f859d4Smrg * The framebuffer source region might extend outside the framebuffer
5577c1f859d4Smrg * bounds.  Clip the source region against the framebuffer bounds and
5578c1f859d4Smrg * adjust the texture/dest position and size accordingly.
5579c1f859d4Smrg *
5580c1f859d4Smrg * \return GL_FALSE if region is totally clipped, GL_TRUE otherwise.
5581c1f859d4Smrg */
5582c1f859d4SmrgGLboolean
5583c1f859d4Smrg_mesa_clip_copytexsubimage(const GLcontext *ctx,
5584c1f859d4Smrg                           GLint *destX, GLint *destY,
5585c1f859d4Smrg                           GLint *srcX, GLint *srcY,
5586c1f859d4Smrg                           GLsizei *width, GLsizei *height)
5587c1f859d4Smrg{
5588c1f859d4Smrg   const struct gl_framebuffer *fb = ctx->ReadBuffer;
5589c1f859d4Smrg   const GLint srcX0 = *srcX, srcY0 = *srcY;
5590c1f859d4Smrg
5591c1f859d4Smrg   if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height,
5592c1f859d4Smrg                            srcX, srcY, width, height)) {
5593c1f859d4Smrg      *destX = *destX + *srcX - srcX0;
5594c1f859d4Smrg      *destY = *destY + *srcY - srcY0;
5595c1f859d4Smrg
5596c1f859d4Smrg      return GL_TRUE;
5597c1f859d4Smrg   }
5598c1f859d4Smrg   else {
5599c1f859d4Smrg      return GL_FALSE;
5600c1f859d4Smrg   }
5601c1f859d4Smrg}
5602c1f859d4Smrg
5603c1f859d4Smrg
5604c1f859d4Smrg
56057117f1b4Smrg/**
56067117f1b4Smrg * Clip the rectangle defined by (x, y, width, height) against the bounds
56077117f1b4Smrg * specified by [xmin, xmax) and [ymin, ymax).
56087117f1b4Smrg * \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise.
56097117f1b4Smrg */
56107117f1b4SmrgGLboolean
56117117f1b4Smrg_mesa_clip_to_region(GLint xmin, GLint ymin,
56127117f1b4Smrg                     GLint xmax, GLint ymax,
56137117f1b4Smrg                     GLint *x, GLint *y,
56147117f1b4Smrg                     GLsizei *width, GLsizei *height )
56157117f1b4Smrg{
56167117f1b4Smrg   /* left clipping */
56177117f1b4Smrg   if (*x < xmin) {
56187117f1b4Smrg      *width -= (xmin - *x);
56197117f1b4Smrg      *x = xmin;
56207117f1b4Smrg   }
56217117f1b4Smrg
56227117f1b4Smrg   /* right clipping */
56237117f1b4Smrg   if (*x + *width > xmax)
5624c1f859d4Smrg      *width -= (*x + *width - xmax);
56257117f1b4Smrg
56267117f1b4Smrg   if (*width <= 0)
56277117f1b4Smrg      return GL_FALSE;
56287117f1b4Smrg
56297117f1b4Smrg   /* bottom (or top) clipping */
56307117f1b4Smrg   if (*y < ymin) {
56317117f1b4Smrg      *height -= (ymin - *y);
56327117f1b4Smrg      *y = ymin;
56337117f1b4Smrg   }
56347117f1b4Smrg
56357117f1b4Smrg   /* top (or bottom) clipping */
56367117f1b4Smrg   if (*y + *height > ymax)
5637c1f859d4Smrg      *height -= (*y + *height - ymax);
56387117f1b4Smrg
56397117f1b4Smrg   if (*height <= 0)
56407117f1b4Smrg      return GL_FALSE;
56417117f1b4Smrg
56427117f1b4Smrg   return GL_TRUE;
56437117f1b4Smrg}
56444a49301eSmrg
56454a49301eSmrg
56464a49301eSmrg/**
56474a49301eSmrg * Clip dst coords against Xmax (or Ymax).
56484a49301eSmrg */
56494a49301eSmrgstatic INLINE void
56504a49301eSmrgclip_right_or_top(GLint *srcX0, GLint *srcX1,
56514a49301eSmrg                  GLint *dstX0, GLint *dstX1,
56524a49301eSmrg                  GLint maxValue)
56534a49301eSmrg{
56544a49301eSmrg   GLfloat t, bias;
56554a49301eSmrg
56564a49301eSmrg   if (*dstX1 > maxValue) {
56574a49301eSmrg      /* X1 outside right edge */
56584a49301eSmrg      ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
56594a49301eSmrg      t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
56604a49301eSmrg      /* chop off [t, 1] part */
56614a49301eSmrg      ASSERT(t >= 0.0 && t <= 1.0);
56624a49301eSmrg      *dstX1 = maxValue;
56634a49301eSmrg      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
56644a49301eSmrg      *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
56654a49301eSmrg   }
56664a49301eSmrg   else if (*dstX0 > maxValue) {
56674a49301eSmrg      /* X0 outside right edge */
56684a49301eSmrg      ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
56694a49301eSmrg      t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
56704a49301eSmrg      /* chop off [t, 1] part */
56714a49301eSmrg      ASSERT(t >= 0.0 && t <= 1.0);
56724a49301eSmrg      *dstX0 = maxValue;
56734a49301eSmrg      bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
56744a49301eSmrg      *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
56754a49301eSmrg   }
56764a49301eSmrg}
56774a49301eSmrg
56784a49301eSmrg
56794a49301eSmrg/**
56804a49301eSmrg * Clip dst coords against Xmin (or Ymin).
56814a49301eSmrg */
56824a49301eSmrgstatic INLINE void
56834a49301eSmrgclip_left_or_bottom(GLint *srcX0, GLint *srcX1,
56844a49301eSmrg                    GLint *dstX0, GLint *dstX1,
56854a49301eSmrg                    GLint minValue)
56864a49301eSmrg{
56874a49301eSmrg   GLfloat t, bias;
56884a49301eSmrg
56894a49301eSmrg   if (*dstX0 < minValue) {
56904a49301eSmrg      /* X0 outside left edge */
56914a49301eSmrg      ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
56924a49301eSmrg      t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
56934a49301eSmrg      /* chop off [0, t] part */
56944a49301eSmrg      ASSERT(t >= 0.0 && t <= 1.0);
56954a49301eSmrg      *dstX0 = minValue;
56964a49301eSmrg      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
56974a49301eSmrg      *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
56984a49301eSmrg   }
56994a49301eSmrg   else if (*dstX1 < minValue) {
57004a49301eSmrg      /* X1 outside left edge */
57014a49301eSmrg      ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
57024a49301eSmrg      t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
57034a49301eSmrg      /* chop off [0, t] part */
57044a49301eSmrg      ASSERT(t >= 0.0 && t <= 1.0);
57054a49301eSmrg      *dstX1 = minValue;
57064a49301eSmrg      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
57074a49301eSmrg      *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
57084a49301eSmrg   }
57094a49301eSmrg}
57104a49301eSmrg
57114a49301eSmrg
57124a49301eSmrg/**
57134a49301eSmrg * Do clipping of blit src/dest rectangles.
57144a49301eSmrg * The dest rect is clipped against both the buffer bounds and scissor bounds.
57154a49301eSmrg * The src rect is just clipped against the buffer bounds.
57164a49301eSmrg *
57174a49301eSmrg * When either the src or dest rect is clipped, the other is also clipped
57184a49301eSmrg * proportionately!
57194a49301eSmrg *
57204a49301eSmrg * Note that X0 need not be less than X1 (same for Y) for either the source
57214a49301eSmrg * and dest rects.  That makes the clipping a little trickier.
57224a49301eSmrg *
57234a49301eSmrg * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
57244a49301eSmrg */
57254a49301eSmrgGLboolean
57264a49301eSmrg_mesa_clip_blit(GLcontext *ctx,
57274a49301eSmrg                GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
57284a49301eSmrg                GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
57294a49301eSmrg{
57304a49301eSmrg   const GLint srcXmin = 0;
57314a49301eSmrg   const GLint srcXmax = ctx->ReadBuffer->Width;
57324a49301eSmrg   const GLint srcYmin = 0;
57334a49301eSmrg   const GLint srcYmax = ctx->ReadBuffer->Height;
57344a49301eSmrg
57354a49301eSmrg   /* these include scissor bounds */
57364a49301eSmrg   const GLint dstXmin = ctx->DrawBuffer->_Xmin;
57374a49301eSmrg   const GLint dstXmax = ctx->DrawBuffer->_Xmax;
57384a49301eSmrg   const GLint dstYmin = ctx->DrawBuffer->_Ymin;
57394a49301eSmrg   const GLint dstYmax = ctx->DrawBuffer->_Ymax;
57404a49301eSmrg
57414a49301eSmrg   /*
57424a49301eSmrg   printf("PreClipX:  src: %d .. %d  dst: %d .. %d\n",
57434a49301eSmrg          *srcX0, *srcX1, *dstX0, *dstX1);
57444a49301eSmrg   printf("PreClipY:  src: %d .. %d  dst: %d .. %d\n",
57454a49301eSmrg          *srcY0, *srcY1, *dstY0, *dstY1);
57464a49301eSmrg   */
57474a49301eSmrg
57484a49301eSmrg   /* trivial rejection tests */
57494a49301eSmrg   if (*dstX0 == *dstX1)
57504a49301eSmrg      return GL_FALSE; /* no width */
57514a49301eSmrg   if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
57524a49301eSmrg      return GL_FALSE; /* totally out (left) of bounds */
57534a49301eSmrg   if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
57544a49301eSmrg      return GL_FALSE; /* totally out (right) of bounds */
57554a49301eSmrg
57564a49301eSmrg   if (*dstY0 == *dstY1)
57574a49301eSmrg      return GL_FALSE;
57584a49301eSmrg   if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
57594a49301eSmrg      return GL_FALSE;
57604a49301eSmrg   if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
57614a49301eSmrg      return GL_FALSE;
57624a49301eSmrg
57634a49301eSmrg   if (*srcX0 == *srcX1)
57644a49301eSmrg      return GL_FALSE;
57654a49301eSmrg   if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
57664a49301eSmrg      return GL_FALSE;
57674a49301eSmrg   if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
57684a49301eSmrg      return GL_FALSE;
57694a49301eSmrg
57704a49301eSmrg   if (*srcY0 == *srcY1)
57714a49301eSmrg      return GL_FALSE;
57724a49301eSmrg   if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
57734a49301eSmrg      return GL_FALSE;
57744a49301eSmrg   if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
57754a49301eSmrg      return GL_FALSE;
57764a49301eSmrg
57774a49301eSmrg   /*
57784a49301eSmrg    * dest clip
57794a49301eSmrg    */
57804a49301eSmrg   clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
57814a49301eSmrg   clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
57824a49301eSmrg   clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
57834a49301eSmrg   clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
57844a49301eSmrg
57854a49301eSmrg   /*
57864a49301eSmrg    * src clip (just swap src/dst values from above)
57874a49301eSmrg    */
57884a49301eSmrg   clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
57894a49301eSmrg   clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
57904a49301eSmrg   clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
57914a49301eSmrg   clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
57924a49301eSmrg
57934a49301eSmrg   /*
57944a49301eSmrg   printf("PostClipX: src: %d .. %d  dst: %d .. %d\n",
57954a49301eSmrg          *srcX0, *srcX1, *dstX0, *dstX1);
57964a49301eSmrg   printf("PostClipY: src: %d .. %d  dst: %d .. %d\n",
57974a49301eSmrg          *srcY0, *srcY1, *dstY0, *dstY1);
57984a49301eSmrg   */
57994a49301eSmrg
58004a49301eSmrg   ASSERT(*dstX0 >= dstXmin);
58014a49301eSmrg   ASSERT(*dstX0 <= dstXmax);
58024a49301eSmrg   ASSERT(*dstX1 >= dstXmin);
58034a49301eSmrg   ASSERT(*dstX1 <= dstXmax);
58044a49301eSmrg
58054a49301eSmrg   ASSERT(*dstY0 >= dstYmin);
58064a49301eSmrg   ASSERT(*dstY0 <= dstYmax);
58074a49301eSmrg   ASSERT(*dstY1 >= dstYmin);
58084a49301eSmrg   ASSERT(*dstY1 <= dstYmax);
58094a49301eSmrg
58104a49301eSmrg   ASSERT(*srcX0 >= srcXmin);
58114a49301eSmrg   ASSERT(*srcX0 <= srcXmax);
58124a49301eSmrg   ASSERT(*srcX1 >= srcXmin);
58134a49301eSmrg   ASSERT(*srcX1 <= srcXmax);
58144a49301eSmrg
58154a49301eSmrg   ASSERT(*srcY0 >= srcYmin);
58164a49301eSmrg   ASSERT(*srcY0 <= srcYmax);
58174a49301eSmrg   ASSERT(*srcY1 >= srcYmin);
58184a49301eSmrg   ASSERT(*srcY1 <= srcYmax);
58194a49301eSmrg
58204a49301eSmrg   return GL_TRUE;
58214a49301eSmrg}
5822