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