image.c revision 7117f1b4
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg * Version:  7.0.1
47117f1b4Smrg *
57117f1b4Smrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
67117f1b4Smrg *
77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
87117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
97117f1b4Smrg * to deal in the Software without restriction, including without limitation
107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
127117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
137117f1b4Smrg *
147117f1b4Smrg * The above copyright notice and this permission notice shall be included
157117f1b4Smrg * in all copies or substantial portions of the Software.
167117f1b4Smrg *
177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
207117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
217117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
227117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
267117f1b4Smrg/**
277117f1b4Smrg * \file image.c
287117f1b4Smrg * Image handling.
297117f1b4Smrg */
307117f1b4Smrg
317117f1b4Smrg
327117f1b4Smrg#include "glheader.h"
337117f1b4Smrg#include "colormac.h"
347117f1b4Smrg#include "context.h"
357117f1b4Smrg#include "image.h"
367117f1b4Smrg#include "imports.h"
377117f1b4Smrg#include "histogram.h"
387117f1b4Smrg#include "macros.h"
397117f1b4Smrg#include "pixel.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 */
657117f1b4Smrgstatic GLboolean
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);
1857117f1b4Smrg      case GL_HALF_FLOAT_ARB:
1867117f1b4Smrg	 return sizeof(GLhalfARB);
1877117f1b4Smrg      default:
1887117f1b4Smrg         return -1;
1897117f1b4Smrg   }
1907117f1b4Smrg}
1917117f1b4Smrg
1927117f1b4Smrg
1937117f1b4Smrg/**
1947117f1b4Smrg * Same as _mesa_sizeof_type() but also accepting the packed pixel
1957117f1b4Smrg * format data types.
1967117f1b4Smrg */
1977117f1b4SmrgGLint
1987117f1b4Smrg_mesa_sizeof_packed_type( GLenum type )
1997117f1b4Smrg{
2007117f1b4Smrg   switch (type) {
2017117f1b4Smrg      case GL_BITMAP:
2027117f1b4Smrg	 return 0;
2037117f1b4Smrg      case GL_UNSIGNED_BYTE:
2047117f1b4Smrg         return sizeof(GLubyte);
2057117f1b4Smrg      case GL_BYTE:
2067117f1b4Smrg	 return sizeof(GLbyte);
2077117f1b4Smrg      case GL_UNSIGNED_SHORT:
2087117f1b4Smrg	 return sizeof(GLushort);
2097117f1b4Smrg      case GL_SHORT:
2107117f1b4Smrg	 return sizeof(GLshort);
2117117f1b4Smrg      case GL_UNSIGNED_INT:
2127117f1b4Smrg	 return sizeof(GLuint);
2137117f1b4Smrg      case GL_INT:
2147117f1b4Smrg	 return sizeof(GLint);
2157117f1b4Smrg      case GL_HALF_FLOAT_ARB:
2167117f1b4Smrg	 return sizeof(GLhalfARB);
2177117f1b4Smrg      case GL_FLOAT:
2187117f1b4Smrg	 return sizeof(GLfloat);
2197117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
2207117f1b4Smrg         return sizeof(GLubyte);
2217117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
2227117f1b4Smrg         return sizeof(GLubyte);
2237117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
2247117f1b4Smrg         return sizeof(GLushort);
2257117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
2267117f1b4Smrg         return sizeof(GLushort);
2277117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
2287117f1b4Smrg         return sizeof(GLushort);
2297117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2307117f1b4Smrg         return sizeof(GLushort);
2317117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
2327117f1b4Smrg         return sizeof(GLushort);
2337117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2347117f1b4Smrg         return sizeof(GLushort);
2357117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
2367117f1b4Smrg         return sizeof(GLuint);
2377117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
2387117f1b4Smrg         return sizeof(GLuint);
2397117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
2407117f1b4Smrg         return sizeof(GLuint);
2417117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
2427117f1b4Smrg         return sizeof(GLuint);
2437117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_MESA:
2447117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_REV_MESA:
2457117f1b4Smrg         return sizeof(GLushort);
2467117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT:
2477117f1b4Smrg         return sizeof(GLuint);
2487117f1b4Smrg      default:
2497117f1b4Smrg         return -1;
2507117f1b4Smrg   }
2517117f1b4Smrg}
2527117f1b4Smrg
2537117f1b4Smrg
2547117f1b4Smrg/**
2557117f1b4Smrg * Get the number of components in a pixel format.
2567117f1b4Smrg *
2577117f1b4Smrg * \param format pixel format.
2587117f1b4Smrg *
2597117f1b4Smrg * \return the number of components in the given format, or -1 if a bad format.
2607117f1b4Smrg */
2617117f1b4SmrgGLint
2627117f1b4Smrg_mesa_components_in_format( GLenum format )
2637117f1b4Smrg{
2647117f1b4Smrg   switch (format) {
2657117f1b4Smrg      case GL_COLOR_INDEX:
2667117f1b4Smrg      case GL_COLOR_INDEX1_EXT:
2677117f1b4Smrg      case GL_COLOR_INDEX2_EXT:
2687117f1b4Smrg      case GL_COLOR_INDEX4_EXT:
2697117f1b4Smrg      case GL_COLOR_INDEX8_EXT:
2707117f1b4Smrg      case GL_COLOR_INDEX12_EXT:
2717117f1b4Smrg      case GL_COLOR_INDEX16_EXT:
2727117f1b4Smrg      case GL_STENCIL_INDEX:
2737117f1b4Smrg      case GL_DEPTH_COMPONENT:
2747117f1b4Smrg      case GL_RED:
2757117f1b4Smrg      case GL_GREEN:
2767117f1b4Smrg      case GL_BLUE:
2777117f1b4Smrg      case GL_ALPHA:
2787117f1b4Smrg      case GL_LUMINANCE:
2797117f1b4Smrg      case GL_INTENSITY:
2807117f1b4Smrg         return 1;
2817117f1b4Smrg      case GL_LUMINANCE_ALPHA:
2827117f1b4Smrg	 return 2;
2837117f1b4Smrg      case GL_RGB:
2847117f1b4Smrg	 return 3;
2857117f1b4Smrg      case GL_RGBA:
2867117f1b4Smrg	 return 4;
2877117f1b4Smrg      case GL_BGR:
2887117f1b4Smrg	 return 3;
2897117f1b4Smrg      case GL_BGRA:
2907117f1b4Smrg	 return 4;
2917117f1b4Smrg      case GL_ABGR_EXT:
2927117f1b4Smrg         return 4;
2937117f1b4Smrg      case GL_YCBCR_MESA:
2947117f1b4Smrg         return 2;
2957117f1b4Smrg      case GL_DEPTH_STENCIL_EXT:
2967117f1b4Smrg         return 2;
2977117f1b4Smrg      default:
2987117f1b4Smrg         return -1;
2997117f1b4Smrg   }
3007117f1b4Smrg}
3017117f1b4Smrg
3027117f1b4Smrg
3037117f1b4Smrg/**
3047117f1b4Smrg * Get the bytes per pixel of pixel format type pair.
3057117f1b4Smrg *
3067117f1b4Smrg * \param format pixel format.
3077117f1b4Smrg * \param type pixel type.
3087117f1b4Smrg *
3097117f1b4Smrg * \return bytes per pixel, or -1 if a bad format or type was given.
3107117f1b4Smrg */
3117117f1b4SmrgGLint
3127117f1b4Smrg_mesa_bytes_per_pixel( GLenum format, GLenum type )
3137117f1b4Smrg{
3147117f1b4Smrg   GLint comps = _mesa_components_in_format( format );
3157117f1b4Smrg   if (comps < 0)
3167117f1b4Smrg      return -1;
3177117f1b4Smrg
3187117f1b4Smrg   switch (type) {
3197117f1b4Smrg      case GL_BITMAP:
3207117f1b4Smrg         return 0;  /* special case */
3217117f1b4Smrg      case GL_BYTE:
3227117f1b4Smrg      case GL_UNSIGNED_BYTE:
3237117f1b4Smrg         return comps * sizeof(GLubyte);
3247117f1b4Smrg      case GL_SHORT:
3257117f1b4Smrg      case GL_UNSIGNED_SHORT:
3267117f1b4Smrg         return comps * sizeof(GLshort);
3277117f1b4Smrg      case GL_INT:
3287117f1b4Smrg      case GL_UNSIGNED_INT:
3297117f1b4Smrg         return comps * sizeof(GLint);
3307117f1b4Smrg      case GL_FLOAT:
3317117f1b4Smrg         return comps * sizeof(GLfloat);
3327117f1b4Smrg      case GL_HALF_FLOAT_ARB:
3337117f1b4Smrg         return comps * sizeof(GLhalfARB);
3347117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
3357117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
3367117f1b4Smrg         if (format == GL_RGB || format == GL_BGR)
3377117f1b4Smrg            return sizeof(GLubyte);
3387117f1b4Smrg         else
3397117f1b4Smrg            return -1;  /* error */
3407117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
3417117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
3427117f1b4Smrg         if (format == GL_RGB || format == GL_BGR)
3437117f1b4Smrg            return sizeof(GLushort);
3447117f1b4Smrg         else
3457117f1b4Smrg            return -1;  /* error */
3467117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
3477117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3487117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
3497117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3507117f1b4Smrg         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
3517117f1b4Smrg            return sizeof(GLushort);
3527117f1b4Smrg         else
3537117f1b4Smrg            return -1;
3547117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
3557117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
3567117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
3577117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
3587117f1b4Smrg         if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT)
3597117f1b4Smrg            return sizeof(GLuint);
3607117f1b4Smrg         else
3617117f1b4Smrg            return -1;
3627117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_MESA:
3637117f1b4Smrg      case GL_UNSIGNED_SHORT_8_8_REV_MESA:
3647117f1b4Smrg         if (format == GL_YCBCR_MESA)
3657117f1b4Smrg            return sizeof(GLushort);
3667117f1b4Smrg         else
3677117f1b4Smrg            return -1;
3687117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT:
3697117f1b4Smrg         if (format == GL_DEPTH_STENCIL_EXT)
3707117f1b4Smrg            return sizeof(GLuint);
3717117f1b4Smrg         else
3727117f1b4Smrg            return -1;
3737117f1b4Smrg      default:
3747117f1b4Smrg         return -1;
3757117f1b4Smrg   }
3767117f1b4Smrg}
3777117f1b4Smrg
3787117f1b4Smrg
3797117f1b4Smrg/**
3807117f1b4Smrg * Test for a legal pixel format and type.
3817117f1b4Smrg *
3827117f1b4Smrg * \param format pixel format.
3837117f1b4Smrg * \param type pixel type.
3847117f1b4Smrg *
3857117f1b4Smrg * \return GL_TRUE if the given pixel format and type are legal, or GL_FALSE
3867117f1b4Smrg * otherwise.
3877117f1b4Smrg */
3887117f1b4SmrgGLboolean
3897117f1b4Smrg_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
3907117f1b4Smrg{
3917117f1b4Smrg   switch (format) {
3927117f1b4Smrg      case GL_COLOR_INDEX:
3937117f1b4Smrg      case GL_STENCIL_INDEX:
3947117f1b4Smrg         switch (type) {
3957117f1b4Smrg            case GL_BITMAP:
3967117f1b4Smrg            case GL_BYTE:
3977117f1b4Smrg            case GL_UNSIGNED_BYTE:
3987117f1b4Smrg            case GL_SHORT:
3997117f1b4Smrg            case GL_UNSIGNED_SHORT:
4007117f1b4Smrg            case GL_INT:
4017117f1b4Smrg            case GL_UNSIGNED_INT:
4027117f1b4Smrg            case GL_FLOAT:
4037117f1b4Smrg               return GL_TRUE;
4047117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4057117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4067117f1b4Smrg            default:
4077117f1b4Smrg               return GL_FALSE;
4087117f1b4Smrg         }
4097117f1b4Smrg      case GL_RED:
4107117f1b4Smrg      case GL_GREEN:
4117117f1b4Smrg      case GL_BLUE:
4127117f1b4Smrg      case GL_ALPHA:
4137117f1b4Smrg#if 0 /* not legal!  see table 3.6 of the 1.5 spec */
4147117f1b4Smrg      case GL_INTENSITY:
4157117f1b4Smrg#endif
4167117f1b4Smrg      case GL_LUMINANCE:
4177117f1b4Smrg      case GL_LUMINANCE_ALPHA:
4187117f1b4Smrg      case GL_DEPTH_COMPONENT:
4197117f1b4Smrg         switch (type) {
4207117f1b4Smrg            case GL_BYTE:
4217117f1b4Smrg            case GL_UNSIGNED_BYTE:
4227117f1b4Smrg            case GL_SHORT:
4237117f1b4Smrg            case GL_UNSIGNED_SHORT:
4247117f1b4Smrg            case GL_INT:
4257117f1b4Smrg            case GL_UNSIGNED_INT:
4267117f1b4Smrg            case GL_FLOAT:
4277117f1b4Smrg               return GL_TRUE;
4287117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4297117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4307117f1b4Smrg            default:
4317117f1b4Smrg               return GL_FALSE;
4327117f1b4Smrg         }
4337117f1b4Smrg      case GL_RGB:
4347117f1b4Smrg         switch (type) {
4357117f1b4Smrg            case GL_BYTE:
4367117f1b4Smrg            case GL_UNSIGNED_BYTE:
4377117f1b4Smrg            case GL_SHORT:
4387117f1b4Smrg            case GL_UNSIGNED_SHORT:
4397117f1b4Smrg            case GL_INT:
4407117f1b4Smrg            case GL_UNSIGNED_INT:
4417117f1b4Smrg            case GL_FLOAT:
4427117f1b4Smrg            case GL_UNSIGNED_BYTE_3_3_2:
4437117f1b4Smrg            case GL_UNSIGNED_BYTE_2_3_3_REV:
4447117f1b4Smrg            case GL_UNSIGNED_SHORT_5_6_5:
4457117f1b4Smrg            case GL_UNSIGNED_SHORT_5_6_5_REV:
4467117f1b4Smrg               return GL_TRUE;
4477117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4487117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4497117f1b4Smrg            default:
4507117f1b4Smrg               return GL_FALSE;
4517117f1b4Smrg         }
4527117f1b4Smrg      case GL_BGR:
4537117f1b4Smrg         switch (type) {
4547117f1b4Smrg            /* NOTE: no packed types are supported with BGR.  That's
4557117f1b4Smrg             * intentional, according to the GL spec.
4567117f1b4Smrg             */
4577117f1b4Smrg            case GL_BYTE:
4587117f1b4Smrg            case GL_UNSIGNED_BYTE:
4597117f1b4Smrg            case GL_SHORT:
4607117f1b4Smrg            case GL_UNSIGNED_SHORT:
4617117f1b4Smrg            case GL_INT:
4627117f1b4Smrg            case GL_UNSIGNED_INT:
4637117f1b4Smrg            case GL_FLOAT:
4647117f1b4Smrg               return GL_TRUE;
4657117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4667117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4677117f1b4Smrg            default:
4687117f1b4Smrg               return GL_FALSE;
4697117f1b4Smrg         }
4707117f1b4Smrg      case GL_RGBA:
4717117f1b4Smrg      case GL_BGRA:
4727117f1b4Smrg      case GL_ABGR_EXT:
4737117f1b4Smrg         switch (type) {
4747117f1b4Smrg            case GL_BYTE:
4757117f1b4Smrg            case GL_UNSIGNED_BYTE:
4767117f1b4Smrg            case GL_SHORT:
4777117f1b4Smrg            case GL_UNSIGNED_SHORT:
4787117f1b4Smrg            case GL_INT:
4797117f1b4Smrg            case GL_UNSIGNED_INT:
4807117f1b4Smrg            case GL_FLOAT:
4817117f1b4Smrg            case GL_UNSIGNED_SHORT_4_4_4_4:
4827117f1b4Smrg            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4837117f1b4Smrg            case GL_UNSIGNED_SHORT_5_5_5_1:
4847117f1b4Smrg            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4857117f1b4Smrg            case GL_UNSIGNED_INT_8_8_8_8:
4867117f1b4Smrg            case GL_UNSIGNED_INT_8_8_8_8_REV:
4877117f1b4Smrg            case GL_UNSIGNED_INT_10_10_10_2:
4887117f1b4Smrg            case GL_UNSIGNED_INT_2_10_10_10_REV:
4897117f1b4Smrg               return GL_TRUE;
4907117f1b4Smrg            case GL_HALF_FLOAT_ARB:
4917117f1b4Smrg               return ctx->Extensions.ARB_half_float_pixel;
4927117f1b4Smrg            default:
4937117f1b4Smrg               return GL_FALSE;
4947117f1b4Smrg         }
4957117f1b4Smrg      case GL_YCBCR_MESA:
4967117f1b4Smrg         if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
4977117f1b4Smrg             type == GL_UNSIGNED_SHORT_8_8_REV_MESA)
4987117f1b4Smrg            return GL_TRUE;
4997117f1b4Smrg         else
5007117f1b4Smrg            return GL_FALSE;
5017117f1b4Smrg      case GL_DEPTH_STENCIL_EXT:
5027117f1b4Smrg         if (ctx->Extensions.EXT_packed_depth_stencil
5037117f1b4Smrg             && type == GL_UNSIGNED_INT_24_8_EXT)
5047117f1b4Smrg            return GL_TRUE;
5057117f1b4Smrg         else
5067117f1b4Smrg            return GL_FALSE;
5077117f1b4Smrg      default:
5087117f1b4Smrg         ; /* fall-through */
5097117f1b4Smrg   }
5107117f1b4Smrg   return GL_FALSE;
5117117f1b4Smrg}
5127117f1b4Smrg
5137117f1b4Smrg
5147117f1b4Smrg/**
5157117f1b4Smrg * Return the address of a specific pixel in an image (1D, 2D or 3D).
5167117f1b4Smrg *
5177117f1b4Smrg * Pixel unpacking/packing parameters are observed according to \p packing.
5187117f1b4Smrg *
5197117f1b4Smrg * \param dimensions either 1, 2 or 3 to indicate dimensionality of image
5207117f1b4Smrg * \param image  starting address of image data
5217117f1b4Smrg * \param width  the image width
5227117f1b4Smrg * \param height  theimage height
5237117f1b4Smrg * \param format  the pixel format
5247117f1b4Smrg * \param type  the pixel data type
5257117f1b4Smrg * \param packing  the pixelstore attributes
5267117f1b4Smrg * \param img  which image in the volume (0 for 1D or 2D images)
5277117f1b4Smrg * \param row  row of pixel in the image (0 for 1D images)
5287117f1b4Smrg * \param column column of pixel in the image
5297117f1b4Smrg *
5307117f1b4Smrg * \return address of pixel on success, or NULL on error.
5317117f1b4Smrg *
5327117f1b4Smrg * \sa gl_pixelstore_attrib.
5337117f1b4Smrg */
5347117f1b4SmrgGLvoid *
5357117f1b4Smrg_mesa_image_address( GLuint dimensions,
5367117f1b4Smrg                     const struct gl_pixelstore_attrib *packing,
5377117f1b4Smrg                     const GLvoid *image,
5387117f1b4Smrg                     GLsizei width, GLsizei height,
5397117f1b4Smrg                     GLenum format, GLenum type,
5407117f1b4Smrg                     GLint img, GLint row, GLint column )
5417117f1b4Smrg{
5427117f1b4Smrg   GLint alignment;        /* 1, 2 or 4 */
5437117f1b4Smrg   GLint pixels_per_row;
5447117f1b4Smrg   GLint rows_per_image;
5457117f1b4Smrg   GLint skiprows;
5467117f1b4Smrg   GLint skippixels;
5477117f1b4Smrg   GLint skipimages;       /* for 3-D volume images */
5487117f1b4Smrg   GLubyte *pixel_addr;
5497117f1b4Smrg
5507117f1b4Smrg   ASSERT(dimensions >= 1 && dimensions <= 3);
5517117f1b4Smrg
5527117f1b4Smrg   alignment = packing->Alignment;
5537117f1b4Smrg   if (packing->RowLength > 0) {
5547117f1b4Smrg      pixels_per_row = packing->RowLength;
5557117f1b4Smrg   }
5567117f1b4Smrg   else {
5577117f1b4Smrg      pixels_per_row = width;
5587117f1b4Smrg   }
5597117f1b4Smrg   if (packing->ImageHeight > 0) {
5607117f1b4Smrg      rows_per_image = packing->ImageHeight;
5617117f1b4Smrg   }
5627117f1b4Smrg   else {
5637117f1b4Smrg      rows_per_image = height;
5647117f1b4Smrg   }
5657117f1b4Smrg
5667117f1b4Smrg   skippixels = packing->SkipPixels;
5677117f1b4Smrg   /* Note: SKIP_ROWS _is_ used for 1D images */
5687117f1b4Smrg   skiprows = packing->SkipRows;
5697117f1b4Smrg   /* Note: SKIP_IMAGES is only used for 3D images */
5707117f1b4Smrg   skipimages = (dimensions == 3) ? packing->SkipImages : 0;
5717117f1b4Smrg
5727117f1b4Smrg   if (type == GL_BITMAP) {
5737117f1b4Smrg      /* BITMAP data */
5747117f1b4Smrg      GLint comp_per_pixel;   /* components per pixel */
5757117f1b4Smrg      GLint bytes_per_comp;   /* bytes per component */
5767117f1b4Smrg      GLint bytes_per_row;
5777117f1b4Smrg      GLint bytes_per_image;
5787117f1b4Smrg
5797117f1b4Smrg      /* Compute bytes per component */
5807117f1b4Smrg      bytes_per_comp = _mesa_sizeof_packed_type( type );
5817117f1b4Smrg      if (bytes_per_comp < 0) {
5827117f1b4Smrg         return NULL;
5837117f1b4Smrg      }
5847117f1b4Smrg
5857117f1b4Smrg      /* Compute number of components per pixel */
5867117f1b4Smrg      comp_per_pixel = _mesa_components_in_format( format );
5877117f1b4Smrg      if (comp_per_pixel < 0) {
5887117f1b4Smrg         return NULL;
5897117f1b4Smrg      }
5907117f1b4Smrg
5917117f1b4Smrg      bytes_per_row = alignment
5927117f1b4Smrg                    * CEILING( comp_per_pixel*pixels_per_row, 8*alignment );
5937117f1b4Smrg
5947117f1b4Smrg      bytes_per_image = bytes_per_row * rows_per_image;
5957117f1b4Smrg
5967117f1b4Smrg      pixel_addr = (GLubyte *) image
5977117f1b4Smrg                 + (skipimages + img) * bytes_per_image
5987117f1b4Smrg                 + (skiprows + row) * bytes_per_row
5997117f1b4Smrg                 + (skippixels + column) / 8;
6007117f1b4Smrg   }
6017117f1b4Smrg   else {
6027117f1b4Smrg      /* Non-BITMAP data */
6037117f1b4Smrg      GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image;
6047117f1b4Smrg      GLint topOfImage;
6057117f1b4Smrg
6067117f1b4Smrg      bytes_per_pixel = _mesa_bytes_per_pixel( format, type );
6077117f1b4Smrg
6087117f1b4Smrg      /* The pixel type and format should have been error checked earlier */
6097117f1b4Smrg      assert(bytes_per_pixel > 0);
6107117f1b4Smrg
6117117f1b4Smrg      bytes_per_row = pixels_per_row * bytes_per_pixel;
6127117f1b4Smrg      remainder = bytes_per_row % alignment;
6137117f1b4Smrg      if (remainder > 0)
6147117f1b4Smrg         bytes_per_row += (alignment - remainder);
6157117f1b4Smrg
6167117f1b4Smrg      ASSERT(bytes_per_row % alignment == 0);
6177117f1b4Smrg
6187117f1b4Smrg      bytes_per_image = bytes_per_row * rows_per_image;
6197117f1b4Smrg
6207117f1b4Smrg      if (packing->Invert) {
6217117f1b4Smrg         /* set pixel_addr to the last row */
6227117f1b4Smrg         topOfImage = bytes_per_row * (height - 1);
6237117f1b4Smrg         bytes_per_row = -bytes_per_row;
6247117f1b4Smrg      }
6257117f1b4Smrg      else {
6267117f1b4Smrg         topOfImage = 0;
6277117f1b4Smrg      }
6287117f1b4Smrg
6297117f1b4Smrg      /* compute final pixel address */
6307117f1b4Smrg      pixel_addr = (GLubyte *) image
6317117f1b4Smrg                 + (skipimages + img) * bytes_per_image
6327117f1b4Smrg                 + topOfImage
6337117f1b4Smrg                 + (skiprows + row) * bytes_per_row
6347117f1b4Smrg                 + (skippixels + column) * bytes_per_pixel;
6357117f1b4Smrg   }
6367117f1b4Smrg
6377117f1b4Smrg   return (GLvoid *) pixel_addr;
6387117f1b4Smrg}
6397117f1b4Smrg
6407117f1b4Smrg
6417117f1b4SmrgGLvoid *
6427117f1b4Smrg_mesa_image_address1d( const struct gl_pixelstore_attrib *packing,
6437117f1b4Smrg                       const GLvoid *image,
6447117f1b4Smrg                       GLsizei width,
6457117f1b4Smrg                       GLenum format, GLenum type,
6467117f1b4Smrg                       GLint column )
6477117f1b4Smrg{
6487117f1b4Smrg   return _mesa_image_address(1, packing, image, width, 1,
6497117f1b4Smrg                              format, type, 0, 0, column);
6507117f1b4Smrg}
6517117f1b4Smrg
6527117f1b4Smrg
6537117f1b4SmrgGLvoid *
6547117f1b4Smrg_mesa_image_address2d( const struct gl_pixelstore_attrib *packing,
6557117f1b4Smrg                       const GLvoid *image,
6567117f1b4Smrg                       GLsizei width, GLsizei height,
6577117f1b4Smrg                       GLenum format, GLenum type,
6587117f1b4Smrg                       GLint row, GLint column )
6597117f1b4Smrg{
6607117f1b4Smrg   return _mesa_image_address(2, packing, image, width, height,
6617117f1b4Smrg                              format, type, 0, row, column);
6627117f1b4Smrg}
6637117f1b4Smrg
6647117f1b4Smrg
6657117f1b4SmrgGLvoid *
6667117f1b4Smrg_mesa_image_address3d( const struct gl_pixelstore_attrib *packing,
6677117f1b4Smrg                       const GLvoid *image,
6687117f1b4Smrg                       GLsizei width, GLsizei height,
6697117f1b4Smrg                       GLenum format, GLenum type,
6707117f1b4Smrg                       GLint img, GLint row, GLint column )
6717117f1b4Smrg{
6727117f1b4Smrg   return _mesa_image_address(3, packing, image, width, height,
6737117f1b4Smrg                              format, type, img, row, column);
6747117f1b4Smrg}
6757117f1b4Smrg
6767117f1b4Smrg
6777117f1b4Smrg
6787117f1b4Smrg/**
6797117f1b4Smrg * Compute the stride (in bytes) between image rows.
6807117f1b4Smrg *
6817117f1b4Smrg * \param packing the pixelstore attributes
6827117f1b4Smrg * \param width image width.
6837117f1b4Smrg * \param format pixel format.
6847117f1b4Smrg * \param type pixel data type.
6857117f1b4Smrg *
6867117f1b4Smrg * \return the stride in bytes for the given parameters, or -1 if error
6877117f1b4Smrg */
6887117f1b4SmrgGLint
6897117f1b4Smrg_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing,
6907117f1b4Smrg                        GLint width, GLenum format, GLenum type )
6917117f1b4Smrg{
6927117f1b4Smrg   GLint bytesPerRow, remainder;
6937117f1b4Smrg
6947117f1b4Smrg   ASSERT(packing);
6957117f1b4Smrg
6967117f1b4Smrg   if (type == GL_BITMAP) {
6977117f1b4Smrg      if (packing->RowLength == 0) {
6987117f1b4Smrg         bytesPerRow = (width + 7) / 8;
6997117f1b4Smrg      }
7007117f1b4Smrg      else {
7017117f1b4Smrg         bytesPerRow = (packing->RowLength + 7) / 8;
7027117f1b4Smrg      }
7037117f1b4Smrg   }
7047117f1b4Smrg   else {
7057117f1b4Smrg      /* Non-BITMAP data */
7067117f1b4Smrg      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
7077117f1b4Smrg      if (bytesPerPixel <= 0)
7087117f1b4Smrg         return -1;  /* error */
7097117f1b4Smrg      if (packing->RowLength == 0) {
7107117f1b4Smrg         bytesPerRow = bytesPerPixel * width;
7117117f1b4Smrg      }
7127117f1b4Smrg      else {
7137117f1b4Smrg         bytesPerRow = bytesPerPixel * packing->RowLength;
7147117f1b4Smrg      }
7157117f1b4Smrg   }
7167117f1b4Smrg
7177117f1b4Smrg   remainder = bytesPerRow % packing->Alignment;
7187117f1b4Smrg   if (remainder > 0) {
7197117f1b4Smrg      bytesPerRow += (packing->Alignment - remainder);
7207117f1b4Smrg   }
7217117f1b4Smrg
7227117f1b4Smrg   if (packing->Invert) {
7237117f1b4Smrg      /* negate the bytes per row (negative row stride) */
7247117f1b4Smrg      bytesPerRow = -bytesPerRow;
7257117f1b4Smrg   }
7267117f1b4Smrg
7277117f1b4Smrg   return bytesPerRow;
7287117f1b4Smrg}
7297117f1b4Smrg
7307117f1b4Smrg
7317117f1b4Smrg#if _HAVE_FULL_GL
7327117f1b4Smrg
7337117f1b4Smrg/*
7347117f1b4Smrg * Compute the stride between images in a 3D texture (in bytes) for the given
7357117f1b4Smrg * pixel packing parameters and image width, format and type.
7367117f1b4Smrg */
7377117f1b4SmrgGLint
7387117f1b4Smrg_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing,
7397117f1b4Smrg                          GLint width, GLint height,
7407117f1b4Smrg                          GLenum format, GLenum type )
7417117f1b4Smrg{
7427117f1b4Smrg   ASSERT(packing);
7437117f1b4Smrg   ASSERT(type != GL_BITMAP);
7447117f1b4Smrg
7457117f1b4Smrg   {
7467117f1b4Smrg      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
7477117f1b4Smrg      GLint bytesPerRow, bytesPerImage, remainder;
7487117f1b4Smrg
7497117f1b4Smrg      if (bytesPerPixel <= 0)
7507117f1b4Smrg         return -1;  /* error */
7517117f1b4Smrg      if (packing->RowLength == 0) {
7527117f1b4Smrg         bytesPerRow = bytesPerPixel * width;
7537117f1b4Smrg      }
7547117f1b4Smrg      else {
7557117f1b4Smrg         bytesPerRow = bytesPerPixel * packing->RowLength;
7567117f1b4Smrg      }
7577117f1b4Smrg      remainder = bytesPerRow % packing->Alignment;
7587117f1b4Smrg      if (remainder > 0)
7597117f1b4Smrg         bytesPerRow += (packing->Alignment - remainder);
7607117f1b4Smrg
7617117f1b4Smrg      if (packing->ImageHeight == 0)
7627117f1b4Smrg         bytesPerImage = bytesPerRow * height;
7637117f1b4Smrg      else
7647117f1b4Smrg         bytesPerImage = bytesPerRow * packing->ImageHeight;
7657117f1b4Smrg
7667117f1b4Smrg      return bytesPerImage;
7677117f1b4Smrg   }
7687117f1b4Smrg}
7697117f1b4Smrg
7707117f1b4Smrg
7717117f1b4Smrg/*
7727117f1b4Smrg * Unpack a 32x32 pixel polygon stipple from user memory using the
7737117f1b4Smrg * current pixel unpack settings.
7747117f1b4Smrg */
7757117f1b4Smrgvoid
7767117f1b4Smrg_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
7777117f1b4Smrg                              const struct gl_pixelstore_attrib *unpacking )
7787117f1b4Smrg{
7797117f1b4Smrg   GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap(32, 32, pattern, unpacking);
7807117f1b4Smrg   if (ptrn) {
7817117f1b4Smrg      /* Convert pattern from GLubytes to GLuints and handle big/little
7827117f1b4Smrg       * endian differences
7837117f1b4Smrg       */
7847117f1b4Smrg      GLubyte *p = ptrn;
7857117f1b4Smrg      GLint i;
7867117f1b4Smrg      for (i = 0; i < 32; i++) {
7877117f1b4Smrg         dest[i] = (p[0] << 24)
7887117f1b4Smrg                 | (p[1] << 16)
7897117f1b4Smrg                 | (p[2] <<  8)
7907117f1b4Smrg                 | (p[3]      );
7917117f1b4Smrg         p += 4;
7927117f1b4Smrg      }
7937117f1b4Smrg      _mesa_free(ptrn);
7947117f1b4Smrg   }
7957117f1b4Smrg}
7967117f1b4Smrg
7977117f1b4Smrg
7987117f1b4Smrg/*
7997117f1b4Smrg * Pack polygon stipple into user memory given current pixel packing
8007117f1b4Smrg * settings.
8017117f1b4Smrg */
8027117f1b4Smrgvoid
8037117f1b4Smrg_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
8047117f1b4Smrg                            const struct gl_pixelstore_attrib *packing )
8057117f1b4Smrg{
8067117f1b4Smrg   /* Convert pattern from GLuints to GLubytes to handle big/little
8077117f1b4Smrg    * endian differences.
8087117f1b4Smrg    */
8097117f1b4Smrg   GLubyte ptrn[32*4];
8107117f1b4Smrg   GLint i;
8117117f1b4Smrg   for (i = 0; i < 32; i++) {
8127117f1b4Smrg      ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
8137117f1b4Smrg      ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
8147117f1b4Smrg      ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
8157117f1b4Smrg      ptrn[i * 4 + 3] = (GLubyte) ((pattern[i]      ) & 0xff);
8167117f1b4Smrg   }
8177117f1b4Smrg
8187117f1b4Smrg   _mesa_pack_bitmap(32, 32, ptrn, dest, packing);
8197117f1b4Smrg}
8207117f1b4Smrg
8217117f1b4Smrg
8227117f1b4Smrg/*
8237117f1b4Smrg * Unpack bitmap data.  Resulting data will be in most-significant-bit-first
8247117f1b4Smrg * order with row alignment = 1 byte.
8257117f1b4Smrg */
8267117f1b4SmrgGLvoid *
8277117f1b4Smrg_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
8287117f1b4Smrg                     const struct gl_pixelstore_attrib *packing )
8297117f1b4Smrg{
8307117f1b4Smrg   GLint bytes, row, width_in_bytes;
8317117f1b4Smrg   GLubyte *buffer, *dst;
8327117f1b4Smrg
8337117f1b4Smrg   if (!pixels)
8347117f1b4Smrg      return NULL;
8357117f1b4Smrg
8367117f1b4Smrg   /* Alloc dest storage */
8377117f1b4Smrg   bytes = ((width + 7) / 8 * height);
8387117f1b4Smrg   buffer = (GLubyte *) _mesa_malloc( bytes );
8397117f1b4Smrg   if (!buffer)
8407117f1b4Smrg      return NULL;
8417117f1b4Smrg
8427117f1b4Smrg   width_in_bytes = CEILING( width, 8 );
8437117f1b4Smrg   dst = buffer;
8447117f1b4Smrg   for (row = 0; row < height; row++) {
8457117f1b4Smrg      const GLubyte *src = (const GLubyte *)
8467117f1b4Smrg         _mesa_image_address2d(packing, pixels, width, height,
8477117f1b4Smrg                               GL_COLOR_INDEX, GL_BITMAP, row, 0);
8487117f1b4Smrg      if (!src) {
8497117f1b4Smrg         _mesa_free(buffer);
8507117f1b4Smrg         return NULL;
8517117f1b4Smrg      }
8527117f1b4Smrg
8537117f1b4Smrg      if ((packing->SkipPixels & 7) == 0) {
8547117f1b4Smrg         _mesa_memcpy( dst, src, width_in_bytes );
8557117f1b4Smrg         if (packing->LsbFirst) {
8567117f1b4Smrg            flip_bytes( dst, width_in_bytes );
8577117f1b4Smrg         }
8587117f1b4Smrg      }
8597117f1b4Smrg      else {
8607117f1b4Smrg         /* handling SkipPixels is a bit tricky (no pun intended!) */
8617117f1b4Smrg         GLint i;
8627117f1b4Smrg         if (packing->LsbFirst) {
8637117f1b4Smrg            GLubyte srcMask = 1 << (packing->SkipPixels & 0x7);
8647117f1b4Smrg            GLubyte dstMask = 128;
8657117f1b4Smrg            const GLubyte *s = src;
8667117f1b4Smrg            GLubyte *d = dst;
8677117f1b4Smrg            *d = 0;
8687117f1b4Smrg            for (i = 0; i < width; i++) {
8697117f1b4Smrg               if (*s & srcMask) {
8707117f1b4Smrg                  *d |= dstMask;
8717117f1b4Smrg               }
8727117f1b4Smrg               if (srcMask == 128) {
8737117f1b4Smrg                  srcMask = 1;
8747117f1b4Smrg                  s++;
8757117f1b4Smrg               }
8767117f1b4Smrg               else {
8777117f1b4Smrg                  srcMask = srcMask << 1;
8787117f1b4Smrg               }
8797117f1b4Smrg               if (dstMask == 1) {
8807117f1b4Smrg                  dstMask = 128;
8817117f1b4Smrg                  d++;
8827117f1b4Smrg                  *d = 0;
8837117f1b4Smrg               }
8847117f1b4Smrg               else {
8857117f1b4Smrg                  dstMask = dstMask >> 1;
8867117f1b4Smrg               }
8877117f1b4Smrg            }
8887117f1b4Smrg         }
8897117f1b4Smrg         else {
8907117f1b4Smrg            GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7);
8917117f1b4Smrg            GLubyte dstMask = 128;
8927117f1b4Smrg            const GLubyte *s = src;
8937117f1b4Smrg            GLubyte *d = dst;
8947117f1b4Smrg            *d = 0;
8957117f1b4Smrg            for (i = 0; i < width; i++) {
8967117f1b4Smrg               if (*s & srcMask) {
8977117f1b4Smrg                  *d |= dstMask;
8987117f1b4Smrg               }
8997117f1b4Smrg               if (srcMask == 1) {
9007117f1b4Smrg                  srcMask = 128;
9017117f1b4Smrg                  s++;
9027117f1b4Smrg               }
9037117f1b4Smrg               else {
9047117f1b4Smrg                  srcMask = srcMask >> 1;
9057117f1b4Smrg               }
9067117f1b4Smrg               if (dstMask == 1) {
9077117f1b4Smrg                  dstMask = 128;
9087117f1b4Smrg                  d++;
9097117f1b4Smrg                  *d = 0;
9107117f1b4Smrg               }
9117117f1b4Smrg               else {
9127117f1b4Smrg                  dstMask = dstMask >> 1;
9137117f1b4Smrg               }
9147117f1b4Smrg            }
9157117f1b4Smrg         }
9167117f1b4Smrg      }
9177117f1b4Smrg      dst += width_in_bytes;
9187117f1b4Smrg   }
9197117f1b4Smrg
9207117f1b4Smrg   return buffer;
9217117f1b4Smrg}
9227117f1b4Smrg
9237117f1b4Smrg
9247117f1b4Smrg/*
9257117f1b4Smrg * Pack bitmap data.
9267117f1b4Smrg */
9277117f1b4Smrgvoid
9287117f1b4Smrg_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
9297117f1b4Smrg                   GLubyte *dest, const struct gl_pixelstore_attrib *packing )
9307117f1b4Smrg{
9317117f1b4Smrg   GLint row, width_in_bytes;
9327117f1b4Smrg   const GLubyte *src;
9337117f1b4Smrg
9347117f1b4Smrg   if (!source)
9357117f1b4Smrg      return;
9367117f1b4Smrg
9377117f1b4Smrg   width_in_bytes = CEILING( width, 8 );
9387117f1b4Smrg   src = source;
9397117f1b4Smrg   for (row = 0; row < height; row++) {
9407117f1b4Smrg      GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
9417117f1b4Smrg                       width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
9427117f1b4Smrg      if (!dst)
9437117f1b4Smrg         return;
9447117f1b4Smrg
9457117f1b4Smrg      if ((packing->SkipPixels & 7) == 0) {
9467117f1b4Smrg         _mesa_memcpy( dst, src, width_in_bytes );
9477117f1b4Smrg         if (packing->LsbFirst) {
9487117f1b4Smrg            flip_bytes( dst, width_in_bytes );
9497117f1b4Smrg         }
9507117f1b4Smrg      }
9517117f1b4Smrg      else {
9527117f1b4Smrg         /* handling SkipPixels is a bit tricky (no pun intended!) */
9537117f1b4Smrg         GLint i;
9547117f1b4Smrg         if (packing->LsbFirst) {
9557117f1b4Smrg            GLubyte srcMask = 128;
9567117f1b4Smrg            GLubyte dstMask = 1 << (packing->SkipPixels & 0x7);
9577117f1b4Smrg            const GLubyte *s = src;
9587117f1b4Smrg            GLubyte *d = dst;
9597117f1b4Smrg            *d = 0;
9607117f1b4Smrg            for (i = 0; i < width; i++) {
9617117f1b4Smrg               if (*s & srcMask) {
9627117f1b4Smrg                  *d |= dstMask;
9637117f1b4Smrg               }
9647117f1b4Smrg               if (srcMask == 1) {
9657117f1b4Smrg                  srcMask = 128;
9667117f1b4Smrg                  s++;
9677117f1b4Smrg               }
9687117f1b4Smrg               else {
9697117f1b4Smrg                  srcMask = srcMask >> 1;
9707117f1b4Smrg               }
9717117f1b4Smrg               if (dstMask == 128) {
9727117f1b4Smrg                  dstMask = 1;
9737117f1b4Smrg                  d++;
9747117f1b4Smrg                  *d = 0;
9757117f1b4Smrg               }
9767117f1b4Smrg               else {
9777117f1b4Smrg                  dstMask = dstMask << 1;
9787117f1b4Smrg               }
9797117f1b4Smrg            }
9807117f1b4Smrg         }
9817117f1b4Smrg         else {
9827117f1b4Smrg            GLubyte srcMask = 128;
9837117f1b4Smrg            GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7);
9847117f1b4Smrg            const GLubyte *s = src;
9857117f1b4Smrg            GLubyte *d = dst;
9867117f1b4Smrg            *d = 0;
9877117f1b4Smrg            for (i = 0; i < width; i++) {
9887117f1b4Smrg               if (*s & srcMask) {
9897117f1b4Smrg                  *d |= dstMask;
9907117f1b4Smrg               }
9917117f1b4Smrg               if (srcMask == 1) {
9927117f1b4Smrg                  srcMask = 128;
9937117f1b4Smrg                  s++;
9947117f1b4Smrg               }
9957117f1b4Smrg               else {
9967117f1b4Smrg                  srcMask = srcMask >> 1;
9977117f1b4Smrg               }
9987117f1b4Smrg               if (dstMask == 1) {
9997117f1b4Smrg                  dstMask = 128;
10007117f1b4Smrg                  d++;
10017117f1b4Smrg                  *d = 0;
10027117f1b4Smrg               }
10037117f1b4Smrg               else {
10047117f1b4Smrg                  dstMask = dstMask >> 1;
10057117f1b4Smrg               }
10067117f1b4Smrg            }
10077117f1b4Smrg         }
10087117f1b4Smrg      }
10097117f1b4Smrg      src += width_in_bytes;
10107117f1b4Smrg   }
10117117f1b4Smrg}
10127117f1b4Smrg
10137117f1b4Smrg
10147117f1b4Smrg/**
10157117f1b4Smrg * Apply various pixel transfer operations to an array of RGBA pixels
10167117f1b4Smrg * as indicated by the transferOps bitmask
10177117f1b4Smrg */
10187117f1b4Smrgvoid
10197117f1b4Smrg_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLbitfield transferOps,
10207117f1b4Smrg                              GLuint n, GLfloat rgba[][4])
10217117f1b4Smrg{
10227117f1b4Smrg   /* scale & bias */
10237117f1b4Smrg   if (transferOps & IMAGE_SCALE_BIAS_BIT) {
10247117f1b4Smrg      _mesa_scale_and_bias_rgba(n, rgba,
10257117f1b4Smrg                                ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
10267117f1b4Smrg                                ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
10277117f1b4Smrg                                ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
10287117f1b4Smrg                                ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
10297117f1b4Smrg   }
10307117f1b4Smrg   /* color map lookup */
10317117f1b4Smrg   if (transferOps & IMAGE_MAP_COLOR_BIT) {
10327117f1b4Smrg      _mesa_map_rgba( ctx, n, rgba );
10337117f1b4Smrg   }
10347117f1b4Smrg   /* GL_COLOR_TABLE lookup */
10357117f1b4Smrg   if (transferOps & IMAGE_COLOR_TABLE_BIT) {
10367117f1b4Smrg      _mesa_lookup_rgba_float(&ctx->ColorTable[COLORTABLE_PRECONVOLUTION], n, rgba);
10377117f1b4Smrg   }
10387117f1b4Smrg   /* convolution */
10397117f1b4Smrg   if (transferOps & IMAGE_CONVOLUTION_BIT) {
10407117f1b4Smrg      /* this has to be done in the calling code */
10417117f1b4Smrg      _mesa_problem(ctx, "IMAGE_CONVOLUTION_BIT set in _mesa_apply_transfer_ops");
10427117f1b4Smrg   }
10437117f1b4Smrg   /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
10447117f1b4Smrg   if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
10457117f1b4Smrg      _mesa_scale_and_bias_rgba(n, rgba,
10467117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[RCOMP],
10477117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[GCOMP],
10487117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[BCOMP],
10497117f1b4Smrg                                ctx->Pixel.PostConvolutionScale[ACOMP],
10507117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[RCOMP],
10517117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[GCOMP],
10527117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[BCOMP],
10537117f1b4Smrg                                ctx->Pixel.PostConvolutionBias[ACOMP]);
10547117f1b4Smrg   }
10557117f1b4Smrg   /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
10567117f1b4Smrg   if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
10577117f1b4Smrg      _mesa_lookup_rgba_float(&ctx->ColorTable[COLORTABLE_POSTCONVOLUTION], n, rgba);
10587117f1b4Smrg   }
10597117f1b4Smrg   /* color matrix transform */
10607117f1b4Smrg   if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
10617117f1b4Smrg      _mesa_transform_rgba(ctx, n, rgba);
10627117f1b4Smrg   }
10637117f1b4Smrg   /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
10647117f1b4Smrg   if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
10657117f1b4Smrg      _mesa_lookup_rgba_float(&ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX], n, rgba);
10667117f1b4Smrg   }
10677117f1b4Smrg   /* update histogram count */
10687117f1b4Smrg   if (transferOps & IMAGE_HISTOGRAM_BIT) {
10697117f1b4Smrg      _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
10707117f1b4Smrg   }
10717117f1b4Smrg   /* update min/max values */
10727117f1b4Smrg   if (transferOps & IMAGE_MIN_MAX_BIT) {
10737117f1b4Smrg      _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
10747117f1b4Smrg   }
10757117f1b4Smrg   /* clamping to [0,1] */
10767117f1b4Smrg   if (transferOps & IMAGE_CLAMP_BIT) {
10777117f1b4Smrg      GLuint i;
10787117f1b4Smrg      for (i = 0; i < n; i++) {
10797117f1b4Smrg         rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
10807117f1b4Smrg         rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
10817117f1b4Smrg         rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
10827117f1b4Smrg         rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
10837117f1b4Smrg      }
10847117f1b4Smrg   }
10857117f1b4Smrg}
10867117f1b4Smrg
10877117f1b4Smrg
10887117f1b4Smrg/*
10897117f1b4Smrg * Apply color index shift and offset to an array of pixels.
10907117f1b4Smrg */
10917117f1b4Smrgstatic void
10927117f1b4Smrgshift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
10937117f1b4Smrg{
10947117f1b4Smrg   GLint shift = ctx->Pixel.IndexShift;
10957117f1b4Smrg   GLint offset = ctx->Pixel.IndexOffset;
10967117f1b4Smrg   GLuint i;
10977117f1b4Smrg   if (shift > 0) {
10987117f1b4Smrg      for (i=0;i<n;i++) {
10997117f1b4Smrg         indexes[i] = (indexes[i] << shift) + offset;
11007117f1b4Smrg      }
11017117f1b4Smrg   }
11027117f1b4Smrg   else if (shift < 0) {
11037117f1b4Smrg      shift = -shift;
11047117f1b4Smrg      for (i=0;i<n;i++) {
11057117f1b4Smrg         indexes[i] = (indexes[i] >> shift) + offset;
11067117f1b4Smrg      }
11077117f1b4Smrg   }
11087117f1b4Smrg   else {
11097117f1b4Smrg      for (i=0;i<n;i++) {
11107117f1b4Smrg         indexes[i] = indexes[i] + offset;
11117117f1b4Smrg      }
11127117f1b4Smrg   }
11137117f1b4Smrg}
11147117f1b4Smrg
11157117f1b4Smrg
11167117f1b4Smrg
11177117f1b4Smrg/**
11187117f1b4Smrg * Apply color index shift, offset and table lookup to an array
11197117f1b4Smrg * of color indexes;
11207117f1b4Smrg */
11217117f1b4Smrgvoid
11227117f1b4Smrg_mesa_apply_ci_transfer_ops(const GLcontext *ctx, GLbitfield transferOps,
11237117f1b4Smrg                            GLuint n, GLuint indexes[])
11247117f1b4Smrg{
11257117f1b4Smrg   if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
11267117f1b4Smrg      shift_and_offset_ci(ctx, n, indexes);
11277117f1b4Smrg   }
11287117f1b4Smrg   if (transferOps & IMAGE_MAP_COLOR_BIT) {
11297117f1b4Smrg      const GLuint mask = ctx->PixelMaps.ItoI.Size - 1;
11307117f1b4Smrg      GLuint i;
11317117f1b4Smrg      for (i = 0; i < n; i++) {
11327117f1b4Smrg         const GLuint j = indexes[i] & mask;
11337117f1b4Smrg         indexes[i] = IROUND(ctx->PixelMaps.ItoI.Map[j]);
11347117f1b4Smrg      }
11357117f1b4Smrg   }
11367117f1b4Smrg}
11377117f1b4Smrg
11387117f1b4Smrg
11397117f1b4Smrg/**
11407117f1b4Smrg * Apply stencil index shift, offset and table lookup to an array
11417117f1b4Smrg * of stencil values.
11427117f1b4Smrg */
11437117f1b4Smrgvoid
11447117f1b4Smrg_mesa_apply_stencil_transfer_ops(const GLcontext *ctx, GLuint n,
11457117f1b4Smrg                                 GLstencil stencil[])
11467117f1b4Smrg{
11477117f1b4Smrg   if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
11487117f1b4Smrg      const GLint offset = ctx->Pixel.IndexOffset;
11497117f1b4Smrg      GLint shift = ctx->Pixel.IndexShift;
11507117f1b4Smrg      GLuint i;
11517117f1b4Smrg      if (shift > 0) {
11527117f1b4Smrg         for (i = 0; i < n; i++) {
11537117f1b4Smrg            stencil[i] = (stencil[i] << shift) + offset;
11547117f1b4Smrg         }
11557117f1b4Smrg      }
11567117f1b4Smrg      else if (shift < 0) {
11577117f1b4Smrg         shift = -shift;
11587117f1b4Smrg         for (i = 0; i < n; i++) {
11597117f1b4Smrg            stencil[i] = (stencil[i] >> shift) + offset;
11607117f1b4Smrg         }
11617117f1b4Smrg      }
11627117f1b4Smrg      else {
11637117f1b4Smrg         for (i = 0; i < n; i++) {
11647117f1b4Smrg            stencil[i] = stencil[i] + offset;
11657117f1b4Smrg         }
11667117f1b4Smrg      }
11677117f1b4Smrg   }
11687117f1b4Smrg   if (ctx->Pixel.MapStencilFlag) {
11697117f1b4Smrg      GLuint mask = ctx->PixelMaps.StoS.Size - 1;
11707117f1b4Smrg      GLuint i;
11717117f1b4Smrg      for (i = 0; i < n; i++) {
11727117f1b4Smrg         stencil[i] = ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
11737117f1b4Smrg      }
11747117f1b4Smrg   }
11757117f1b4Smrg}
11767117f1b4Smrg
11777117f1b4Smrg
11787117f1b4Smrg/**
11797117f1b4Smrg * Used to pack an array [][4] of RGBA float colors as specified
11807117f1b4Smrg * by the dstFormat, dstType and dstPacking.  Used by glReadPixels,
11817117f1b4Smrg * glGetConvolutionFilter(), etc.
11827117f1b4Smrg * Incoming colors will be clamped to [0,1] if needed.
11837117f1b4Smrg * Note: the rgba values will be modified by this function when any pixel
11847117f1b4Smrg * transfer ops are enabled.
11857117f1b4Smrg */
11867117f1b4Smrgvoid
11877117f1b4Smrg_mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
11887117f1b4Smrg                           GLenum dstFormat, GLenum dstType,
11897117f1b4Smrg                           GLvoid *dstAddr,
11907117f1b4Smrg                           const struct gl_pixelstore_attrib *dstPacking,
11917117f1b4Smrg                           GLbitfield transferOps)
11927117f1b4Smrg{
11937117f1b4Smrg   GLfloat luminance[MAX_WIDTH];
11947117f1b4Smrg   const GLint comps = _mesa_components_in_format(dstFormat);
11957117f1b4Smrg   GLuint i;
11967117f1b4Smrg
11977117f1b4Smrg   if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
11987117f1b4Smrg      /* need to clamp to [0, 1] */
11997117f1b4Smrg      transferOps |= IMAGE_CLAMP_BIT;
12007117f1b4Smrg   }
12017117f1b4Smrg
12027117f1b4Smrg   if (transferOps) {
12037117f1b4Smrg      _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
12047117f1b4Smrg      if ((transferOps & IMAGE_MIN_MAX_BIT) && ctx->MinMax.Sink) {
12057117f1b4Smrg         return;
12067117f1b4Smrg      }
12077117f1b4Smrg   }
12087117f1b4Smrg
12097117f1b4Smrg   if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
12107117f1b4Smrg      /* compute luminance values */
12117117f1b4Smrg      if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
12127117f1b4Smrg         for (i = 0; i < n; i++) {
12137117f1b4Smrg            GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
12147117f1b4Smrg            luminance[i] = CLAMP(sum, 0.0F, 1.0F);
12157117f1b4Smrg         }
12167117f1b4Smrg      }
12177117f1b4Smrg      else {
12187117f1b4Smrg         for (i = 0; i < n; i++) {
12197117f1b4Smrg            luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
12207117f1b4Smrg         }
12217117f1b4Smrg      }
12227117f1b4Smrg   }
12237117f1b4Smrg
12247117f1b4Smrg   /*
12257117f1b4Smrg    * Pack/store the pixels.  Ugh!  Lots of cases!!!
12267117f1b4Smrg    */
12277117f1b4Smrg   switch (dstType) {
12287117f1b4Smrg      case GL_UNSIGNED_BYTE:
12297117f1b4Smrg         {
12307117f1b4Smrg            GLubyte *dst = (GLubyte *) dstAddr;
12317117f1b4Smrg            switch (dstFormat) {
12327117f1b4Smrg               case GL_RED:
12337117f1b4Smrg                  for (i=0;i<n;i++)
12347117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
12357117f1b4Smrg                  break;
12367117f1b4Smrg               case GL_GREEN:
12377117f1b4Smrg                  for (i=0;i<n;i++)
12387117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
12397117f1b4Smrg                  break;
12407117f1b4Smrg               case GL_BLUE:
12417117f1b4Smrg                  for (i=0;i<n;i++)
12427117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
12437117f1b4Smrg                  break;
12447117f1b4Smrg               case GL_ALPHA:
12457117f1b4Smrg                  for (i=0;i<n;i++)
12467117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
12477117f1b4Smrg                  break;
12487117f1b4Smrg               case GL_LUMINANCE:
12497117f1b4Smrg                  for (i=0;i<n;i++)
12507117f1b4Smrg                     dst[i] = FLOAT_TO_UBYTE(luminance[i]);
12517117f1b4Smrg                  break;
12527117f1b4Smrg               case GL_LUMINANCE_ALPHA:
12537117f1b4Smrg                  for (i=0;i<n;i++) {
12547117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_UBYTE(luminance[i]);
12557117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
12567117f1b4Smrg                  }
12577117f1b4Smrg                  break;
12587117f1b4Smrg               case GL_RGB:
12597117f1b4Smrg                  for (i=0;i<n;i++) {
12607117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
12617117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
12627117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
12637117f1b4Smrg                  }
12647117f1b4Smrg                  break;
12657117f1b4Smrg               case GL_RGBA:
12667117f1b4Smrg                  for (i=0;i<n;i++) {
12677117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
12687117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
12697117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
12707117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
12717117f1b4Smrg                  }
12727117f1b4Smrg                  break;
12737117f1b4Smrg               case GL_BGR:
12747117f1b4Smrg                  for (i=0;i<n;i++) {
12757117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
12767117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
12777117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
12787117f1b4Smrg                  }
12797117f1b4Smrg                  break;
12807117f1b4Smrg               case GL_BGRA:
12817117f1b4Smrg                  for (i=0;i<n;i++) {
12827117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
12837117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
12847117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
12857117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
12867117f1b4Smrg                  }
12877117f1b4Smrg                  break;
12887117f1b4Smrg               case GL_ABGR_EXT:
12897117f1b4Smrg                  for (i=0;i<n;i++) {
12907117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
12917117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
12927117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
12937117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
12947117f1b4Smrg                  }
12957117f1b4Smrg                  break;
12967117f1b4Smrg               default:
12977117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
12987117f1b4Smrg            }
12997117f1b4Smrg         }
13007117f1b4Smrg         break;
13017117f1b4Smrg      case GL_BYTE:
13027117f1b4Smrg         {
13037117f1b4Smrg            GLbyte *dst = (GLbyte *) dstAddr;
13047117f1b4Smrg            switch (dstFormat) {
13057117f1b4Smrg               case GL_RED:
13067117f1b4Smrg                  for (i=0;i<n;i++)
13077117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
13087117f1b4Smrg                  break;
13097117f1b4Smrg               case GL_GREEN:
13107117f1b4Smrg                  for (i=0;i<n;i++)
13117117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
13127117f1b4Smrg                  break;
13137117f1b4Smrg               case GL_BLUE:
13147117f1b4Smrg                  for (i=0;i<n;i++)
13157117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
13167117f1b4Smrg                  break;
13177117f1b4Smrg               case GL_ALPHA:
13187117f1b4Smrg                  for (i=0;i<n;i++)
13197117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
13207117f1b4Smrg                  break;
13217117f1b4Smrg               case GL_LUMINANCE:
13227117f1b4Smrg                  for (i=0;i<n;i++)
13237117f1b4Smrg                     dst[i] = FLOAT_TO_BYTE(luminance[i]);
13247117f1b4Smrg                  break;
13257117f1b4Smrg               case GL_LUMINANCE_ALPHA:
13267117f1b4Smrg                  for (i=0;i<n;i++) {
13277117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_BYTE(luminance[i]);
13287117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
13297117f1b4Smrg                  }
13307117f1b4Smrg                  break;
13317117f1b4Smrg               case GL_RGB:
13327117f1b4Smrg                  for (i=0;i<n;i++) {
13337117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
13347117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
13357117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
13367117f1b4Smrg                  }
13377117f1b4Smrg                  break;
13387117f1b4Smrg               case GL_RGBA:
13397117f1b4Smrg                  for (i=0;i<n;i++) {
13407117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
13417117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
13427117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
13437117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
13447117f1b4Smrg                  }
13457117f1b4Smrg                  break;
13467117f1b4Smrg               case GL_BGR:
13477117f1b4Smrg                  for (i=0;i<n;i++) {
13487117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
13497117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
13507117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
13517117f1b4Smrg                  }
13527117f1b4Smrg                  break;
13537117f1b4Smrg               case GL_BGRA:
13547117f1b4Smrg                  for (i=0;i<n;i++) {
13557117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
13567117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
13577117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
13587117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
13597117f1b4Smrg                  }
13607117f1b4Smrg		  break;
13617117f1b4Smrg               case GL_ABGR_EXT:
13627117f1b4Smrg                  for (i=0;i<n;i++) {
13637117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_BYTE(rgba[i][ACOMP]);
13647117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_BYTE(rgba[i][BCOMP]);
13657117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_BYTE(rgba[i][GCOMP]);
13667117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_BYTE(rgba[i][RCOMP]);
13677117f1b4Smrg                  }
13687117f1b4Smrg                  break;
13697117f1b4Smrg               default:
13707117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
13717117f1b4Smrg            }
13727117f1b4Smrg         }
13737117f1b4Smrg         break;
13747117f1b4Smrg      case GL_UNSIGNED_SHORT:
13757117f1b4Smrg         {
13767117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
13777117f1b4Smrg            switch (dstFormat) {
13787117f1b4Smrg               case GL_RED:
13797117f1b4Smrg                  for (i=0;i<n;i++)
13807117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][RCOMP]);
13817117f1b4Smrg                  break;
13827117f1b4Smrg               case GL_GREEN:
13837117f1b4Smrg                  for (i=0;i<n;i++)
13847117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][GCOMP]);
13857117f1b4Smrg                  break;
13867117f1b4Smrg               case GL_BLUE:
13877117f1b4Smrg                  for (i=0;i<n;i++)
13887117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][BCOMP]);
13897117f1b4Smrg                  break;
13907117f1b4Smrg               case GL_ALPHA:
13917117f1b4Smrg                  for (i=0;i<n;i++)
13927117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][ACOMP]);
13937117f1b4Smrg                  break;
13947117f1b4Smrg               case GL_LUMINANCE:
13957117f1b4Smrg                  for (i=0;i<n;i++)
13967117f1b4Smrg                     UNCLAMPED_FLOAT_TO_USHORT(dst[i], luminance[i]);
13977117f1b4Smrg                  break;
13987117f1b4Smrg               case GL_LUMINANCE_ALPHA:
13997117f1b4Smrg                  for (i=0;i<n;i++) {
14007117f1b4Smrg                     UNCLAMPED_FLOAT_TO_USHORT(dst[i*2+0], luminance[i]);
14017117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*2+1], rgba[i][ACOMP]);
14027117f1b4Smrg                  }
14037117f1b4Smrg                  break;
14047117f1b4Smrg               case GL_RGB:
14057117f1b4Smrg                  for (i=0;i<n;i++) {
14067117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][RCOMP]);
14077117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]);
14087117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][BCOMP]);
14097117f1b4Smrg                  }
14107117f1b4Smrg                  break;
14117117f1b4Smrg               case GL_RGBA:
14127117f1b4Smrg                  for (i=0;i<n;i++) {
14137117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][RCOMP]);
14147117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]);
14157117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][BCOMP]);
14167117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]);
14177117f1b4Smrg                  }
14187117f1b4Smrg                  break;
14197117f1b4Smrg               case GL_BGR:
14207117f1b4Smrg                  for (i=0;i<n;i++) {
14217117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][BCOMP]);
14227117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]);
14237117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][RCOMP]);
14247117f1b4Smrg                  }
14257117f1b4Smrg                  break;
14267117f1b4Smrg               case GL_BGRA:
14277117f1b4Smrg                  for (i=0;i<n;i++) {
14287117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][BCOMP]);
14297117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]);
14307117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][RCOMP]);
14317117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]);
14327117f1b4Smrg                  }
14337117f1b4Smrg                  break;
14347117f1b4Smrg               case GL_ABGR_EXT:
14357117f1b4Smrg                  for (i=0;i<n;i++) {
14367117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][ACOMP]);
14377117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][BCOMP]);
14387117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][GCOMP]);
14397117f1b4Smrg                     CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]);
14407117f1b4Smrg                  }
14417117f1b4Smrg                  break;
14427117f1b4Smrg               default:
14437117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
14447117f1b4Smrg            }
14457117f1b4Smrg         }
14467117f1b4Smrg         break;
14477117f1b4Smrg      case GL_SHORT:
14487117f1b4Smrg         {
14497117f1b4Smrg            GLshort *dst = (GLshort *) dstAddr;
14507117f1b4Smrg            switch (dstFormat) {
14517117f1b4Smrg               case GL_RED:
14527117f1b4Smrg                  for (i=0;i<n;i++)
14537117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
14547117f1b4Smrg                  break;
14557117f1b4Smrg               case GL_GREEN:
14567117f1b4Smrg                  for (i=0;i<n;i++)
14577117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
14587117f1b4Smrg                  break;
14597117f1b4Smrg               case GL_BLUE:
14607117f1b4Smrg                  for (i=0;i<n;i++)
14617117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
14627117f1b4Smrg                  break;
14637117f1b4Smrg               case GL_ALPHA:
14647117f1b4Smrg                  for (i=0;i<n;i++)
14657117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
14667117f1b4Smrg                  break;
14677117f1b4Smrg               case GL_LUMINANCE:
14687117f1b4Smrg                  for (i=0;i<n;i++)
14697117f1b4Smrg                     dst[i] = FLOAT_TO_SHORT(luminance[i]);
14707117f1b4Smrg                  break;
14717117f1b4Smrg               case GL_LUMINANCE_ALPHA:
14727117f1b4Smrg                  for (i=0;i<n;i++) {
14737117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_SHORT(luminance[i]);
14747117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
14757117f1b4Smrg                  }
14767117f1b4Smrg                  break;
14777117f1b4Smrg               case GL_RGB:
14787117f1b4Smrg                  for (i=0;i<n;i++) {
14797117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
14807117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
14817117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
14827117f1b4Smrg                  }
14837117f1b4Smrg                  break;
14847117f1b4Smrg               case GL_RGBA:
14857117f1b4Smrg                  for (i=0;i<n;i++) {
14867117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
14877117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
14887117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
14897117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
14907117f1b4Smrg                  }
14917117f1b4Smrg                  break;
14927117f1b4Smrg               case GL_BGR:
14937117f1b4Smrg                  for (i=0;i<n;i++) {
14947117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
14957117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
14967117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
14977117f1b4Smrg                  }
14987117f1b4Smrg                  break;
14997117f1b4Smrg               case GL_BGRA:
15007117f1b4Smrg                  for (i=0;i<n;i++) {
15017117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
15027117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
15037117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
15047117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
15057117f1b4Smrg                  }
15067117f1b4Smrg		  break;
15077117f1b4Smrg               case GL_ABGR_EXT:
15087117f1b4Smrg                  for (i=0;i<n;i++) {
15097117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_SHORT(rgba[i][ACOMP]);
15107117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_SHORT(rgba[i][BCOMP]);
15117117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_SHORT(rgba[i][GCOMP]);
15127117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_SHORT(rgba[i][RCOMP]);
15137117f1b4Smrg                  }
15147117f1b4Smrg                  break;
15157117f1b4Smrg               default:
15167117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
15177117f1b4Smrg            }
15187117f1b4Smrg         }
15197117f1b4Smrg         break;
15207117f1b4Smrg      case GL_UNSIGNED_INT:
15217117f1b4Smrg         {
15227117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
15237117f1b4Smrg            switch (dstFormat) {
15247117f1b4Smrg               case GL_RED:
15257117f1b4Smrg                  for (i=0;i<n;i++)
15267117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][RCOMP]);
15277117f1b4Smrg                  break;
15287117f1b4Smrg               case GL_GREEN:
15297117f1b4Smrg                  for (i=0;i<n;i++)
15307117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][GCOMP]);
15317117f1b4Smrg                  break;
15327117f1b4Smrg               case GL_BLUE:
15337117f1b4Smrg                  for (i=0;i<n;i++)
15347117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][BCOMP]);
15357117f1b4Smrg                  break;
15367117f1b4Smrg               case GL_ALPHA:
15377117f1b4Smrg                  for (i=0;i<n;i++)
15387117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(rgba[i][ACOMP]);
15397117f1b4Smrg                  break;
15407117f1b4Smrg               case GL_LUMINANCE:
15417117f1b4Smrg                  for (i=0;i<n;i++)
15427117f1b4Smrg                     dst[i] = FLOAT_TO_UINT(luminance[i]);
15437117f1b4Smrg                  break;
15447117f1b4Smrg               case GL_LUMINANCE_ALPHA:
15457117f1b4Smrg                  for (i=0;i<n;i++) {
15467117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_UINT(luminance[i]);
15477117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_UINT(rgba[i][ACOMP]);
15487117f1b4Smrg                  }
15497117f1b4Smrg                  break;
15507117f1b4Smrg               case GL_RGB:
15517117f1b4Smrg                  for (i=0;i<n;i++) {
15527117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
15537117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
15547117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UINT(rgba[i][BCOMP]);
15557117f1b4Smrg                  }
15567117f1b4Smrg                  break;
15577117f1b4Smrg               case GL_RGBA:
15587117f1b4Smrg                  for (i=0;i<n;i++) {
15597117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UINT(rgba[i][RCOMP]);
15607117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
15617117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UINT(rgba[i][BCOMP]);
15627117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]);
15637117f1b4Smrg                  }
15647117f1b4Smrg                  break;
15657117f1b4Smrg               case GL_BGR:
15667117f1b4Smrg                  for (i=0;i<n;i++) {
15677117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_UINT(rgba[i][BCOMP]);
15687117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
15697117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_UINT(rgba[i][RCOMP]);
15707117f1b4Smrg                  }
15717117f1b4Smrg                  break;
15727117f1b4Smrg               case GL_BGRA:
15737117f1b4Smrg                  for (i=0;i<n;i++) {
15747117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UINT(rgba[i][BCOMP]);
15757117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]);
15767117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UINT(rgba[i][RCOMP]);
15777117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]);
15787117f1b4Smrg                  }
15797117f1b4Smrg                  break;
15807117f1b4Smrg               case GL_ABGR_EXT:
15817117f1b4Smrg                  for (i=0;i<n;i++) {
15827117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_UINT(rgba[i][ACOMP]);
15837117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_UINT(rgba[i][BCOMP]);
15847117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_UINT(rgba[i][GCOMP]);
15857117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]);
15867117f1b4Smrg                  }
15877117f1b4Smrg                  break;
15887117f1b4Smrg               default:
15897117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
15907117f1b4Smrg            }
15917117f1b4Smrg         }
15927117f1b4Smrg         break;
15937117f1b4Smrg      case GL_INT:
15947117f1b4Smrg         {
15957117f1b4Smrg            GLint *dst = (GLint *) dstAddr;
15967117f1b4Smrg            switch (dstFormat) {
15977117f1b4Smrg               case GL_RED:
15987117f1b4Smrg                  for (i=0;i<n;i++)
15997117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][RCOMP]);
16007117f1b4Smrg                  break;
16017117f1b4Smrg               case GL_GREEN:
16027117f1b4Smrg                  for (i=0;i<n;i++)
16037117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][GCOMP]);
16047117f1b4Smrg                  break;
16057117f1b4Smrg               case GL_BLUE:
16067117f1b4Smrg                  for (i=0;i<n;i++)
16077117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][BCOMP]);
16087117f1b4Smrg                  break;
16097117f1b4Smrg               case GL_ALPHA:
16107117f1b4Smrg                  for (i=0;i<n;i++)
16117117f1b4Smrg                     dst[i] = FLOAT_TO_INT(rgba[i][ACOMP]);
16127117f1b4Smrg                  break;
16137117f1b4Smrg               case GL_LUMINANCE:
16147117f1b4Smrg                  for (i=0;i<n;i++)
16157117f1b4Smrg                     dst[i] = FLOAT_TO_INT(luminance[i]);
16167117f1b4Smrg                  break;
16177117f1b4Smrg               case GL_LUMINANCE_ALPHA:
16187117f1b4Smrg                  for (i=0;i<n;i++) {
16197117f1b4Smrg                     dst[i*2+0] = FLOAT_TO_INT(luminance[i]);
16207117f1b4Smrg                     dst[i*2+1] = FLOAT_TO_INT(rgba[i][ACOMP]);
16217117f1b4Smrg                  }
16227117f1b4Smrg                  break;
16237117f1b4Smrg               case GL_RGB:
16247117f1b4Smrg                  for (i=0;i<n;i++) {
16257117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
16267117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
16277117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_INT(rgba[i][BCOMP]);
16287117f1b4Smrg                  }
16297117f1b4Smrg                  break;
16307117f1b4Smrg               case GL_RGBA:
16317117f1b4Smrg                  for (i=0;i<n;i++) {
16327117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_INT(rgba[i][RCOMP]);
16337117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
16347117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_INT(rgba[i][BCOMP]);
16357117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]);
16367117f1b4Smrg                  }
16377117f1b4Smrg                  break;
16387117f1b4Smrg               case GL_BGR:
16397117f1b4Smrg                  for (i=0;i<n;i++) {
16407117f1b4Smrg                     dst[i*3+0] = FLOAT_TO_INT(rgba[i][BCOMP]);
16417117f1b4Smrg                     dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
16427117f1b4Smrg                     dst[i*3+2] = FLOAT_TO_INT(rgba[i][RCOMP]);
16437117f1b4Smrg                  }
16447117f1b4Smrg                  break;
16457117f1b4Smrg               case GL_BGRA:
16467117f1b4Smrg                  for (i=0;i<n;i++) {
16477117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_INT(rgba[i][BCOMP]);
16487117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]);
16497117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_INT(rgba[i][RCOMP]);
16507117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]);
16517117f1b4Smrg                  }
16527117f1b4Smrg                  break;
16537117f1b4Smrg               case GL_ABGR_EXT:
16547117f1b4Smrg                  for (i=0;i<n;i++) {
16557117f1b4Smrg                     dst[i*4+0] = FLOAT_TO_INT(rgba[i][ACOMP]);
16567117f1b4Smrg                     dst[i*4+1] = FLOAT_TO_INT(rgba[i][BCOMP]);
16577117f1b4Smrg                     dst[i*4+2] = FLOAT_TO_INT(rgba[i][GCOMP]);
16587117f1b4Smrg                     dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]);
16597117f1b4Smrg                  }
16607117f1b4Smrg                  break;
16617117f1b4Smrg               default:
16627117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
16637117f1b4Smrg            }
16647117f1b4Smrg         }
16657117f1b4Smrg         break;
16667117f1b4Smrg      case GL_FLOAT:
16677117f1b4Smrg         {
16687117f1b4Smrg            GLfloat *dst = (GLfloat *) dstAddr;
16697117f1b4Smrg            switch (dstFormat) {
16707117f1b4Smrg               case GL_RED:
16717117f1b4Smrg                  for (i=0;i<n;i++)
16727117f1b4Smrg                     dst[i] = rgba[i][RCOMP];
16737117f1b4Smrg                  break;
16747117f1b4Smrg               case GL_GREEN:
16757117f1b4Smrg                  for (i=0;i<n;i++)
16767117f1b4Smrg                     dst[i] = rgba[i][GCOMP];
16777117f1b4Smrg                  break;
16787117f1b4Smrg               case GL_BLUE:
16797117f1b4Smrg                  for (i=0;i<n;i++)
16807117f1b4Smrg                     dst[i] = rgba[i][BCOMP];
16817117f1b4Smrg                  break;
16827117f1b4Smrg               case GL_ALPHA:
16837117f1b4Smrg                  for (i=0;i<n;i++)
16847117f1b4Smrg                     dst[i] = rgba[i][ACOMP];
16857117f1b4Smrg                  break;
16867117f1b4Smrg               case GL_LUMINANCE:
16877117f1b4Smrg                  for (i=0;i<n;i++)
16887117f1b4Smrg                     dst[i] = luminance[i];
16897117f1b4Smrg                  break;
16907117f1b4Smrg               case GL_LUMINANCE_ALPHA:
16917117f1b4Smrg                  for (i=0;i<n;i++) {
16927117f1b4Smrg                     dst[i*2+0] = luminance[i];
16937117f1b4Smrg                     dst[i*2+1] = rgba[i][ACOMP];
16947117f1b4Smrg                  }
16957117f1b4Smrg                  break;
16967117f1b4Smrg               case GL_RGB:
16977117f1b4Smrg                  for (i=0;i<n;i++) {
16987117f1b4Smrg                     dst[i*3+0] = rgba[i][RCOMP];
16997117f1b4Smrg                     dst[i*3+1] = rgba[i][GCOMP];
17007117f1b4Smrg                     dst[i*3+2] = rgba[i][BCOMP];
17017117f1b4Smrg                  }
17027117f1b4Smrg                  break;
17037117f1b4Smrg               case GL_RGBA:
17047117f1b4Smrg                  for (i=0;i<n;i++) {
17057117f1b4Smrg                     dst[i*4+0] = rgba[i][RCOMP];
17067117f1b4Smrg                     dst[i*4+1] = rgba[i][GCOMP];
17077117f1b4Smrg                     dst[i*4+2] = rgba[i][BCOMP];
17087117f1b4Smrg                     dst[i*4+3] = rgba[i][ACOMP];
17097117f1b4Smrg                  }
17107117f1b4Smrg                  break;
17117117f1b4Smrg               case GL_BGR:
17127117f1b4Smrg                  for (i=0;i<n;i++) {
17137117f1b4Smrg                     dst[i*3+0] = rgba[i][BCOMP];
17147117f1b4Smrg                     dst[i*3+1] = rgba[i][GCOMP];
17157117f1b4Smrg                     dst[i*3+2] = rgba[i][RCOMP];
17167117f1b4Smrg                  }
17177117f1b4Smrg                  break;
17187117f1b4Smrg               case GL_BGRA:
17197117f1b4Smrg                  for (i=0;i<n;i++) {
17207117f1b4Smrg                     dst[i*4+0] = rgba[i][BCOMP];
17217117f1b4Smrg                     dst[i*4+1] = rgba[i][GCOMP];
17227117f1b4Smrg                     dst[i*4+2] = rgba[i][RCOMP];
17237117f1b4Smrg                     dst[i*4+3] = rgba[i][ACOMP];
17247117f1b4Smrg                  }
17257117f1b4Smrg                  break;
17267117f1b4Smrg               case GL_ABGR_EXT:
17277117f1b4Smrg                  for (i=0;i<n;i++) {
17287117f1b4Smrg                     dst[i*4+0] = rgba[i][ACOMP];
17297117f1b4Smrg                     dst[i*4+1] = rgba[i][BCOMP];
17307117f1b4Smrg                     dst[i*4+2] = rgba[i][GCOMP];
17317117f1b4Smrg                     dst[i*4+3] = rgba[i][RCOMP];
17327117f1b4Smrg                  }
17337117f1b4Smrg                  break;
17347117f1b4Smrg               default:
17357117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
17367117f1b4Smrg            }
17377117f1b4Smrg         }
17387117f1b4Smrg         break;
17397117f1b4Smrg      case GL_HALF_FLOAT_ARB:
17407117f1b4Smrg         {
17417117f1b4Smrg            GLhalfARB *dst = (GLhalfARB *) dstAddr;
17427117f1b4Smrg            switch (dstFormat) {
17437117f1b4Smrg               case GL_RED:
17447117f1b4Smrg                  for (i=0;i<n;i++)
17457117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][RCOMP]);
17467117f1b4Smrg                  break;
17477117f1b4Smrg               case GL_GREEN:
17487117f1b4Smrg                  for (i=0;i<n;i++)
17497117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][GCOMP]);
17507117f1b4Smrg                  break;
17517117f1b4Smrg               case GL_BLUE:
17527117f1b4Smrg                  for (i=0;i<n;i++)
17537117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][BCOMP]);
17547117f1b4Smrg                  break;
17557117f1b4Smrg               case GL_ALPHA:
17567117f1b4Smrg                  for (i=0;i<n;i++)
17577117f1b4Smrg                     dst[i] = _mesa_float_to_half(rgba[i][ACOMP]);
17587117f1b4Smrg                  break;
17597117f1b4Smrg               case GL_LUMINANCE:
17607117f1b4Smrg                  for (i=0;i<n;i++)
17617117f1b4Smrg                     dst[i] = _mesa_float_to_half(luminance[i]);
17627117f1b4Smrg                  break;
17637117f1b4Smrg               case GL_LUMINANCE_ALPHA:
17647117f1b4Smrg                  for (i=0;i<n;i++) {
17657117f1b4Smrg                     dst[i*2+0] = _mesa_float_to_half(luminance[i]);
17667117f1b4Smrg                     dst[i*2+1] = _mesa_float_to_half(rgba[i][ACOMP]);
17677117f1b4Smrg                  }
17687117f1b4Smrg                  break;
17697117f1b4Smrg               case GL_RGB:
17707117f1b4Smrg                  for (i=0;i<n;i++) {
17717117f1b4Smrg                     dst[i*3+0] = _mesa_float_to_half(rgba[i][RCOMP]);
17727117f1b4Smrg                     dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]);
17737117f1b4Smrg                     dst[i*3+2] = _mesa_float_to_half(rgba[i][BCOMP]);
17747117f1b4Smrg                  }
17757117f1b4Smrg                  break;
17767117f1b4Smrg               case GL_RGBA:
17777117f1b4Smrg                  for (i=0;i<n;i++) {
17787117f1b4Smrg                     dst[i*4+0] = _mesa_float_to_half(rgba[i][RCOMP]);
17797117f1b4Smrg                     dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]);
17807117f1b4Smrg                     dst[i*4+2] = _mesa_float_to_half(rgba[i][BCOMP]);
17817117f1b4Smrg                     dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]);
17827117f1b4Smrg                  }
17837117f1b4Smrg                  break;
17847117f1b4Smrg               case GL_BGR:
17857117f1b4Smrg                  for (i=0;i<n;i++) {
17867117f1b4Smrg                     dst[i*3+0] = _mesa_float_to_half(rgba[i][BCOMP]);
17877117f1b4Smrg                     dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]);
17887117f1b4Smrg                     dst[i*3+2] = _mesa_float_to_half(rgba[i][RCOMP]);
17897117f1b4Smrg                  }
17907117f1b4Smrg                  break;
17917117f1b4Smrg               case GL_BGRA:
17927117f1b4Smrg                  for (i=0;i<n;i++) {
17937117f1b4Smrg                     dst[i*4+0] = _mesa_float_to_half(rgba[i][BCOMP]);
17947117f1b4Smrg                     dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]);
17957117f1b4Smrg                     dst[i*4+2] = _mesa_float_to_half(rgba[i][RCOMP]);
17967117f1b4Smrg                     dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]);
17977117f1b4Smrg                  }
17987117f1b4Smrg                  break;
17997117f1b4Smrg               case GL_ABGR_EXT:
18007117f1b4Smrg                  for (i=0;i<n;i++) {
18017117f1b4Smrg                     dst[i*4+0] = _mesa_float_to_half(rgba[i][ACOMP]);
18027117f1b4Smrg                     dst[i*4+1] = _mesa_float_to_half(rgba[i][BCOMP]);
18037117f1b4Smrg                     dst[i*4+2] = _mesa_float_to_half(rgba[i][GCOMP]);
18047117f1b4Smrg                     dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]);
18057117f1b4Smrg                  }
18067117f1b4Smrg                  break;
18077117f1b4Smrg               default:
18087117f1b4Smrg                  _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n");
18097117f1b4Smrg            }
18107117f1b4Smrg         }
18117117f1b4Smrg         break;
18127117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
18137117f1b4Smrg         if (dstFormat == GL_RGB) {
18147117f1b4Smrg            GLubyte *dst = (GLubyte *) dstAddr;
18157117f1b4Smrg            for (i=0;i<n;i++) {
18167117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 7.0F)) << 5)
18177117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 7.0F)) << 2)
18187117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 3.0F))     );
18197117f1b4Smrg            }
18207117f1b4Smrg         }
18217117f1b4Smrg         break;
18227117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
18237117f1b4Smrg         if (dstFormat == GL_RGB) {
18247117f1b4Smrg            GLubyte *dst = (GLubyte *) dstAddr;
18257117f1b4Smrg            for (i=0;i<n;i++) {
18267117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 7.0F))     )
18277117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 7.0F)) << 3)
18287117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 3.0F)) << 6);
18297117f1b4Smrg            }
18307117f1b4Smrg         }
18317117f1b4Smrg         break;
18327117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
18337117f1b4Smrg         if (dstFormat == GL_RGB) {
18347117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18357117f1b4Smrg            for (i=0;i<n;i++) {
18367117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) << 11)
18377117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 63.0F)) <<  5)
18387117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 31.0F))      );
18397117f1b4Smrg            }
18407117f1b4Smrg         }
18417117f1b4Smrg         break;
18427117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
18437117f1b4Smrg         if (dstFormat == GL_RGB) {
18447117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18457117f1b4Smrg            for (i=0;i<n;i++) {
18467117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F))      )
18477117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 63.0F)) <<  5)
18487117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 11);
18497117f1b4Smrg            }
18507117f1b4Smrg         }
18517117f1b4Smrg         break;
18527117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
18537117f1b4Smrg         if (dstFormat == GL_RGBA) {
18547117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18557117f1b4Smrg            for (i=0;i<n;i++) {
18567117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 15.0F)) << 12)
18577117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  8)
18587117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  4)
18597117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] * 15.0F))      );
18607117f1b4Smrg            }
18617117f1b4Smrg         }
18627117f1b4Smrg         else if (dstFormat == GL_BGRA) {
18637117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18647117f1b4Smrg            for (i=0;i<n;i++) {
18657117f1b4Smrg               dst[i] = (((GLint) (rgba[i][BCOMP] * 15.0F)) << 12)
18667117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  8)
18677117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] * 15.0F)) <<  4)
18687117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] * 15.0F))      );
18697117f1b4Smrg            }
18707117f1b4Smrg         }
18717117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
18727117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18737117f1b4Smrg            for (i=0;i<n;i++) {
18747117f1b4Smrg               dst[i] = (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12)
18757117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  8)
18767117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  4)
18777117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] * 15.0F))      );
18787117f1b4Smrg            }
18797117f1b4Smrg         }
18807117f1b4Smrg         break;
18817117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
18827117f1b4Smrg         if (dstFormat == GL_RGBA) {
18837117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18847117f1b4Smrg            for (i=0;i<n;i++) {
18857117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 15.0F))      )
18867117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  4)
18877117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  8)
18887117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12);
18897117f1b4Smrg            }
18907117f1b4Smrg         }
18917117f1b4Smrg         else if (dstFormat == GL_BGRA) {
18927117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
18937117f1b4Smrg            for (i=0;i<n;i++) {
18947117f1b4Smrg               dst[i] = (((GLint) (rgba[i][BCOMP] * 15.0F))      )
18957117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  4)
18967117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] * 15.0F)) <<  8)
18977117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] * 15.0F)) << 12);
18987117f1b4Smrg            }
18997117f1b4Smrg         }
19007117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
19017117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19027117f1b4Smrg            for (i=0;i<n;i++) {
19037117f1b4Smrg               dst[i] = (((GLint) (rgba[i][ACOMP] * 15.0F))      )
19047117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 15.0F)) <<  4)
19057117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 15.0F)) <<  8)
19067117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] * 15.0F)) << 12);
19077117f1b4Smrg            }
19087117f1b4Smrg         }
19097117f1b4Smrg         break;
19107117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
19117117f1b4Smrg         if (dstFormat == GL_RGBA) {
19127117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19137117f1b4Smrg            for (i=0;i<n;i++) {
19147117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F)) << 11)
19157117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  6)
19167117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) <<  1)
19177117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] *  1.0F))      );
19187117f1b4Smrg            }
19197117f1b4Smrg         }
19207117f1b4Smrg         else if (dstFormat == GL_BGRA) {
19217117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19227117f1b4Smrg            for (i=0;i<n;i++) {
19237117f1b4Smrg               dst[i] = (((GLint) (rgba[i][BCOMP] * 31.0F)) << 11)
19247117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  6)
19257117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] * 31.0F)) <<  1)
19267117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] *  1.0F))      );
19277117f1b4Smrg            }
19287117f1b4Smrg         }
19297117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
19307117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19317117f1b4Smrg            for (i=0;i<n;i++) {
19327117f1b4Smrg               dst[i] = (((GLint) (rgba[i][ACOMP] * 31.0F)) << 11)
19337117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) <<  6)
19347117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  1)
19357117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] *  1.0F))      );
19367117f1b4Smrg            }
19377117f1b4Smrg         }
19387117f1b4Smrg         break;
19397117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
19407117f1b4Smrg         if (dstFormat == GL_RGBA) {
19417117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19427117f1b4Smrg            for (i=0;i<n;i++) {
19437117f1b4Smrg               dst[i] = (((GLint) (rgba[i][RCOMP] * 31.0F))      )
19447117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  5)
19457117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) << 10)
19467117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] *  1.0F)) << 15);
19477117f1b4Smrg            }
19487117f1b4Smrg         }
19497117f1b4Smrg         else if (dstFormat == GL_BGRA) {
19507117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19517117f1b4Smrg            for (i=0;i<n;i++) {
19527117f1b4Smrg               dst[i] = (((GLint) (rgba[i][BCOMP] * 31.0F))      )
19537117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) <<  5)
19547117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] * 31.0F)) << 10)
19557117f1b4Smrg                      | (((GLint) (rgba[i][ACOMP] *  1.0F)) << 15);
19567117f1b4Smrg            }
19577117f1b4Smrg         }
19587117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
19597117f1b4Smrg            GLushort *dst = (GLushort *) dstAddr;
19607117f1b4Smrg            for (i=0;i<n;i++) {
19617117f1b4Smrg               dst[i] = (((GLint) (rgba[i][ACOMP] * 31.0F))      )
19627117f1b4Smrg                      | (((GLint) (rgba[i][BCOMP] * 31.0F)) <<  5)
19637117f1b4Smrg                      | (((GLint) (rgba[i][GCOMP] * 31.0F)) << 10)
19647117f1b4Smrg                      | (((GLint) (rgba[i][RCOMP] *  1.0F)) << 15);
19657117f1b4Smrg            }
19667117f1b4Smrg         }
19677117f1b4Smrg         break;
19687117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
19697117f1b4Smrg         if (dstFormat == GL_RGBA) {
19707117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
19717117f1b4Smrg            for (i=0;i<n;i++) {
19727117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 24)
19737117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
19747117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) <<  8)
19757117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] * 255.0F))      );
19767117f1b4Smrg            }
19777117f1b4Smrg         }
19787117f1b4Smrg         else if (dstFormat == GL_BGRA) {
19797117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
19807117f1b4Smrg            for (i=0;i<n;i++) {
19817117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 24)
19827117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
19837117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] * 255.0F)) <<  8)
19847117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] * 255.0F))      );
19857117f1b4Smrg            }
19867117f1b4Smrg         }
19877117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
19887117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
19897117f1b4Smrg            for (i=0;i<n;i++) {
19907117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24)
19917117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 16)
19927117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) <<  8)
19937117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] * 255.0F))      );
19947117f1b4Smrg            }
19957117f1b4Smrg         }
19967117f1b4Smrg         break;
19977117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
19987117f1b4Smrg         if (dstFormat == GL_RGBA) {
19997117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20007117f1b4Smrg            for (i=0;i<n;i++) {
20017117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][RCOMP] * 255.0F))      )
20027117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) <<  8)
20037117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) << 16)
20047117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24);
20057117f1b4Smrg            }
20067117f1b4Smrg         }
20077117f1b4Smrg         else if (dstFormat == GL_BGRA) {
20087117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20097117f1b4Smrg            for (i=0;i<n;i++) {
20107117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][BCOMP] * 255.0F))      )
20117117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) <<  8)
20127117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 16)
20137117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] * 255.0F)) << 24);
20147117f1b4Smrg            }
20157117f1b4Smrg         }
20167117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
20177117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20187117f1b4Smrg            for (i=0;i<n;i++) {
20197117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][ACOMP] * 255.0F))      )
20207117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 255.0F)) <<  8)
20217117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 255.0F)) << 16)
20227117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] * 255.0F)) << 24);
20237117f1b4Smrg            }
20247117f1b4Smrg         }
20257117f1b4Smrg         break;
20267117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
20277117f1b4Smrg         if (dstFormat == GL_RGBA) {
20287117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20297117f1b4Smrg            for (i=0;i<n;i++) {
20307117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 22)
20317117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 12)
20327117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) <<  2)
20337117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] *    3.0F))      );
20347117f1b4Smrg            }
20357117f1b4Smrg         }
20367117f1b4Smrg         else if (dstFormat == GL_BGRA) {
20377117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20387117f1b4Smrg            for (i=0;i<n;i++) {
20397117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 22)
20407117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 12)
20417117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] * 1023.0F)) <<  2)
20427117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] *    3.0F))      );
20437117f1b4Smrg            }
20447117f1b4Smrg         }
20457117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
20467117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20477117f1b4Smrg            for (i=0;i<n;i++) {
20487117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][ACOMP] * 1023.0F)) << 22)
20497117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 12)
20507117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) <<  2)
20517117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] *    3.0F))      );
20527117f1b4Smrg            }
20537117f1b4Smrg         }
20547117f1b4Smrg         break;
20557117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
20567117f1b4Smrg         if (dstFormat == GL_RGBA) {
20577117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20587117f1b4Smrg            for (i=0;i<n;i++) {
20597117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][RCOMP] * 1023.0F))      )
20607117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 10)
20617117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 20)
20627117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] *    3.0F)) << 30);
20637117f1b4Smrg            }
20647117f1b4Smrg         }
20657117f1b4Smrg         else if (dstFormat == GL_BGRA) {
20667117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20677117f1b4Smrg            for (i=0;i<n;i++) {
20687117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][BCOMP] * 1023.0F))      )
20697117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 10)
20707117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] * 1023.0F)) << 20)
20717117f1b4Smrg                      | (((GLuint) (rgba[i][ACOMP] *    3.0F)) << 30);
20727117f1b4Smrg            }
20737117f1b4Smrg         }
20747117f1b4Smrg         else if (dstFormat == GL_ABGR_EXT) {
20757117f1b4Smrg            GLuint *dst = (GLuint *) dstAddr;
20767117f1b4Smrg            for (i=0;i<n;i++) {
20777117f1b4Smrg               dst[i] = (((GLuint) (rgba[i][ACOMP] * 1023.0F))      )
20787117f1b4Smrg                      | (((GLuint) (rgba[i][BCOMP] * 1023.0F)) << 10)
20797117f1b4Smrg                      | (((GLuint) (rgba[i][GCOMP] * 1023.0F)) << 20)
20807117f1b4Smrg                      | (((GLuint) (rgba[i][RCOMP] *    3.0F)) << 30);
20817117f1b4Smrg            }
20827117f1b4Smrg         }
20837117f1b4Smrg         break;
20847117f1b4Smrg      default:
20857117f1b4Smrg         _mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float");
20867117f1b4Smrg         return;
20877117f1b4Smrg   }
20887117f1b4Smrg
20897117f1b4Smrg   if (dstPacking->SwapBytes) {
20907117f1b4Smrg      GLint swapSize = _mesa_sizeof_packed_type(dstType);
20917117f1b4Smrg      if (swapSize == 2) {
20927117f1b4Smrg         if (dstPacking->SwapBytes) {
20937117f1b4Smrg            _mesa_swap2((GLushort *) dstAddr, n * comps);
20947117f1b4Smrg         }
20957117f1b4Smrg      }
20967117f1b4Smrg      else if (swapSize == 4) {
20977117f1b4Smrg         if (dstPacking->SwapBytes) {
20987117f1b4Smrg            _mesa_swap4((GLuint *) dstAddr, n * comps);
20997117f1b4Smrg         }
21007117f1b4Smrg      }
21017117f1b4Smrg   }
21027117f1b4Smrg}
21037117f1b4Smrg
21047117f1b4Smrg
21057117f1b4Smrg#define SWAP2BYTE(VALUE)			\
21067117f1b4Smrg   {						\
21077117f1b4Smrg      GLubyte *bytes = (GLubyte *) &(VALUE);	\
21087117f1b4Smrg      GLubyte tmp = bytes[0];			\
21097117f1b4Smrg      bytes[0] = bytes[1];			\
21107117f1b4Smrg      bytes[1] = tmp;				\
21117117f1b4Smrg   }
21127117f1b4Smrg
21137117f1b4Smrg#define SWAP4BYTE(VALUE)			\
21147117f1b4Smrg   {						\
21157117f1b4Smrg      GLubyte *bytes = (GLubyte *) &(VALUE);	\
21167117f1b4Smrg      GLubyte tmp = bytes[0];			\
21177117f1b4Smrg      bytes[0] = bytes[3];			\
21187117f1b4Smrg      bytes[3] = tmp;				\
21197117f1b4Smrg      tmp = bytes[1];				\
21207117f1b4Smrg      bytes[1] = bytes[2];			\
21217117f1b4Smrg      bytes[2] = tmp;				\
21227117f1b4Smrg   }
21237117f1b4Smrg
21247117f1b4Smrg
21257117f1b4Smrgstatic void
21267117f1b4Smrgextract_uint_indexes(GLuint n, GLuint indexes[],
21277117f1b4Smrg                     GLenum srcFormat, GLenum srcType, const GLvoid *src,
21287117f1b4Smrg                     const struct gl_pixelstore_attrib *unpack )
21297117f1b4Smrg{
21307117f1b4Smrg   ASSERT(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX);
21317117f1b4Smrg
21327117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
21337117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
21347117f1b4Smrg          srcType == GL_BYTE ||
21357117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
21367117f1b4Smrg          srcType == GL_SHORT ||
21377117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
21387117f1b4Smrg          srcType == GL_INT ||
21397117f1b4Smrg          srcType == GL_UNSIGNED_INT_24_8_EXT ||
21407117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
21417117f1b4Smrg          srcType == GL_FLOAT);
21427117f1b4Smrg
21437117f1b4Smrg   switch (srcType) {
21447117f1b4Smrg      case GL_BITMAP:
21457117f1b4Smrg         {
21467117f1b4Smrg            GLubyte *ubsrc = (GLubyte *) src;
21477117f1b4Smrg            if (unpack->LsbFirst) {
21487117f1b4Smrg               GLubyte mask = 1 << (unpack->SkipPixels & 0x7);
21497117f1b4Smrg               GLuint i;
21507117f1b4Smrg               for (i = 0; i < n; i++) {
21517117f1b4Smrg                  indexes[i] = (*ubsrc & mask) ? 1 : 0;
21527117f1b4Smrg                  if (mask == 128) {
21537117f1b4Smrg                     mask = 1;
21547117f1b4Smrg                     ubsrc++;
21557117f1b4Smrg                  }
21567117f1b4Smrg                  else {
21577117f1b4Smrg                     mask = mask << 1;
21587117f1b4Smrg                  }
21597117f1b4Smrg               }
21607117f1b4Smrg            }
21617117f1b4Smrg            else {
21627117f1b4Smrg               GLubyte mask = 128 >> (unpack->SkipPixels & 0x7);
21637117f1b4Smrg               GLuint i;
21647117f1b4Smrg               for (i = 0; i < n; i++) {
21657117f1b4Smrg                  indexes[i] = (*ubsrc & mask) ? 1 : 0;
21667117f1b4Smrg                  if (mask == 1) {
21677117f1b4Smrg                     mask = 128;
21687117f1b4Smrg                     ubsrc++;
21697117f1b4Smrg                  }
21707117f1b4Smrg                  else {
21717117f1b4Smrg                     mask = mask >> 1;
21727117f1b4Smrg                  }
21737117f1b4Smrg               }
21747117f1b4Smrg            }
21757117f1b4Smrg         }
21767117f1b4Smrg         break;
21777117f1b4Smrg      case GL_UNSIGNED_BYTE:
21787117f1b4Smrg         {
21797117f1b4Smrg            GLuint i;
21807117f1b4Smrg            const GLubyte *s = (const GLubyte *) src;
21817117f1b4Smrg            for (i = 0; i < n; i++)
21827117f1b4Smrg               indexes[i] = s[i];
21837117f1b4Smrg         }
21847117f1b4Smrg         break;
21857117f1b4Smrg      case GL_BYTE:
21867117f1b4Smrg         {
21877117f1b4Smrg            GLuint i;
21887117f1b4Smrg            const GLbyte *s = (const GLbyte *) src;
21897117f1b4Smrg            for (i = 0; i < n; i++)
21907117f1b4Smrg               indexes[i] = s[i];
21917117f1b4Smrg         }
21927117f1b4Smrg         break;
21937117f1b4Smrg      case GL_UNSIGNED_SHORT:
21947117f1b4Smrg         {
21957117f1b4Smrg            GLuint i;
21967117f1b4Smrg            const GLushort *s = (const GLushort *) src;
21977117f1b4Smrg            if (unpack->SwapBytes) {
21987117f1b4Smrg               for (i = 0; i < n; i++) {
21997117f1b4Smrg                  GLushort value = s[i];
22007117f1b4Smrg                  SWAP2BYTE(value);
22017117f1b4Smrg                  indexes[i] = value;
22027117f1b4Smrg               }
22037117f1b4Smrg            }
22047117f1b4Smrg            else {
22057117f1b4Smrg               for (i = 0; i < n; i++)
22067117f1b4Smrg                  indexes[i] = s[i];
22077117f1b4Smrg            }
22087117f1b4Smrg         }
22097117f1b4Smrg         break;
22107117f1b4Smrg      case GL_SHORT:
22117117f1b4Smrg         {
22127117f1b4Smrg            GLuint i;
22137117f1b4Smrg            const GLshort *s = (const GLshort *) src;
22147117f1b4Smrg            if (unpack->SwapBytes) {
22157117f1b4Smrg               for (i = 0; i < n; i++) {
22167117f1b4Smrg                  GLshort value = s[i];
22177117f1b4Smrg                  SWAP2BYTE(value);
22187117f1b4Smrg                  indexes[i] = value;
22197117f1b4Smrg               }
22207117f1b4Smrg            }
22217117f1b4Smrg            else {
22227117f1b4Smrg               for (i = 0; i < n; i++)
22237117f1b4Smrg                  indexes[i] = s[i];
22247117f1b4Smrg            }
22257117f1b4Smrg         }
22267117f1b4Smrg         break;
22277117f1b4Smrg      case GL_UNSIGNED_INT:
22287117f1b4Smrg         {
22297117f1b4Smrg            GLuint i;
22307117f1b4Smrg            const GLuint *s = (const GLuint *) src;
22317117f1b4Smrg            if (unpack->SwapBytes) {
22327117f1b4Smrg               for (i = 0; i < n; i++) {
22337117f1b4Smrg                  GLuint value = s[i];
22347117f1b4Smrg                  SWAP4BYTE(value);
22357117f1b4Smrg                  indexes[i] = value;
22367117f1b4Smrg               }
22377117f1b4Smrg            }
22387117f1b4Smrg            else {
22397117f1b4Smrg               for (i = 0; i < n; i++)
22407117f1b4Smrg                  indexes[i] = s[i];
22417117f1b4Smrg            }
22427117f1b4Smrg         }
22437117f1b4Smrg         break;
22447117f1b4Smrg      case GL_INT:
22457117f1b4Smrg         {
22467117f1b4Smrg            GLuint i;
22477117f1b4Smrg            const GLint *s = (const GLint *) src;
22487117f1b4Smrg            if (unpack->SwapBytes) {
22497117f1b4Smrg               for (i = 0; i < n; i++) {
22507117f1b4Smrg                  GLint value = s[i];
22517117f1b4Smrg                  SWAP4BYTE(value);
22527117f1b4Smrg                  indexes[i] = value;
22537117f1b4Smrg               }
22547117f1b4Smrg            }
22557117f1b4Smrg            else {
22567117f1b4Smrg               for (i = 0; i < n; i++)
22577117f1b4Smrg                  indexes[i] = s[i];
22587117f1b4Smrg            }
22597117f1b4Smrg         }
22607117f1b4Smrg         break;
22617117f1b4Smrg      case GL_FLOAT:
22627117f1b4Smrg         {
22637117f1b4Smrg            GLuint i;
22647117f1b4Smrg            const GLfloat *s = (const GLfloat *) src;
22657117f1b4Smrg            if (unpack->SwapBytes) {
22667117f1b4Smrg               for (i = 0; i < n; i++) {
22677117f1b4Smrg                  GLfloat value = s[i];
22687117f1b4Smrg                  SWAP4BYTE(value);
22697117f1b4Smrg                  indexes[i] = (GLuint) value;
22707117f1b4Smrg               }
22717117f1b4Smrg            }
22727117f1b4Smrg            else {
22737117f1b4Smrg               for (i = 0; i < n; i++)
22747117f1b4Smrg                  indexes[i] = (GLuint) s[i];
22757117f1b4Smrg            }
22767117f1b4Smrg         }
22777117f1b4Smrg         break;
22787117f1b4Smrg      case GL_HALF_FLOAT_ARB:
22797117f1b4Smrg         {
22807117f1b4Smrg            GLuint i;
22817117f1b4Smrg            const GLhalfARB *s = (const GLhalfARB *) src;
22827117f1b4Smrg            if (unpack->SwapBytes) {
22837117f1b4Smrg               for (i = 0; i < n; i++) {
22847117f1b4Smrg                  GLhalfARB value = s[i];
22857117f1b4Smrg                  SWAP2BYTE(value);
22867117f1b4Smrg                  indexes[i] = (GLuint) _mesa_half_to_float(value);
22877117f1b4Smrg               }
22887117f1b4Smrg            }
22897117f1b4Smrg            else {
22907117f1b4Smrg               for (i = 0; i < n; i++)
22917117f1b4Smrg                  indexes[i] = (GLuint) _mesa_half_to_float(s[i]);
22927117f1b4Smrg            }
22937117f1b4Smrg         }
22947117f1b4Smrg         break;
22957117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT:
22967117f1b4Smrg         {
22977117f1b4Smrg            GLuint i;
22987117f1b4Smrg            const GLuint *s = (const GLuint *) src;
22997117f1b4Smrg            if (unpack->SwapBytes) {
23007117f1b4Smrg               for (i = 0; i < n; i++) {
23017117f1b4Smrg                  GLuint value = s[i];
23027117f1b4Smrg                  SWAP4BYTE(value);
23037117f1b4Smrg                  indexes[i] = value & 0xff;  /* lower 8 bits */
23047117f1b4Smrg               }
23057117f1b4Smrg            }
23067117f1b4Smrg            else {
23077117f1b4Smrg               for (i = 0; i < n; i++)
23087117f1b4Smrg                  indexes[i] = s[i] & 0xfff;  /* lower 8 bits */
23097117f1b4Smrg            }
23107117f1b4Smrg         }
23117117f1b4Smrg         break;
23127117f1b4Smrg
23137117f1b4Smrg      default:
23147117f1b4Smrg         _mesa_problem(NULL, "bad srcType in extract_uint_indexes");
23157117f1b4Smrg         return;
23167117f1b4Smrg   }
23177117f1b4Smrg}
23187117f1b4Smrg
23197117f1b4Smrg
23207117f1b4Smrg/*
23217117f1b4Smrg * This function extracts floating point RGBA values from arbitrary
23227117f1b4Smrg * image data.  srcFormat and srcType are the format and type parameters
23237117f1b4Smrg * passed to glDrawPixels, glTexImage[123]D, glTexSubImage[123]D, etc.
23247117f1b4Smrg *
23257117f1b4Smrg * Refering to section 3.6.4 of the OpenGL 1.2 spec, this function
23267117f1b4Smrg * implements the "Conversion to floating point", "Conversion to RGB",
23277117f1b4Smrg * and "Final Expansion to RGBA" operations.
23287117f1b4Smrg *
23297117f1b4Smrg * Args:  n - number of pixels
23307117f1b4Smrg *        rgba - output colors
23317117f1b4Smrg *        srcFormat - format of incoming data
23327117f1b4Smrg *        srcType - data type of incoming data
23337117f1b4Smrg *        src - source data pointer
23347117f1b4Smrg *        swapBytes - perform byteswapping of incoming data?
23357117f1b4Smrg */
23367117f1b4Smrgstatic void
23377117f1b4Smrgextract_float_rgba(GLuint n, GLfloat rgba[][4],
23387117f1b4Smrg                   GLenum srcFormat, GLenum srcType, const GLvoid *src,
23397117f1b4Smrg                   GLboolean swapBytes)
23407117f1b4Smrg{
23417117f1b4Smrg   GLint redIndex, greenIndex, blueIndex, alphaIndex;
23427117f1b4Smrg   GLint stride;
23437117f1b4Smrg   GLint rComp, bComp, gComp, aComp;
23447117f1b4Smrg
23457117f1b4Smrg   ASSERT(srcFormat == GL_RED ||
23467117f1b4Smrg          srcFormat == GL_GREEN ||
23477117f1b4Smrg          srcFormat == GL_BLUE ||
23487117f1b4Smrg          srcFormat == GL_ALPHA ||
23497117f1b4Smrg          srcFormat == GL_LUMINANCE ||
23507117f1b4Smrg          srcFormat == GL_LUMINANCE_ALPHA ||
23517117f1b4Smrg          srcFormat == GL_INTENSITY ||
23527117f1b4Smrg          srcFormat == GL_RGB ||
23537117f1b4Smrg          srcFormat == GL_BGR ||
23547117f1b4Smrg          srcFormat == GL_RGBA ||
23557117f1b4Smrg          srcFormat == GL_BGRA ||
23567117f1b4Smrg          srcFormat == GL_ABGR_EXT);
23577117f1b4Smrg
23587117f1b4Smrg   ASSERT(srcType == GL_UNSIGNED_BYTE ||
23597117f1b4Smrg          srcType == GL_BYTE ||
23607117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
23617117f1b4Smrg          srcType == GL_SHORT ||
23627117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
23637117f1b4Smrg          srcType == GL_INT ||
23647117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
23657117f1b4Smrg          srcType == GL_FLOAT ||
23667117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_3_3_2 ||
23677117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
23687117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5 ||
23697117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
23707117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
23717117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
23727117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
23737117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
23747117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
23757117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
23767117f1b4Smrg          srcType == GL_UNSIGNED_INT_10_10_10_2 ||
23777117f1b4Smrg          srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
23787117f1b4Smrg
23797117f1b4Smrg   rComp = gComp = bComp = aComp = -1;
23807117f1b4Smrg
23817117f1b4Smrg   switch (srcFormat) {
23827117f1b4Smrg      case GL_RED:
23837117f1b4Smrg         redIndex = 0;
23847117f1b4Smrg         greenIndex = blueIndex = alphaIndex = -1;
23857117f1b4Smrg         stride = 1;
23867117f1b4Smrg         break;
23877117f1b4Smrg      case GL_GREEN:
23887117f1b4Smrg         greenIndex = 0;
23897117f1b4Smrg         redIndex = blueIndex = alphaIndex = -1;
23907117f1b4Smrg         stride = 1;
23917117f1b4Smrg         break;
23927117f1b4Smrg      case GL_BLUE:
23937117f1b4Smrg         blueIndex = 0;
23947117f1b4Smrg         redIndex = greenIndex = alphaIndex = -1;
23957117f1b4Smrg         stride = 1;
23967117f1b4Smrg         break;
23977117f1b4Smrg      case GL_ALPHA:
23987117f1b4Smrg         redIndex = greenIndex = blueIndex = -1;
23997117f1b4Smrg         alphaIndex = 0;
24007117f1b4Smrg         stride = 1;
24017117f1b4Smrg         break;
24027117f1b4Smrg      case GL_LUMINANCE:
24037117f1b4Smrg         redIndex = greenIndex = blueIndex = 0;
24047117f1b4Smrg         alphaIndex = -1;
24057117f1b4Smrg         stride = 1;
24067117f1b4Smrg         break;
24077117f1b4Smrg      case GL_LUMINANCE_ALPHA:
24087117f1b4Smrg         redIndex = greenIndex = blueIndex = 0;
24097117f1b4Smrg         alphaIndex = 1;
24107117f1b4Smrg         stride = 2;
24117117f1b4Smrg         break;
24127117f1b4Smrg      case GL_INTENSITY:
24137117f1b4Smrg         redIndex = greenIndex = blueIndex = alphaIndex = 0;
24147117f1b4Smrg         stride = 1;
24157117f1b4Smrg         break;
24167117f1b4Smrg      case GL_RGB:
24177117f1b4Smrg         redIndex = 0;
24187117f1b4Smrg         greenIndex = 1;
24197117f1b4Smrg         blueIndex = 2;
24207117f1b4Smrg         alphaIndex = -1;
24217117f1b4Smrg         rComp = 0;
24227117f1b4Smrg         gComp = 1;
24237117f1b4Smrg         bComp = 2;
24247117f1b4Smrg         aComp = 3;
24257117f1b4Smrg         stride = 3;
24267117f1b4Smrg         break;
24277117f1b4Smrg      case GL_BGR:
24287117f1b4Smrg         redIndex = 2;
24297117f1b4Smrg         greenIndex = 1;
24307117f1b4Smrg         blueIndex = 0;
24317117f1b4Smrg         alphaIndex = -1;
24327117f1b4Smrg         rComp = 2;
24337117f1b4Smrg         gComp = 1;
24347117f1b4Smrg         bComp = 0;
24357117f1b4Smrg         aComp = 3;
24367117f1b4Smrg         stride = 3;
24377117f1b4Smrg         break;
24387117f1b4Smrg      case GL_RGBA:
24397117f1b4Smrg         redIndex = 0;
24407117f1b4Smrg         greenIndex = 1;
24417117f1b4Smrg         blueIndex = 2;
24427117f1b4Smrg         alphaIndex = 3;
24437117f1b4Smrg         rComp = 0;
24447117f1b4Smrg         gComp = 1;
24457117f1b4Smrg         bComp = 2;
24467117f1b4Smrg         aComp = 3;
24477117f1b4Smrg         stride = 4;
24487117f1b4Smrg         break;
24497117f1b4Smrg      case GL_BGRA:
24507117f1b4Smrg         redIndex = 2;
24517117f1b4Smrg         greenIndex = 1;
24527117f1b4Smrg         blueIndex = 0;
24537117f1b4Smrg         alphaIndex = 3;
24547117f1b4Smrg         rComp = 2;
24557117f1b4Smrg         gComp = 1;
24567117f1b4Smrg         bComp = 0;
24577117f1b4Smrg         aComp = 3;
24587117f1b4Smrg         stride = 4;
24597117f1b4Smrg         break;
24607117f1b4Smrg      case GL_ABGR_EXT:
24617117f1b4Smrg         redIndex = 3;
24627117f1b4Smrg         greenIndex = 2;
24637117f1b4Smrg         blueIndex = 1;
24647117f1b4Smrg         alphaIndex = 0;
24657117f1b4Smrg         rComp = 3;
24667117f1b4Smrg         gComp = 2;
24677117f1b4Smrg         bComp = 1;
24687117f1b4Smrg         aComp = 0;
24697117f1b4Smrg         stride = 4;
24707117f1b4Smrg         break;
24717117f1b4Smrg      default:
24727117f1b4Smrg         _mesa_problem(NULL, "bad srcFormat in extract float data");
24737117f1b4Smrg         return;
24747117f1b4Smrg   }
24757117f1b4Smrg
24767117f1b4Smrg
24777117f1b4Smrg#define PROCESS(INDEX, CHANNEL, DEFAULT, TYPE, CONVERSION)		\
24787117f1b4Smrg   if ((INDEX) < 0) {							\
24797117f1b4Smrg      GLuint i;								\
24807117f1b4Smrg      for (i = 0; i < n; i++) {						\
24817117f1b4Smrg         rgba[i][CHANNEL] = DEFAULT;					\
24827117f1b4Smrg      }									\
24837117f1b4Smrg   }									\
24847117f1b4Smrg   else if (swapBytes) {						\
24857117f1b4Smrg      const TYPE *s = (const TYPE *) src;				\
24867117f1b4Smrg      GLuint i;								\
24877117f1b4Smrg      for (i = 0; i < n; i++) {						\
24887117f1b4Smrg         TYPE value = s[INDEX];						\
24897117f1b4Smrg         if (sizeof(TYPE) == 2) {					\
24907117f1b4Smrg            SWAP2BYTE(value);						\
24917117f1b4Smrg         }								\
24927117f1b4Smrg         else if (sizeof(TYPE) == 4) {					\
24937117f1b4Smrg            SWAP4BYTE(value);						\
24947117f1b4Smrg         }								\
24957117f1b4Smrg         rgba[i][CHANNEL] = (GLfloat) CONVERSION(value);		\
24967117f1b4Smrg         s += stride;							\
24977117f1b4Smrg      }									\
24987117f1b4Smrg   }									\
24997117f1b4Smrg   else {								\
25007117f1b4Smrg      const TYPE *s = (const TYPE *) src;				\
25017117f1b4Smrg      GLuint i;								\
25027117f1b4Smrg      for (i = 0; i < n; i++) {						\
25037117f1b4Smrg         rgba[i][CHANNEL] = (GLfloat) CONVERSION(s[INDEX]);		\
25047117f1b4Smrg         s += stride;							\
25057117f1b4Smrg      }									\
25067117f1b4Smrg   }
25077117f1b4Smrg
25087117f1b4Smrg   switch (srcType) {
25097117f1b4Smrg      case GL_UNSIGNED_BYTE:
25107117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
25117117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
25127117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
25137117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLubyte, UBYTE_TO_FLOAT);
25147117f1b4Smrg         break;
25157117f1b4Smrg      case GL_BYTE:
25167117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
25177117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
25187117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
25197117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLbyte, BYTE_TO_FLOAT);
25207117f1b4Smrg         break;
25217117f1b4Smrg      case GL_UNSIGNED_SHORT:
25227117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
25237117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
25247117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
25257117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLushort, USHORT_TO_FLOAT);
25267117f1b4Smrg         break;
25277117f1b4Smrg      case GL_SHORT:
25287117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
25297117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
25307117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
25317117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLshort, SHORT_TO_FLOAT);
25327117f1b4Smrg         break;
25337117f1b4Smrg      case GL_UNSIGNED_INT:
25347117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
25357117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
25367117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
25377117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLuint, UINT_TO_FLOAT);
25387117f1b4Smrg         break;
25397117f1b4Smrg      case GL_INT:
25407117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLint, INT_TO_FLOAT);
25417117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLint, INT_TO_FLOAT);
25427117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLint, INT_TO_FLOAT);
25437117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLint, INT_TO_FLOAT);
25447117f1b4Smrg         break;
25457117f1b4Smrg      case GL_FLOAT:
25467117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLfloat, (GLfloat));
25477117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLfloat, (GLfloat));
25487117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLfloat, (GLfloat));
25497117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLfloat, (GLfloat));
25507117f1b4Smrg         break;
25517117f1b4Smrg      case GL_HALF_FLOAT_ARB:
25527117f1b4Smrg         PROCESS(redIndex,   RCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
25537117f1b4Smrg         PROCESS(greenIndex, GCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
25547117f1b4Smrg         PROCESS(blueIndex,  BCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
25557117f1b4Smrg         PROCESS(alphaIndex, ACOMP, 1.0F, GLhalfARB, _mesa_half_to_float);
25567117f1b4Smrg         break;
25577117f1b4Smrg      case GL_UNSIGNED_BYTE_3_3_2:
25587117f1b4Smrg         {
25597117f1b4Smrg            const GLubyte *ubsrc = (const GLubyte *) src;
25607117f1b4Smrg            GLuint i;
25617117f1b4Smrg            for (i = 0; i < n; i ++) {
25627117f1b4Smrg               GLubyte p = ubsrc[i];
25637117f1b4Smrg               rgba[i][rComp] = ((p >> 5)      ) * (1.0F / 7.0F);
25647117f1b4Smrg               rgba[i][gComp] = ((p >> 2) & 0x7) * (1.0F / 7.0F);
25657117f1b4Smrg               rgba[i][bComp] = ((p     ) & 0x3) * (1.0F / 3.0F);
25667117f1b4Smrg               rgba[i][aComp] = 1.0F;
25677117f1b4Smrg            }
25687117f1b4Smrg         }
25697117f1b4Smrg         break;
25707117f1b4Smrg      case GL_UNSIGNED_BYTE_2_3_3_REV:
25717117f1b4Smrg         {
25727117f1b4Smrg            const GLubyte *ubsrc = (const GLubyte *) src;
25737117f1b4Smrg            GLuint i;
25747117f1b4Smrg            for (i = 0; i < n; i ++) {
25757117f1b4Smrg               GLubyte p = ubsrc[i];
25767117f1b4Smrg               rgba[i][rComp] = ((p     ) & 0x7) * (1.0F / 7.0F);
25777117f1b4Smrg               rgba[i][gComp] = ((p >> 3) & 0x7) * (1.0F / 7.0F);
25787117f1b4Smrg               rgba[i][bComp] = ((p >> 6)      ) * (1.0F / 3.0F);
25797117f1b4Smrg               rgba[i][aComp] = 1.0F;
25807117f1b4Smrg            }
25817117f1b4Smrg         }
25827117f1b4Smrg         break;
25837117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5:
25847117f1b4Smrg         if (swapBytes) {
25857117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
25867117f1b4Smrg            GLuint i;
25877117f1b4Smrg            for (i = 0; i < n; i ++) {
25887117f1b4Smrg               GLushort p = ussrc[i];
25897117f1b4Smrg               SWAP2BYTE(p);
25907117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
25917117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
25927117f1b4Smrg               rgba[i][bComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
25937117f1b4Smrg               rgba[i][aComp] = 1.0F;
25947117f1b4Smrg            }
25957117f1b4Smrg         }
25967117f1b4Smrg         else {
25977117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
25987117f1b4Smrg            GLuint i;
25997117f1b4Smrg            for (i = 0; i < n; i ++) {
26007117f1b4Smrg               GLushort p = ussrc[i];
26017117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
26027117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
26037117f1b4Smrg               rgba[i][bComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
26047117f1b4Smrg               rgba[i][aComp] = 1.0F;
26057117f1b4Smrg            }
26067117f1b4Smrg         }
26077117f1b4Smrg         break;
26087117f1b4Smrg      case GL_UNSIGNED_SHORT_5_6_5_REV:
26097117f1b4Smrg         if (swapBytes) {
26107117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26117117f1b4Smrg            GLuint i;
26127117f1b4Smrg            for (i = 0; i < n; i ++) {
26137117f1b4Smrg               GLushort p = ussrc[i];
26147117f1b4Smrg               SWAP2BYTE(p);
26157117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
26167117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
26177117f1b4Smrg               rgba[i][bComp] = ((p >> 11)       ) * (1.0F / 31.0F);
26187117f1b4Smrg               rgba[i][aComp] = 1.0F;
26197117f1b4Smrg            }
26207117f1b4Smrg         }
26217117f1b4Smrg         else {
26227117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26237117f1b4Smrg            GLuint i;
26247117f1b4Smrg            for (i = 0; i < n; i ++) {
26257117f1b4Smrg               GLushort p = ussrc[i];
26267117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
26277117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
26287117f1b4Smrg               rgba[i][bComp] = ((p >> 11)       ) * (1.0F / 31.0F);
26297117f1b4Smrg               rgba[i][aComp] = 1.0F;
26307117f1b4Smrg            }
26317117f1b4Smrg         }
26327117f1b4Smrg         break;
26337117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4:
26347117f1b4Smrg         if (swapBytes) {
26357117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26367117f1b4Smrg            GLuint i;
26377117f1b4Smrg            for (i = 0; i < n; i ++) {
26387117f1b4Smrg               GLushort p = ussrc[i];
26397117f1b4Smrg               SWAP2BYTE(p);
26407117f1b4Smrg               rgba[i][rComp] = ((p >> 12)      ) * (1.0F / 15.0F);
26417117f1b4Smrg               rgba[i][gComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
26427117f1b4Smrg               rgba[i][bComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
26437117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
26447117f1b4Smrg            }
26457117f1b4Smrg         }
26467117f1b4Smrg         else {
26477117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26487117f1b4Smrg            GLuint i;
26497117f1b4Smrg            for (i = 0; i < n; i ++) {
26507117f1b4Smrg               GLushort p = ussrc[i];
26517117f1b4Smrg               rgba[i][rComp] = ((p >> 12)      ) * (1.0F / 15.0F);
26527117f1b4Smrg               rgba[i][gComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
26537117f1b4Smrg               rgba[i][bComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
26547117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
26557117f1b4Smrg            }
26567117f1b4Smrg         }
26577117f1b4Smrg         break;
26587117f1b4Smrg      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
26597117f1b4Smrg         if (swapBytes) {
26607117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26617117f1b4Smrg            GLuint i;
26627117f1b4Smrg            for (i = 0; i < n; i ++) {
26637117f1b4Smrg               GLushort p = ussrc[i];
26647117f1b4Smrg               SWAP2BYTE(p);
26657117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
26667117f1b4Smrg               rgba[i][gComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
26677117f1b4Smrg               rgba[i][bComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
26687117f1b4Smrg               rgba[i][aComp] = ((p >> 12)      ) * (1.0F / 15.0F);
26697117f1b4Smrg            }
26707117f1b4Smrg         }
26717117f1b4Smrg         else {
26727117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26737117f1b4Smrg            GLuint i;
26747117f1b4Smrg            for (i = 0; i < n; i ++) {
26757117f1b4Smrg               GLushort p = ussrc[i];
26767117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
26777117f1b4Smrg               rgba[i][gComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
26787117f1b4Smrg               rgba[i][bComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
26797117f1b4Smrg               rgba[i][aComp] = ((p >> 12)      ) * (1.0F / 15.0F);
26807117f1b4Smrg            }
26817117f1b4Smrg         }
26827117f1b4Smrg         break;
26837117f1b4Smrg      case GL_UNSIGNED_SHORT_5_5_5_1:
26847117f1b4Smrg         if (swapBytes) {
26857117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26867117f1b4Smrg            GLuint i;
26877117f1b4Smrg            for (i = 0; i < n; i ++) {
26887117f1b4Smrg               GLushort p = ussrc[i];
26897117f1b4Smrg               SWAP2BYTE(p);
26907117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
26917117f1b4Smrg               rgba[i][gComp] = ((p >>  6) & 0x1f) * (1.0F / 31.0F);
26927117f1b4Smrg               rgba[i][bComp] = ((p >>  1) & 0x1f) * (1.0F / 31.0F);
26937117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x1)  * (1.0F /  1.0F);
26947117f1b4Smrg            }
26957117f1b4Smrg         }
26967117f1b4Smrg         else {
26977117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
26987117f1b4Smrg            GLuint i;
26997117f1b4Smrg            for (i = 0; i < n; i ++) {
27007117f1b4Smrg               GLushort p = ussrc[i];
27017117f1b4Smrg               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
27027117f1b4Smrg               rgba[i][gComp] = ((p >>  6) & 0x1f) * (1.0F / 31.0F);
27037117f1b4Smrg               rgba[i][bComp] = ((p >>  1) & 0x1f) * (1.0F / 31.0F);
27047117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x1)  * (1.0F /  1.0F);
27057117f1b4Smrg            }
27067117f1b4Smrg         }
27077117f1b4Smrg         break;
27087117f1b4Smrg      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
27097117f1b4Smrg         if (swapBytes) {
27107117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
27117117f1b4Smrg            GLuint i;
27127117f1b4Smrg            for (i = 0; i < n; i ++) {
27137117f1b4Smrg               GLushort p = ussrc[i];
27147117f1b4Smrg               SWAP2BYTE(p);
27157117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
27167117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x1f) * (1.0F / 31.0F);
27177117f1b4Smrg               rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
27187117f1b4Smrg               rgba[i][aComp] = ((p >> 15)       ) * (1.0F /  1.0F);
27197117f1b4Smrg            }
27207117f1b4Smrg         }
27217117f1b4Smrg         else {
27227117f1b4Smrg            const GLushort *ussrc = (const GLushort *) src;
27237117f1b4Smrg            GLuint i;
27247117f1b4Smrg            for (i = 0; i < n; i ++) {
27257117f1b4Smrg               GLushort p = ussrc[i];
27267117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
27277117f1b4Smrg               rgba[i][gComp] = ((p >>  5) & 0x1f) * (1.0F / 31.0F);
27287117f1b4Smrg               rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
27297117f1b4Smrg               rgba[i][aComp] = ((p >> 15)       ) * (1.0F /  1.0F);
27307117f1b4Smrg            }
27317117f1b4Smrg         }
27327117f1b4Smrg         break;
27337117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8:
27347117f1b4Smrg         if (swapBytes) {
27357117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
27367117f1b4Smrg            GLuint i;
27377117f1b4Smrg            for (i = 0; i < n; i ++) {
27387117f1b4Smrg               GLuint p = uisrc[i];
27397117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
27407117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
27417117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
27427117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
27437117f1b4Smrg            }
27447117f1b4Smrg         }
27457117f1b4Smrg         else {
27467117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
27477117f1b4Smrg            GLuint i;
27487117f1b4Smrg            for (i = 0; i < n; i ++) {
27497117f1b4Smrg               GLuint p = uisrc[i];
27507117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
27517117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
27527117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
27537117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
27547117f1b4Smrg            }
27557117f1b4Smrg         }
27567117f1b4Smrg         break;
27577117f1b4Smrg      case GL_UNSIGNED_INT_8_8_8_8_REV:
27587117f1b4Smrg         if (swapBytes) {
27597117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
27607117f1b4Smrg            GLuint i;
27617117f1b4Smrg            for (i = 0; i < n; i ++) {
27627117f1b4Smrg               GLuint p = uisrc[i];
27637117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
27647117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
27657117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
27667117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
27677117f1b4Smrg            }
27687117f1b4Smrg         }
27697117f1b4Smrg         else {
27707117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
27717117f1b4Smrg            GLuint i;
27727117f1b4Smrg            for (i = 0; i < n; i ++) {
27737117f1b4Smrg               GLuint p = uisrc[i];
27747117f1b4Smrg               rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
27757117f1b4Smrg               rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
27767117f1b4Smrg               rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
27777117f1b4Smrg               rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
27787117f1b4Smrg            }
27797117f1b4Smrg         }
27807117f1b4Smrg         break;
27817117f1b4Smrg      case GL_UNSIGNED_INT_10_10_10_2:
27827117f1b4Smrg         if (swapBytes) {
27837117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
27847117f1b4Smrg            GLuint i;
27857117f1b4Smrg            for (i = 0; i < n; i ++) {
27867117f1b4Smrg               GLuint p = uisrc[i];
27877117f1b4Smrg               SWAP4BYTE(p);
27887117f1b4Smrg               rgba[i][rComp] = ((p >> 22)        ) * (1.0F / 1023.0F);
27897117f1b4Smrg               rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
27907117f1b4Smrg               rgba[i][bComp] = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F);
27917117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x3  ) * (1.0F /    3.0F);
27927117f1b4Smrg            }
27937117f1b4Smrg         }
27947117f1b4Smrg         else {
27957117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
27967117f1b4Smrg            GLuint i;
27977117f1b4Smrg            for (i = 0; i < n; i ++) {
27987117f1b4Smrg               GLuint p = uisrc[i];
27997117f1b4Smrg               rgba[i][rComp] = ((p >> 22)        ) * (1.0F / 1023.0F);
28007117f1b4Smrg               rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
28017117f1b4Smrg               rgba[i][bComp] = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F);
28027117f1b4Smrg               rgba[i][aComp] = ((p      ) & 0x3  ) * (1.0F /    3.0F);
28037117f1b4Smrg            }
28047117f1b4Smrg         }
28057117f1b4Smrg         break;
28067117f1b4Smrg      case GL_UNSIGNED_INT_2_10_10_10_REV:
28077117f1b4Smrg         if (swapBytes) {
28087117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
28097117f1b4Smrg            GLuint i;
28107117f1b4Smrg            for (i = 0; i < n; i ++) {
28117117f1b4Smrg               GLuint p = uisrc[i];
28127117f1b4Smrg               SWAP4BYTE(p);
28137117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x3ff) * (1.0F / 1023.0F);
28147117f1b4Smrg               rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
28157117f1b4Smrg               rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
28167117f1b4Smrg               rgba[i][aComp] = ((p >> 30)        ) * (1.0F /    3.0F);
28177117f1b4Smrg            }
28187117f1b4Smrg         }
28197117f1b4Smrg         else {
28207117f1b4Smrg            const GLuint *uisrc = (const GLuint *) src;
28217117f1b4Smrg            GLuint i;
28227117f1b4Smrg            for (i = 0; i < n; i ++) {
28237117f1b4Smrg               GLuint p = uisrc[i];
28247117f1b4Smrg               rgba[i][rComp] = ((p      ) & 0x3ff) * (1.0F / 1023.0F);
28257117f1b4Smrg               rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
28267117f1b4Smrg               rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
28277117f1b4Smrg               rgba[i][aComp] = ((p >> 30)        ) * (1.0F /    3.0F);
28287117f1b4Smrg            }
28297117f1b4Smrg         }
28307117f1b4Smrg         break;
28317117f1b4Smrg      default:
28327117f1b4Smrg         _mesa_problem(NULL, "bad srcType in extract float data");
28337117f1b4Smrg         break;
28347117f1b4Smrg   }
28357117f1b4Smrg}
28367117f1b4Smrg
28377117f1b4Smrg
28387117f1b4Smrg/*
28397117f1b4Smrg * Unpack a row of color image data from a client buffer according to
28407117f1b4Smrg * the pixel unpacking parameters.
28417117f1b4Smrg * Return GLchan values in the specified dest image format.
28427117f1b4Smrg * This is used by glDrawPixels and glTexImage?D().
28437117f1b4Smrg * \param ctx - the context
28447117f1b4Smrg *         n - number of pixels in the span
28457117f1b4Smrg *         dstFormat - format of destination color array
28467117f1b4Smrg *         dest - the destination color array
28477117f1b4Smrg *         srcFormat - source image format
28487117f1b4Smrg *         srcType - source image  data type
28497117f1b4Smrg *         source - source image pointer
28507117f1b4Smrg *         srcPacking - pixel unpacking parameters
28517117f1b4Smrg *         transferOps - bitmask of IMAGE_*_BIT values of operations to apply
28527117f1b4Smrg *
28537117f1b4Smrg * XXX perhaps expand this to process whole images someday.
28547117f1b4Smrg */
28557117f1b4Smrgvoid
28567117f1b4Smrg_mesa_unpack_color_span_chan( GLcontext *ctx,
28577117f1b4Smrg                              GLuint n, GLenum dstFormat, GLchan dest[],
28587117f1b4Smrg                              GLenum srcFormat, GLenum srcType,
28597117f1b4Smrg                              const GLvoid *source,
28607117f1b4Smrg                              const struct gl_pixelstore_attrib *srcPacking,
28617117f1b4Smrg                              GLbitfield transferOps )
28627117f1b4Smrg{
28637117f1b4Smrg   ASSERT(dstFormat == GL_ALPHA ||
28647117f1b4Smrg          dstFormat == GL_LUMINANCE ||
28657117f1b4Smrg          dstFormat == GL_LUMINANCE_ALPHA ||
28667117f1b4Smrg          dstFormat == GL_INTENSITY ||
28677117f1b4Smrg          dstFormat == GL_RGB ||
28687117f1b4Smrg          dstFormat == GL_RGBA ||
28697117f1b4Smrg          dstFormat == GL_COLOR_INDEX);
28707117f1b4Smrg
28717117f1b4Smrg   ASSERT(srcFormat == GL_RED ||
28727117f1b4Smrg          srcFormat == GL_GREEN ||
28737117f1b4Smrg          srcFormat == GL_BLUE ||
28747117f1b4Smrg          srcFormat == GL_ALPHA ||
28757117f1b4Smrg          srcFormat == GL_LUMINANCE ||
28767117f1b4Smrg          srcFormat == GL_LUMINANCE_ALPHA ||
28777117f1b4Smrg          srcFormat == GL_INTENSITY ||
28787117f1b4Smrg          srcFormat == GL_RGB ||
28797117f1b4Smrg          srcFormat == GL_BGR ||
28807117f1b4Smrg          srcFormat == GL_RGBA ||
28817117f1b4Smrg          srcFormat == GL_BGRA ||
28827117f1b4Smrg          srcFormat == GL_ABGR_EXT ||
28837117f1b4Smrg          srcFormat == GL_COLOR_INDEX);
28847117f1b4Smrg
28857117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
28867117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
28877117f1b4Smrg          srcType == GL_BYTE ||
28887117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
28897117f1b4Smrg          srcType == GL_SHORT ||
28907117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
28917117f1b4Smrg          srcType == GL_INT ||
28927117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
28937117f1b4Smrg          srcType == GL_FLOAT ||
28947117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_3_3_2 ||
28957117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
28967117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5 ||
28977117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
28987117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
28997117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
29007117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
29017117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
29027117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
29037117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
29047117f1b4Smrg          srcType == GL_UNSIGNED_INT_10_10_10_2 ||
29057117f1b4Smrg          srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
29067117f1b4Smrg
29077117f1b4Smrg   /* Try simple cases first */
29087117f1b4Smrg   if (transferOps == 0) {
29097117f1b4Smrg      if (srcType == CHAN_TYPE) {
29107117f1b4Smrg         if (dstFormat == GL_RGBA) {
29117117f1b4Smrg            if (srcFormat == GL_RGBA) {
29127117f1b4Smrg               _mesa_memcpy( dest, source, n * 4 * sizeof(GLchan) );
29137117f1b4Smrg               return;
29147117f1b4Smrg            }
29157117f1b4Smrg            else if (srcFormat == GL_RGB) {
29167117f1b4Smrg               GLuint i;
29177117f1b4Smrg               const GLchan *src = (const GLchan *) source;
29187117f1b4Smrg               GLchan *dst = dest;
29197117f1b4Smrg               for (i = 0; i < n; i++) {
29207117f1b4Smrg                  dst[0] = src[0];
29217117f1b4Smrg                  dst[1] = src[1];
29227117f1b4Smrg                  dst[2] = src[2];
29237117f1b4Smrg                  dst[3] = CHAN_MAX;
29247117f1b4Smrg                  src += 3;
29257117f1b4Smrg                  dst += 4;
29267117f1b4Smrg               }
29277117f1b4Smrg               return;
29287117f1b4Smrg            }
29297117f1b4Smrg         }
29307117f1b4Smrg         else if (dstFormat == GL_RGB) {
29317117f1b4Smrg            if (srcFormat == GL_RGB) {
29327117f1b4Smrg               _mesa_memcpy( dest, source, n * 3 * sizeof(GLchan) );
29337117f1b4Smrg               return;
29347117f1b4Smrg            }
29357117f1b4Smrg            else if (srcFormat == GL_RGBA) {
29367117f1b4Smrg               GLuint i;
29377117f1b4Smrg               const GLchan *src = (const GLchan *) source;
29387117f1b4Smrg               GLchan *dst = dest;
29397117f1b4Smrg               for (i = 0; i < n; i++) {
29407117f1b4Smrg                  dst[0] = src[0];
29417117f1b4Smrg                  dst[1] = src[1];
29427117f1b4Smrg                  dst[2] = src[2];
29437117f1b4Smrg                  src += 4;
29447117f1b4Smrg                  dst += 3;
29457117f1b4Smrg               }
29467117f1b4Smrg               return;
29477117f1b4Smrg            }
29487117f1b4Smrg         }
29497117f1b4Smrg         else if (dstFormat == srcFormat) {
29507117f1b4Smrg            GLint comps = _mesa_components_in_format(srcFormat);
29517117f1b4Smrg            assert(comps > 0);
29527117f1b4Smrg            _mesa_memcpy( dest, source, n * comps * sizeof(GLchan) );
29537117f1b4Smrg            return;
29547117f1b4Smrg         }
29557117f1b4Smrg      }
29567117f1b4Smrg      /*
29577117f1b4Smrg       * Common situation, loading 8bit RGBA/RGB source images
29587117f1b4Smrg       * into 16/32 bit destination. (OSMesa16/32)
29597117f1b4Smrg       */
29607117f1b4Smrg      else if (srcType == GL_UNSIGNED_BYTE) {
29617117f1b4Smrg         if (dstFormat == GL_RGBA) {
29627117f1b4Smrg            if (srcFormat == GL_RGB) {
29637117f1b4Smrg               GLuint i;
29647117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
29657117f1b4Smrg               GLchan *dst = dest;
29667117f1b4Smrg               for (i = 0; i < n; i++) {
29677117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
29687117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
29697117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
29707117f1b4Smrg                  dst[3] = CHAN_MAX;
29717117f1b4Smrg                  src += 3;
29727117f1b4Smrg                  dst += 4;
29737117f1b4Smrg               }
29747117f1b4Smrg               return;
29757117f1b4Smrg            }
29767117f1b4Smrg            else if (srcFormat == GL_RGBA) {
29777117f1b4Smrg               GLuint i;
29787117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
29797117f1b4Smrg               GLchan *dst = dest;
29807117f1b4Smrg               for (i = 0; i < n; i++) {
29817117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
29827117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
29837117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
29847117f1b4Smrg                  dst[3] = UBYTE_TO_CHAN(src[3]);
29857117f1b4Smrg                  src += 4;
29867117f1b4Smrg                  dst += 4;
29877117f1b4Smrg               }
29887117f1b4Smrg               return;
29897117f1b4Smrg             }
29907117f1b4Smrg         }
29917117f1b4Smrg         else if (dstFormat == GL_RGB) {
29927117f1b4Smrg            if (srcFormat == GL_RGB) {
29937117f1b4Smrg               GLuint i;
29947117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
29957117f1b4Smrg               GLchan *dst = dest;
29967117f1b4Smrg               for (i = 0; i < n; i++) {
29977117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
29987117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
29997117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
30007117f1b4Smrg                  src += 3;
30017117f1b4Smrg                  dst += 3;
30027117f1b4Smrg               }
30037117f1b4Smrg               return;
30047117f1b4Smrg            }
30057117f1b4Smrg            else if (srcFormat == GL_RGBA) {
30067117f1b4Smrg               GLuint i;
30077117f1b4Smrg               const GLubyte *src = (const GLubyte *) source;
30087117f1b4Smrg               GLchan *dst = dest;
30097117f1b4Smrg               for (i = 0; i < n; i++) {
30107117f1b4Smrg                  dst[0] = UBYTE_TO_CHAN(src[0]);
30117117f1b4Smrg                  dst[1] = UBYTE_TO_CHAN(src[1]);
30127117f1b4Smrg                  dst[2] = UBYTE_TO_CHAN(src[2]);
30137117f1b4Smrg                  src += 4;
30147117f1b4Smrg                  dst += 3;
30157117f1b4Smrg               }
30167117f1b4Smrg               return;
30177117f1b4Smrg            }
30187117f1b4Smrg         }
30197117f1b4Smrg      }
30207117f1b4Smrg   }
30217117f1b4Smrg
30227117f1b4Smrg
30237117f1b4Smrg   /* general solution begins here */
30247117f1b4Smrg   {
30257117f1b4Smrg      GLint dstComponents;
30267117f1b4Smrg      GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex;
30277117f1b4Smrg      GLint dstLuminanceIndex, dstIntensityIndex;
30287117f1b4Smrg      GLfloat rgba[MAX_WIDTH][4];
30297117f1b4Smrg
30307117f1b4Smrg      dstComponents = _mesa_components_in_format( dstFormat );
30317117f1b4Smrg      /* source & dest image formats should have been error checked by now */
30327117f1b4Smrg      assert(dstComponents > 0);
30337117f1b4Smrg
30347117f1b4Smrg      /*
30357117f1b4Smrg       * Extract image data and convert to RGBA floats
30367117f1b4Smrg       */
30377117f1b4Smrg      assert(n <= MAX_WIDTH);
30387117f1b4Smrg      if (srcFormat == GL_COLOR_INDEX) {
30397117f1b4Smrg         GLuint indexes[MAX_WIDTH];
30407117f1b4Smrg         extract_uint_indexes(n, indexes, srcFormat, srcType, source,
30417117f1b4Smrg                              srcPacking);
30427117f1b4Smrg
30437117f1b4Smrg         if (dstFormat == GL_COLOR_INDEX) {
30447117f1b4Smrg            GLuint i;
30457117f1b4Smrg            _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
30467117f1b4Smrg            /* convert to GLchan and return */
30477117f1b4Smrg            for (i = 0; i < n; i++) {
30487117f1b4Smrg               dest[i] = (GLchan) (indexes[i] & 0xff);
30497117f1b4Smrg            }
30507117f1b4Smrg            return;
30517117f1b4Smrg         }
30527117f1b4Smrg         else {
30537117f1b4Smrg            /* Convert indexes to RGBA */
30547117f1b4Smrg            if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
30557117f1b4Smrg               shift_and_offset_ci(ctx, n, indexes);
30567117f1b4Smrg            }
30577117f1b4Smrg            _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
30587117f1b4Smrg         }
30597117f1b4Smrg
30607117f1b4Smrg         /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
30617117f1b4Smrg          * with color indexes.
30627117f1b4Smrg          */
30637117f1b4Smrg         transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
30647117f1b4Smrg      }
30657117f1b4Smrg      else {
30667117f1b4Smrg         /* non-color index data */
30677117f1b4Smrg         extract_float_rgba(n, rgba, srcFormat, srcType, source,
30687117f1b4Smrg                            srcPacking->SwapBytes);
30697117f1b4Smrg      }
30707117f1b4Smrg
30717117f1b4Smrg      /* Need to clamp if returning GLubytes or GLushorts */
30727117f1b4Smrg#if CHAN_TYPE != GL_FLOAT
30737117f1b4Smrg      transferOps |= IMAGE_CLAMP_BIT;
30747117f1b4Smrg#endif
30757117f1b4Smrg
30767117f1b4Smrg      if (transferOps) {
30777117f1b4Smrg         _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
30787117f1b4Smrg      }
30797117f1b4Smrg
30807117f1b4Smrg      /* Now determine which color channels we need to produce.
30817117f1b4Smrg       * And determine the dest index (offset) within each color tuple.
30827117f1b4Smrg       */
30837117f1b4Smrg      switch (dstFormat) {
30847117f1b4Smrg         case GL_ALPHA:
30857117f1b4Smrg            dstAlphaIndex = 0;
30867117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
30877117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
30887117f1b4Smrg            break;
30897117f1b4Smrg         case GL_LUMINANCE:
30907117f1b4Smrg            dstLuminanceIndex = 0;
30917117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
30927117f1b4Smrg            dstIntensityIndex = -1;
30937117f1b4Smrg            break;
30947117f1b4Smrg         case GL_LUMINANCE_ALPHA:
30957117f1b4Smrg            dstLuminanceIndex = 0;
30967117f1b4Smrg            dstAlphaIndex = 1;
30977117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
30987117f1b4Smrg            dstIntensityIndex = -1;
30997117f1b4Smrg            break;
31007117f1b4Smrg         case GL_INTENSITY:
31017117f1b4Smrg            dstIntensityIndex = 0;
31027117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
31037117f1b4Smrg            dstLuminanceIndex = -1;
31047117f1b4Smrg            break;
31057117f1b4Smrg         case GL_RGB:
31067117f1b4Smrg            dstRedIndex = 0;
31077117f1b4Smrg            dstGreenIndex = 1;
31087117f1b4Smrg            dstBlueIndex = 2;
31097117f1b4Smrg            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
31107117f1b4Smrg            break;
31117117f1b4Smrg         case GL_RGBA:
31127117f1b4Smrg            dstRedIndex = 0;
31137117f1b4Smrg            dstGreenIndex = 1;
31147117f1b4Smrg            dstBlueIndex = 2;
31157117f1b4Smrg            dstAlphaIndex = 3;
31167117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
31177117f1b4Smrg            break;
31187117f1b4Smrg         default:
31197117f1b4Smrg            _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_chan_span()");
31207117f1b4Smrg            return;
31217117f1b4Smrg      }
31227117f1b4Smrg
31237117f1b4Smrg
31247117f1b4Smrg      /* Now return the GLchan data in the requested dstFormat */
31257117f1b4Smrg
31267117f1b4Smrg      if (dstRedIndex >= 0) {
31277117f1b4Smrg         GLchan *dst = dest;
31287117f1b4Smrg         GLuint i;
31297117f1b4Smrg         for (i = 0; i < n; i++) {
31307117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstRedIndex], rgba[i][RCOMP]);
31317117f1b4Smrg            dst += dstComponents;
31327117f1b4Smrg         }
31337117f1b4Smrg      }
31347117f1b4Smrg
31357117f1b4Smrg      if (dstGreenIndex >= 0) {
31367117f1b4Smrg         GLchan *dst = dest;
31377117f1b4Smrg         GLuint i;
31387117f1b4Smrg         for (i = 0; i < n; i++) {
31397117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstGreenIndex], rgba[i][GCOMP]);
31407117f1b4Smrg            dst += dstComponents;
31417117f1b4Smrg         }
31427117f1b4Smrg      }
31437117f1b4Smrg
31447117f1b4Smrg      if (dstBlueIndex >= 0) {
31457117f1b4Smrg         GLchan *dst = dest;
31467117f1b4Smrg         GLuint i;
31477117f1b4Smrg         for (i = 0; i < n; i++) {
31487117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstBlueIndex], rgba[i][BCOMP]);
31497117f1b4Smrg            dst += dstComponents;
31507117f1b4Smrg         }
31517117f1b4Smrg      }
31527117f1b4Smrg
31537117f1b4Smrg      if (dstAlphaIndex >= 0) {
31547117f1b4Smrg         GLchan *dst = dest;
31557117f1b4Smrg         GLuint i;
31567117f1b4Smrg         for (i = 0; i < n; i++) {
31577117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[dstAlphaIndex], rgba[i][ACOMP]);
31587117f1b4Smrg            dst += dstComponents;
31597117f1b4Smrg         }
31607117f1b4Smrg      }
31617117f1b4Smrg
31627117f1b4Smrg      if (dstIntensityIndex >= 0) {
31637117f1b4Smrg         GLchan *dst = dest;
31647117f1b4Smrg         GLuint i;
31657117f1b4Smrg         assert(dstIntensityIndex == 0);
31667117f1b4Smrg         assert(dstComponents == 1);
31677117f1b4Smrg         for (i = 0; i < n; i++) {
31687117f1b4Smrg            /* Intensity comes from red channel */
31697117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[i], rgba[i][RCOMP]);
31707117f1b4Smrg         }
31717117f1b4Smrg      }
31727117f1b4Smrg
31737117f1b4Smrg      if (dstLuminanceIndex >= 0) {
31747117f1b4Smrg         GLchan *dst = dest;
31757117f1b4Smrg         GLuint i;
31767117f1b4Smrg         assert(dstLuminanceIndex == 0);
31777117f1b4Smrg         for (i = 0; i < n; i++) {
31787117f1b4Smrg            /* Luminance comes from red channel */
31797117f1b4Smrg            CLAMPED_FLOAT_TO_CHAN(dst[0], rgba[i][RCOMP]);
31807117f1b4Smrg            dst += dstComponents;
31817117f1b4Smrg         }
31827117f1b4Smrg      }
31837117f1b4Smrg   }
31847117f1b4Smrg}
31857117f1b4Smrg
31867117f1b4Smrg
31877117f1b4Smrg/**
31887117f1b4Smrg * Same as _mesa_unpack_color_span_chan(), but return GLfloat data
31897117f1b4Smrg * instead of GLchan.
31907117f1b4Smrg */
31917117f1b4Smrgvoid
31927117f1b4Smrg_mesa_unpack_color_span_float( GLcontext *ctx,
31937117f1b4Smrg                               GLuint n, GLenum dstFormat, GLfloat dest[],
31947117f1b4Smrg                               GLenum srcFormat, GLenum srcType,
31957117f1b4Smrg                               const GLvoid *source,
31967117f1b4Smrg                               const struct gl_pixelstore_attrib *srcPacking,
31977117f1b4Smrg                               GLbitfield transferOps )
31987117f1b4Smrg{
31997117f1b4Smrg   ASSERT(dstFormat == GL_ALPHA ||
32007117f1b4Smrg          dstFormat == GL_LUMINANCE ||
32017117f1b4Smrg          dstFormat == GL_LUMINANCE_ALPHA ||
32027117f1b4Smrg          dstFormat == GL_INTENSITY ||
32037117f1b4Smrg          dstFormat == GL_RGB ||
32047117f1b4Smrg          dstFormat == GL_RGBA ||
32057117f1b4Smrg          dstFormat == GL_COLOR_INDEX);
32067117f1b4Smrg
32077117f1b4Smrg   ASSERT(srcFormat == GL_RED ||
32087117f1b4Smrg          srcFormat == GL_GREEN ||
32097117f1b4Smrg          srcFormat == GL_BLUE ||
32107117f1b4Smrg          srcFormat == GL_ALPHA ||
32117117f1b4Smrg          srcFormat == GL_LUMINANCE ||
32127117f1b4Smrg          srcFormat == GL_LUMINANCE_ALPHA ||
32137117f1b4Smrg          srcFormat == GL_INTENSITY ||
32147117f1b4Smrg          srcFormat == GL_RGB ||
32157117f1b4Smrg          srcFormat == GL_BGR ||
32167117f1b4Smrg          srcFormat == GL_RGBA ||
32177117f1b4Smrg          srcFormat == GL_BGRA ||
32187117f1b4Smrg          srcFormat == GL_ABGR_EXT ||
32197117f1b4Smrg          srcFormat == GL_COLOR_INDEX);
32207117f1b4Smrg
32217117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
32227117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
32237117f1b4Smrg          srcType == GL_BYTE ||
32247117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
32257117f1b4Smrg          srcType == GL_SHORT ||
32267117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
32277117f1b4Smrg          srcType == GL_INT ||
32287117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
32297117f1b4Smrg          srcType == GL_FLOAT ||
32307117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_3_3_2 ||
32317117f1b4Smrg          srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
32327117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5 ||
32337117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
32347117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
32357117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
32367117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
32377117f1b4Smrg          srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
32387117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8 ||
32397117f1b4Smrg          srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
32407117f1b4Smrg          srcType == GL_UNSIGNED_INT_10_10_10_2 ||
32417117f1b4Smrg          srcType == GL_UNSIGNED_INT_2_10_10_10_REV);
32427117f1b4Smrg
32437117f1b4Smrg   /* general solution, no special cases, yet */
32447117f1b4Smrg   {
32457117f1b4Smrg      GLint dstComponents;
32467117f1b4Smrg      GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex;
32477117f1b4Smrg      GLint dstLuminanceIndex, dstIntensityIndex;
32487117f1b4Smrg      GLfloat rgba[MAX_WIDTH][4];
32497117f1b4Smrg
32507117f1b4Smrg      dstComponents = _mesa_components_in_format( dstFormat );
32517117f1b4Smrg      /* source & dest image formats should have been error checked by now */
32527117f1b4Smrg      assert(dstComponents > 0);
32537117f1b4Smrg
32547117f1b4Smrg      /*
32557117f1b4Smrg       * Extract image data and convert to RGBA floats
32567117f1b4Smrg       */
32577117f1b4Smrg      assert(n <= MAX_WIDTH);
32587117f1b4Smrg      if (srcFormat == GL_COLOR_INDEX) {
32597117f1b4Smrg         GLuint indexes[MAX_WIDTH];
32607117f1b4Smrg         extract_uint_indexes(n, indexes, srcFormat, srcType, source,
32617117f1b4Smrg                              srcPacking);
32627117f1b4Smrg
32637117f1b4Smrg         if (dstFormat == GL_COLOR_INDEX) {
32647117f1b4Smrg            GLuint i;
32657117f1b4Smrg            _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
32667117f1b4Smrg            /* convert to GLchan and return */
32677117f1b4Smrg            for (i = 0; i < n; i++) {
32687117f1b4Smrg               dest[i] = (GLchan) (indexes[i] & 0xff);
32697117f1b4Smrg            }
32707117f1b4Smrg            return;
32717117f1b4Smrg         }
32727117f1b4Smrg         else {
32737117f1b4Smrg            /* Convert indexes to RGBA */
32747117f1b4Smrg            if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
32757117f1b4Smrg               shift_and_offset_ci(ctx, n, indexes);
32767117f1b4Smrg            }
32777117f1b4Smrg            _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
32787117f1b4Smrg         }
32797117f1b4Smrg
32807117f1b4Smrg         /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
32817117f1b4Smrg          * with color indexes.
32827117f1b4Smrg          */
32837117f1b4Smrg         transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
32847117f1b4Smrg      }
32857117f1b4Smrg      else {
32867117f1b4Smrg         /* non-color index data */
32877117f1b4Smrg         extract_float_rgba(n, rgba, srcFormat, srcType, source,
32887117f1b4Smrg                            srcPacking->SwapBytes);
32897117f1b4Smrg      }
32907117f1b4Smrg
32917117f1b4Smrg      if (transferOps) {
32927117f1b4Smrg         _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
32937117f1b4Smrg      }
32947117f1b4Smrg
32957117f1b4Smrg      /* Now determine which color channels we need to produce.
32967117f1b4Smrg       * And determine the dest index (offset) within each color tuple.
32977117f1b4Smrg       */
32987117f1b4Smrg      switch (dstFormat) {
32997117f1b4Smrg         case GL_ALPHA:
33007117f1b4Smrg            dstAlphaIndex = 0;
33017117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
33027117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
33037117f1b4Smrg            break;
33047117f1b4Smrg         case GL_LUMINANCE:
33057117f1b4Smrg            dstLuminanceIndex = 0;
33067117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
33077117f1b4Smrg            dstIntensityIndex = -1;
33087117f1b4Smrg            break;
33097117f1b4Smrg         case GL_LUMINANCE_ALPHA:
33107117f1b4Smrg            dstLuminanceIndex = 0;
33117117f1b4Smrg            dstAlphaIndex = 1;
33127117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = -1;
33137117f1b4Smrg            dstIntensityIndex = -1;
33147117f1b4Smrg            break;
33157117f1b4Smrg         case GL_INTENSITY:
33167117f1b4Smrg            dstIntensityIndex = 0;
33177117f1b4Smrg            dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1;
33187117f1b4Smrg            dstLuminanceIndex = -1;
33197117f1b4Smrg            break;
33207117f1b4Smrg         case GL_RGB:
33217117f1b4Smrg            dstRedIndex = 0;
33227117f1b4Smrg            dstGreenIndex = 1;
33237117f1b4Smrg            dstBlueIndex = 2;
33247117f1b4Smrg            dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1;
33257117f1b4Smrg            break;
33267117f1b4Smrg         case GL_RGBA:
33277117f1b4Smrg            dstRedIndex = 0;
33287117f1b4Smrg            dstGreenIndex = 1;
33297117f1b4Smrg            dstBlueIndex = 2;
33307117f1b4Smrg            dstAlphaIndex = 3;
33317117f1b4Smrg            dstLuminanceIndex = dstIntensityIndex = -1;
33327117f1b4Smrg            break;
33337117f1b4Smrg         default:
33347117f1b4Smrg            _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_color_span_float()");
33357117f1b4Smrg            return;
33367117f1b4Smrg      }
33377117f1b4Smrg
33387117f1b4Smrg      /* Now pack results in the requested dstFormat */
33397117f1b4Smrg      if (dstRedIndex >= 0) {
33407117f1b4Smrg         GLfloat *dst = dest;
33417117f1b4Smrg         GLuint i;
33427117f1b4Smrg         for (i = 0; i < n; i++) {
33437117f1b4Smrg            dst[dstRedIndex] = rgba[i][RCOMP];
33447117f1b4Smrg            dst += dstComponents;
33457117f1b4Smrg         }
33467117f1b4Smrg      }
33477117f1b4Smrg
33487117f1b4Smrg      if (dstGreenIndex >= 0) {
33497117f1b4Smrg         GLfloat *dst = dest;
33507117f1b4Smrg         GLuint i;
33517117f1b4Smrg         for (i = 0; i < n; i++) {
33527117f1b4Smrg            dst[dstGreenIndex] = rgba[i][GCOMP];
33537117f1b4Smrg            dst += dstComponents;
33547117f1b4Smrg         }
33557117f1b4Smrg      }
33567117f1b4Smrg
33577117f1b4Smrg      if (dstBlueIndex >= 0) {
33587117f1b4Smrg         GLfloat *dst = dest;
33597117f1b4Smrg         GLuint i;
33607117f1b4Smrg         for (i = 0; i < n; i++) {
33617117f1b4Smrg            dst[dstBlueIndex] = rgba[i][BCOMP];
33627117f1b4Smrg            dst += dstComponents;
33637117f1b4Smrg         }
33647117f1b4Smrg      }
33657117f1b4Smrg
33667117f1b4Smrg      if (dstAlphaIndex >= 0) {
33677117f1b4Smrg         GLfloat *dst = dest;
33687117f1b4Smrg         GLuint i;
33697117f1b4Smrg         for (i = 0; i < n; i++) {
33707117f1b4Smrg            dst[dstAlphaIndex] = rgba[i][ACOMP];
33717117f1b4Smrg            dst += dstComponents;
33727117f1b4Smrg         }
33737117f1b4Smrg      }
33747117f1b4Smrg
33757117f1b4Smrg      if (dstIntensityIndex >= 0) {
33767117f1b4Smrg         GLfloat *dst = dest;
33777117f1b4Smrg         GLuint i;
33787117f1b4Smrg         assert(dstIntensityIndex == 0);
33797117f1b4Smrg         assert(dstComponents == 1);
33807117f1b4Smrg         for (i = 0; i < n; i++) {
33817117f1b4Smrg            /* Intensity comes from red channel */
33827117f1b4Smrg            dst[i] = rgba[i][RCOMP];
33837117f1b4Smrg         }
33847117f1b4Smrg      }
33857117f1b4Smrg
33867117f1b4Smrg      if (dstLuminanceIndex >= 0) {
33877117f1b4Smrg         GLfloat *dst = dest;
33887117f1b4Smrg         GLuint i;
33897117f1b4Smrg         assert(dstLuminanceIndex == 0);
33907117f1b4Smrg         for (i = 0; i < n; i++) {
33917117f1b4Smrg            /* Luminance comes from red channel */
33927117f1b4Smrg            dst[0] = rgba[i][RCOMP];
33937117f1b4Smrg            dst += dstComponents;
33947117f1b4Smrg         }
33957117f1b4Smrg      }
33967117f1b4Smrg   }
33977117f1b4Smrg}
33987117f1b4Smrg
33997117f1b4Smrg
34007117f1b4Smrg/*
34017117f1b4Smrg * Unpack a row of color index data from a client buffer according to
34027117f1b4Smrg * the pixel unpacking parameters.
34037117f1b4Smrg * This is (or will be) used by glDrawPixels, glTexImage[123]D, etc.
34047117f1b4Smrg *
34057117f1b4Smrg * Args:  ctx - the context
34067117f1b4Smrg *        n - number of pixels
34077117f1b4Smrg *        dstType - destination data type
34087117f1b4Smrg *        dest - destination array
34097117f1b4Smrg *        srcType - source pixel type
34107117f1b4Smrg *        source - source data pointer
34117117f1b4Smrg *        srcPacking - pixel unpacking parameters
34127117f1b4Smrg *        transferOps - the pixel transfer operations to apply
34137117f1b4Smrg */
34147117f1b4Smrgvoid
34157117f1b4Smrg_mesa_unpack_index_span( const GLcontext *ctx, GLuint n,
34167117f1b4Smrg                         GLenum dstType, GLvoid *dest,
34177117f1b4Smrg                         GLenum srcType, const GLvoid *source,
34187117f1b4Smrg                         const struct gl_pixelstore_attrib *srcPacking,
34197117f1b4Smrg                         GLbitfield transferOps )
34207117f1b4Smrg{
34217117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
34227117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
34237117f1b4Smrg          srcType == GL_BYTE ||
34247117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
34257117f1b4Smrg          srcType == GL_SHORT ||
34267117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
34277117f1b4Smrg          srcType == GL_INT ||
34287117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
34297117f1b4Smrg          srcType == GL_FLOAT);
34307117f1b4Smrg
34317117f1b4Smrg   ASSERT(dstType == GL_UNSIGNED_BYTE ||
34327117f1b4Smrg          dstType == GL_UNSIGNED_SHORT ||
34337117f1b4Smrg          dstType == GL_UNSIGNED_INT);
34347117f1b4Smrg
34357117f1b4Smrg
34367117f1b4Smrg   transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
34377117f1b4Smrg
34387117f1b4Smrg   /*
34397117f1b4Smrg    * Try simple cases first
34407117f1b4Smrg    */
34417117f1b4Smrg   if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE
34427117f1b4Smrg       && dstType == GL_UNSIGNED_BYTE) {
34437117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLubyte));
34447117f1b4Smrg   }
34457117f1b4Smrg   else if (transferOps == 0 && srcType == GL_UNSIGNED_INT
34467117f1b4Smrg            && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) {
34477117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLuint));
34487117f1b4Smrg   }
34497117f1b4Smrg   else {
34507117f1b4Smrg      /*
34517117f1b4Smrg       * general solution
34527117f1b4Smrg       */
34537117f1b4Smrg      GLuint indexes[MAX_WIDTH];
34547117f1b4Smrg      assert(n <= MAX_WIDTH);
34557117f1b4Smrg
34567117f1b4Smrg      extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
34577117f1b4Smrg                           srcPacking);
34587117f1b4Smrg
34597117f1b4Smrg      if (transferOps)
34607117f1b4Smrg         _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
34617117f1b4Smrg
34627117f1b4Smrg      /* convert to dest type */
34637117f1b4Smrg      switch (dstType) {
34647117f1b4Smrg         case GL_UNSIGNED_BYTE:
34657117f1b4Smrg            {
34667117f1b4Smrg               GLubyte *dst = (GLubyte *) dest;
34677117f1b4Smrg               GLuint i;
34687117f1b4Smrg               for (i = 0; i < n; i++) {
34697117f1b4Smrg                  dst[i] = (GLubyte) (indexes[i] & 0xff);
34707117f1b4Smrg               }
34717117f1b4Smrg            }
34727117f1b4Smrg            break;
34737117f1b4Smrg         case GL_UNSIGNED_SHORT:
34747117f1b4Smrg            {
34757117f1b4Smrg               GLuint *dst = (GLuint *) dest;
34767117f1b4Smrg               GLuint i;
34777117f1b4Smrg               for (i = 0; i < n; i++) {
34787117f1b4Smrg                  dst[i] = (GLushort) (indexes[i] & 0xffff);
34797117f1b4Smrg               }
34807117f1b4Smrg            }
34817117f1b4Smrg            break;
34827117f1b4Smrg         case GL_UNSIGNED_INT:
34837117f1b4Smrg            _mesa_memcpy(dest, indexes, n * sizeof(GLuint));
34847117f1b4Smrg            break;
34857117f1b4Smrg         default:
34867117f1b4Smrg            _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span");
34877117f1b4Smrg      }
34887117f1b4Smrg   }
34897117f1b4Smrg}
34907117f1b4Smrg
34917117f1b4Smrg
34927117f1b4Smrgvoid
34937117f1b4Smrg_mesa_pack_index_span( const GLcontext *ctx, GLuint n,
34947117f1b4Smrg                       GLenum dstType, GLvoid *dest, const GLuint *source,
34957117f1b4Smrg                       const struct gl_pixelstore_attrib *dstPacking,
34967117f1b4Smrg                       GLbitfield transferOps )
34977117f1b4Smrg{
34987117f1b4Smrg   GLuint indexes[MAX_WIDTH];
34997117f1b4Smrg
35007117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
35017117f1b4Smrg
35027117f1b4Smrg   transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT);
35037117f1b4Smrg
35047117f1b4Smrg   if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) {
35057117f1b4Smrg      /* make a copy of input */
35067117f1b4Smrg      _mesa_memcpy(indexes, source, n * sizeof(GLuint));
35077117f1b4Smrg      _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
35087117f1b4Smrg      source = indexes;
35097117f1b4Smrg   }
35107117f1b4Smrg
35117117f1b4Smrg   switch (dstType) {
35127117f1b4Smrg   case GL_UNSIGNED_BYTE:
35137117f1b4Smrg      {
35147117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
35157117f1b4Smrg         GLuint i;
35167117f1b4Smrg         for (i = 0; i < n; i++) {
35177117f1b4Smrg            *dst++ = (GLubyte) source[i];
35187117f1b4Smrg         }
35197117f1b4Smrg      }
35207117f1b4Smrg      break;
35217117f1b4Smrg   case GL_BYTE:
35227117f1b4Smrg      {
35237117f1b4Smrg         GLbyte *dst = (GLbyte *) dest;
35247117f1b4Smrg         GLuint i;
35257117f1b4Smrg         for (i = 0; i < n; i++) {
35267117f1b4Smrg            dst[i] = (GLbyte) source[i];
35277117f1b4Smrg         }
35287117f1b4Smrg      }
35297117f1b4Smrg      break;
35307117f1b4Smrg   case GL_UNSIGNED_SHORT:
35317117f1b4Smrg      {
35327117f1b4Smrg         GLushort *dst = (GLushort *) dest;
35337117f1b4Smrg         GLuint i;
35347117f1b4Smrg         for (i = 0; i < n; i++) {
35357117f1b4Smrg            dst[i] = (GLushort) source[i];
35367117f1b4Smrg         }
35377117f1b4Smrg         if (dstPacking->SwapBytes) {
35387117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
35397117f1b4Smrg         }
35407117f1b4Smrg      }
35417117f1b4Smrg      break;
35427117f1b4Smrg   case GL_SHORT:
35437117f1b4Smrg      {
35447117f1b4Smrg         GLshort *dst = (GLshort *) dest;
35457117f1b4Smrg         GLuint i;
35467117f1b4Smrg         for (i = 0; i < n; i++) {
35477117f1b4Smrg            dst[i] = (GLshort) source[i];
35487117f1b4Smrg         }
35497117f1b4Smrg         if (dstPacking->SwapBytes) {
35507117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
35517117f1b4Smrg         }
35527117f1b4Smrg      }
35537117f1b4Smrg      break;
35547117f1b4Smrg   case GL_UNSIGNED_INT:
35557117f1b4Smrg      {
35567117f1b4Smrg         GLuint *dst = (GLuint *) dest;
35577117f1b4Smrg         GLuint i;
35587117f1b4Smrg         for (i = 0; i < n; i++) {
35597117f1b4Smrg            dst[i] = (GLuint) source[i];
35607117f1b4Smrg         }
35617117f1b4Smrg         if (dstPacking->SwapBytes) {
35627117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
35637117f1b4Smrg         }
35647117f1b4Smrg      }
35657117f1b4Smrg      break;
35667117f1b4Smrg   case GL_INT:
35677117f1b4Smrg      {
35687117f1b4Smrg         GLint *dst = (GLint *) dest;
35697117f1b4Smrg         GLuint i;
35707117f1b4Smrg         for (i = 0; i < n; i++) {
35717117f1b4Smrg            dst[i] = (GLint) source[i];
35727117f1b4Smrg         }
35737117f1b4Smrg         if (dstPacking->SwapBytes) {
35747117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
35757117f1b4Smrg         }
35767117f1b4Smrg      }
35777117f1b4Smrg      break;
35787117f1b4Smrg   case GL_FLOAT:
35797117f1b4Smrg      {
35807117f1b4Smrg         GLfloat *dst = (GLfloat *) dest;
35817117f1b4Smrg         GLuint i;
35827117f1b4Smrg         for (i = 0; i < n; i++) {
35837117f1b4Smrg            dst[i] = (GLfloat) source[i];
35847117f1b4Smrg         }
35857117f1b4Smrg         if (dstPacking->SwapBytes) {
35867117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
35877117f1b4Smrg         }
35887117f1b4Smrg      }
35897117f1b4Smrg      break;
35907117f1b4Smrg   case GL_HALF_FLOAT_ARB:
35917117f1b4Smrg      {
35927117f1b4Smrg         GLhalfARB *dst = (GLhalfARB *) dest;
35937117f1b4Smrg         GLuint i;
35947117f1b4Smrg         for (i = 0; i < n; i++) {
35957117f1b4Smrg            dst[i] = _mesa_float_to_half((GLfloat) source[i]);
35967117f1b4Smrg         }
35977117f1b4Smrg         if (dstPacking->SwapBytes) {
35987117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
35997117f1b4Smrg         }
36007117f1b4Smrg      }
36017117f1b4Smrg      break;
36027117f1b4Smrg   default:
36037117f1b4Smrg      _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
36047117f1b4Smrg   }
36057117f1b4Smrg}
36067117f1b4Smrg
36077117f1b4Smrg
36087117f1b4Smrg/*
36097117f1b4Smrg * Unpack a row of stencil data from a client buffer according to
36107117f1b4Smrg * the pixel unpacking parameters.
36117117f1b4Smrg * This is (or will be) used by glDrawPixels
36127117f1b4Smrg *
36137117f1b4Smrg * Args:  ctx - the context
36147117f1b4Smrg *        n - number of pixels
36157117f1b4Smrg *        dstType - destination data type
36167117f1b4Smrg *        dest - destination array
36177117f1b4Smrg *        srcType - source pixel type
36187117f1b4Smrg *        source - source data pointer
36197117f1b4Smrg *        srcPacking - pixel unpacking parameters
36207117f1b4Smrg *        transferOps - apply offset/bias/lookup ops?
36217117f1b4Smrg */
36227117f1b4Smrgvoid
36237117f1b4Smrg_mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
36247117f1b4Smrg                           GLenum dstType, GLvoid *dest,
36257117f1b4Smrg                           GLenum srcType, const GLvoid *source,
36267117f1b4Smrg                           const struct gl_pixelstore_attrib *srcPacking,
36277117f1b4Smrg                           GLbitfield transferOps )
36287117f1b4Smrg{
36297117f1b4Smrg   ASSERT(srcType == GL_BITMAP ||
36307117f1b4Smrg          srcType == GL_UNSIGNED_BYTE ||
36317117f1b4Smrg          srcType == GL_BYTE ||
36327117f1b4Smrg          srcType == GL_UNSIGNED_SHORT ||
36337117f1b4Smrg          srcType == GL_SHORT ||
36347117f1b4Smrg          srcType == GL_UNSIGNED_INT ||
36357117f1b4Smrg          srcType == GL_INT ||
36367117f1b4Smrg          srcType == GL_UNSIGNED_INT_24_8_EXT ||
36377117f1b4Smrg          srcType == GL_HALF_FLOAT_ARB ||
36387117f1b4Smrg          srcType == GL_FLOAT);
36397117f1b4Smrg
36407117f1b4Smrg   ASSERT(dstType == GL_UNSIGNED_BYTE ||
36417117f1b4Smrg          dstType == GL_UNSIGNED_SHORT ||
36427117f1b4Smrg          dstType == GL_UNSIGNED_INT);
36437117f1b4Smrg
36447117f1b4Smrg   /* only shift and offset apply to stencil */
36457117f1b4Smrg   transferOps &= IMAGE_SHIFT_OFFSET_BIT;
36467117f1b4Smrg
36477117f1b4Smrg   /*
36487117f1b4Smrg    * Try simple cases first
36497117f1b4Smrg    */
36507117f1b4Smrg   if (transferOps == 0 &&
36517117f1b4Smrg       !ctx->Pixel.MapStencilFlag &&
36527117f1b4Smrg       srcType == GL_UNSIGNED_BYTE &&
36537117f1b4Smrg       dstType == GL_UNSIGNED_BYTE) {
36547117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLubyte));
36557117f1b4Smrg   }
36567117f1b4Smrg   else if (transferOps == 0 &&
36577117f1b4Smrg            !ctx->Pixel.MapStencilFlag &&
36587117f1b4Smrg            srcType == GL_UNSIGNED_INT &&
36597117f1b4Smrg            dstType == GL_UNSIGNED_INT &&
36607117f1b4Smrg            !srcPacking->SwapBytes) {
36617117f1b4Smrg      _mesa_memcpy(dest, source, n * sizeof(GLuint));
36627117f1b4Smrg   }
36637117f1b4Smrg   else {
36647117f1b4Smrg      /*
36657117f1b4Smrg       * general solution
36667117f1b4Smrg       */
36677117f1b4Smrg      GLuint indexes[MAX_WIDTH];
36687117f1b4Smrg      assert(n <= MAX_WIDTH);
36697117f1b4Smrg
36707117f1b4Smrg      extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
36717117f1b4Smrg                           srcPacking);
36727117f1b4Smrg
36737117f1b4Smrg      if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
36747117f1b4Smrg         /* shift and offset indexes */
36757117f1b4Smrg         shift_and_offset_ci(ctx, n, indexes);
36767117f1b4Smrg      }
36777117f1b4Smrg
36787117f1b4Smrg      if (ctx->Pixel.MapStencilFlag) {
36797117f1b4Smrg         /* Apply stencil lookup table */
36807117f1b4Smrg         const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
36817117f1b4Smrg         GLuint i;
36827117f1b4Smrg         for (i = 0; i < n; i++) {
36837117f1b4Smrg            indexes[i] = ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
36847117f1b4Smrg         }
36857117f1b4Smrg      }
36867117f1b4Smrg
36877117f1b4Smrg      /* convert to dest type */
36887117f1b4Smrg      switch (dstType) {
36897117f1b4Smrg         case GL_UNSIGNED_BYTE:
36907117f1b4Smrg            {
36917117f1b4Smrg               GLubyte *dst = (GLubyte *) dest;
36927117f1b4Smrg               GLuint i;
36937117f1b4Smrg               for (i = 0; i < n; i++) {
36947117f1b4Smrg                  dst[i] = (GLubyte) (indexes[i] & 0xff);
36957117f1b4Smrg               }
36967117f1b4Smrg            }
36977117f1b4Smrg            break;
36987117f1b4Smrg         case GL_UNSIGNED_SHORT:
36997117f1b4Smrg            {
37007117f1b4Smrg               GLuint *dst = (GLuint *) dest;
37017117f1b4Smrg               GLuint i;
37027117f1b4Smrg               for (i = 0; i < n; i++) {
37037117f1b4Smrg                  dst[i] = (GLushort) (indexes[i] & 0xffff);
37047117f1b4Smrg               }
37057117f1b4Smrg            }
37067117f1b4Smrg            break;
37077117f1b4Smrg         case GL_UNSIGNED_INT:
37087117f1b4Smrg            _mesa_memcpy(dest, indexes, n * sizeof(GLuint));
37097117f1b4Smrg            break;
37107117f1b4Smrg         default:
37117117f1b4Smrg            _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
37127117f1b4Smrg      }
37137117f1b4Smrg   }
37147117f1b4Smrg}
37157117f1b4Smrg
37167117f1b4Smrg
37177117f1b4Smrgvoid
37187117f1b4Smrg_mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
37197117f1b4Smrg                         GLenum dstType, GLvoid *dest, const GLstencil *source,
37207117f1b4Smrg                         const struct gl_pixelstore_attrib *dstPacking )
37217117f1b4Smrg{
37227117f1b4Smrg   GLstencil stencil[MAX_WIDTH];
37237117f1b4Smrg
37247117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
37257117f1b4Smrg
37267117f1b4Smrg   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
37277117f1b4Smrg       ctx->Pixel.MapStencilFlag) {
37287117f1b4Smrg      /* make a copy of input */
37297117f1b4Smrg      _mesa_memcpy(stencil, source, n * sizeof(GLstencil));
37307117f1b4Smrg      _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
37317117f1b4Smrg      source = stencil;
37327117f1b4Smrg   }
37337117f1b4Smrg
37347117f1b4Smrg   switch (dstType) {
37357117f1b4Smrg   case GL_UNSIGNED_BYTE:
37367117f1b4Smrg      if (sizeof(GLstencil) == 1) {
37377117f1b4Smrg         _mesa_memcpy( dest, source, n );
37387117f1b4Smrg      }
37397117f1b4Smrg      else {
37407117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
37417117f1b4Smrg         GLuint i;
37427117f1b4Smrg         for (i=0;i<n;i++) {
37437117f1b4Smrg            dst[i] = (GLubyte) source[i];
37447117f1b4Smrg         }
37457117f1b4Smrg      }
37467117f1b4Smrg      break;
37477117f1b4Smrg   case GL_BYTE:
37487117f1b4Smrg      {
37497117f1b4Smrg         GLbyte *dst = (GLbyte *) dest;
37507117f1b4Smrg         GLuint i;
37517117f1b4Smrg         for (i=0;i<n;i++) {
37527117f1b4Smrg            dst[i] = (GLbyte) (source[i] & 0x7f);
37537117f1b4Smrg         }
37547117f1b4Smrg      }
37557117f1b4Smrg      break;
37567117f1b4Smrg   case GL_UNSIGNED_SHORT:
37577117f1b4Smrg      {
37587117f1b4Smrg         GLushort *dst = (GLushort *) dest;
37597117f1b4Smrg         GLuint i;
37607117f1b4Smrg         for (i=0;i<n;i++) {
37617117f1b4Smrg            dst[i] = (GLushort) source[i];
37627117f1b4Smrg         }
37637117f1b4Smrg         if (dstPacking->SwapBytes) {
37647117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
37657117f1b4Smrg         }
37667117f1b4Smrg      }
37677117f1b4Smrg      break;
37687117f1b4Smrg   case GL_SHORT:
37697117f1b4Smrg      {
37707117f1b4Smrg         GLshort *dst = (GLshort *) dest;
37717117f1b4Smrg         GLuint i;
37727117f1b4Smrg         for (i=0;i<n;i++) {
37737117f1b4Smrg            dst[i] = (GLshort) source[i];
37747117f1b4Smrg         }
37757117f1b4Smrg         if (dstPacking->SwapBytes) {
37767117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
37777117f1b4Smrg         }
37787117f1b4Smrg      }
37797117f1b4Smrg      break;
37807117f1b4Smrg   case GL_UNSIGNED_INT:
37817117f1b4Smrg      {
37827117f1b4Smrg         GLuint *dst = (GLuint *) dest;
37837117f1b4Smrg         GLuint i;
37847117f1b4Smrg         for (i=0;i<n;i++) {
37857117f1b4Smrg            dst[i] = (GLuint) source[i];
37867117f1b4Smrg         }
37877117f1b4Smrg         if (dstPacking->SwapBytes) {
37887117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
37897117f1b4Smrg         }
37907117f1b4Smrg      }
37917117f1b4Smrg      break;
37927117f1b4Smrg   case GL_INT:
37937117f1b4Smrg      {
37947117f1b4Smrg         GLint *dst = (GLint *) dest;
37957117f1b4Smrg         GLuint i;
37967117f1b4Smrg         for (i=0;i<n;i++) {
37977117f1b4Smrg            dst[i] = (GLint) source[i];
37987117f1b4Smrg         }
37997117f1b4Smrg         if (dstPacking->SwapBytes) {
38007117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
38017117f1b4Smrg         }
38027117f1b4Smrg      }
38037117f1b4Smrg      break;
38047117f1b4Smrg   case GL_FLOAT:
38057117f1b4Smrg      {
38067117f1b4Smrg         GLfloat *dst = (GLfloat *) dest;
38077117f1b4Smrg         GLuint i;
38087117f1b4Smrg         for (i=0;i<n;i++) {
38097117f1b4Smrg            dst[i] = (GLfloat) source[i];
38107117f1b4Smrg         }
38117117f1b4Smrg         if (dstPacking->SwapBytes) {
38127117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
38137117f1b4Smrg         }
38147117f1b4Smrg      }
38157117f1b4Smrg      break;
38167117f1b4Smrg   case GL_HALF_FLOAT_ARB:
38177117f1b4Smrg      {
38187117f1b4Smrg         GLhalfARB *dst = (GLhalfARB *) dest;
38197117f1b4Smrg         GLuint i;
38207117f1b4Smrg         for (i=0;i<n;i++) {
38217117f1b4Smrg            dst[i] = _mesa_float_to_half( (float) source[i] );
38227117f1b4Smrg         }
38237117f1b4Smrg         if (dstPacking->SwapBytes) {
38247117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
38257117f1b4Smrg         }
38267117f1b4Smrg      }
38277117f1b4Smrg      break;
38287117f1b4Smrg   case GL_BITMAP:
38297117f1b4Smrg      if (dstPacking->LsbFirst) {
38307117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
38317117f1b4Smrg         GLint shift = 0;
38327117f1b4Smrg         GLuint i;
38337117f1b4Smrg         for (i = 0; i < n; i++) {
38347117f1b4Smrg            if (shift == 0)
38357117f1b4Smrg               *dst = 0;
38367117f1b4Smrg            *dst |= ((source[i] != 0) << shift);
38377117f1b4Smrg            shift++;
38387117f1b4Smrg            if (shift == 8) {
38397117f1b4Smrg               shift = 0;
38407117f1b4Smrg               dst++;
38417117f1b4Smrg            }
38427117f1b4Smrg         }
38437117f1b4Smrg      }
38447117f1b4Smrg      else {
38457117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
38467117f1b4Smrg         GLint shift = 7;
38477117f1b4Smrg         GLuint i;
38487117f1b4Smrg         for (i = 0; i < n; i++) {
38497117f1b4Smrg            if (shift == 7)
38507117f1b4Smrg               *dst = 0;
38517117f1b4Smrg            *dst |= ((source[i] != 0) << shift);
38527117f1b4Smrg            shift--;
38537117f1b4Smrg            if (shift < 0) {
38547117f1b4Smrg               shift = 7;
38557117f1b4Smrg               dst++;
38567117f1b4Smrg            }
38577117f1b4Smrg         }
38587117f1b4Smrg      }
38597117f1b4Smrg      break;
38607117f1b4Smrg   default:
38617117f1b4Smrg      _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
38627117f1b4Smrg   }
38637117f1b4Smrg}
38647117f1b4Smrg
38657117f1b4Smrg#define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT)                              \
38667117f1b4Smrg    do {                                                                \
38677117f1b4Smrg        GLuint i;                                                       \
38687117f1b4Smrg        const GLTYPE *src = (const GLTYPE *)source;                     \
38697117f1b4Smrg        for (i = 0; i < n; i++) {                                       \
38707117f1b4Smrg            GLTYPE value = src[i];                                      \
38717117f1b4Smrg            if (srcPacking->SwapBytes) {                                \
38727117f1b4Smrg                if (sizeof(GLTYPE) == 2) {                              \
38737117f1b4Smrg                    SWAP2BYTE(value);                                   \
38747117f1b4Smrg                } else if (sizeof(GLTYPE) == 4) {                       \
38757117f1b4Smrg                    SWAP4BYTE(value);                                   \
38767117f1b4Smrg                }                                                       \
38777117f1b4Smrg            }                                                           \
38787117f1b4Smrg            depthValues[i] = GLTYPE2FLOAT(value);                       \
38797117f1b4Smrg        }                                                               \
38807117f1b4Smrg    } while (0)
38817117f1b4Smrg
38827117f1b4Smrg
38837117f1b4Smrg/**
38847117f1b4Smrg * Unpack a row of depth/z values from memory, returning GLushort, GLuint
38857117f1b4Smrg * or GLfloat values.
38867117f1b4Smrg * The glPixelTransfer (scale/bias) params will be applied.
38877117f1b4Smrg *
38887117f1b4Smrg * \param dstType  one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT
38897117f1b4Smrg * \param depthScale  scale factor (max value) for returned GLushort or
38907117f1b4Smrg *                    GLuint values (ignored for GLfloat).
38917117f1b4Smrg */
38927117f1b4Smrgvoid
38937117f1b4Smrg_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
38947117f1b4Smrg                         GLenum dstType, GLvoid *dest, GLfloat depthScale,
38957117f1b4Smrg                         GLenum srcType, const GLvoid *source,
38967117f1b4Smrg                         const struct gl_pixelstore_attrib *srcPacking )
38977117f1b4Smrg{
38987117f1b4Smrg   GLfloat depthTemp[MAX_WIDTH], *depthValues;
38997117f1b4Smrg   GLboolean needClamp = GL_FALSE;
39007117f1b4Smrg
39017117f1b4Smrg   /* Look for special cases first.
39027117f1b4Smrg    * Not only are these faster, they're less prone to numeric conversion
39037117f1b4Smrg    * problems.  Otherwise, converting from an int type to a float then
39047117f1b4Smrg    * back to an int type can introduce errors that will show up as
39057117f1b4Smrg    * artifacts in things like depth peeling which uses glCopyTexImage.
39067117f1b4Smrg    */
39077117f1b4Smrg   if (ctx->Pixel.DepthScale == 1.0 && ctx->Pixel.DepthBias == 0.0) {
39087117f1b4Smrg      if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) {
39097117f1b4Smrg         const GLuint *src = (const GLuint *) source;
39107117f1b4Smrg         GLushort *dst = (GLushort *) dest;
39117117f1b4Smrg         GLuint i;
39127117f1b4Smrg         for (i = 0; i < n; i++) {
39137117f1b4Smrg            dst[i] = src[i] >> 16;
39147117f1b4Smrg         }
39157117f1b4Smrg         return;
39167117f1b4Smrg      }
39177117f1b4Smrg      if (srcType == GL_UNSIGNED_SHORT
39187117f1b4Smrg          && dstType == GL_UNSIGNED_INT
39197117f1b4Smrg          && depthScale == (GLfloat) 0xffffffff) {
39207117f1b4Smrg         const GLushort *src = (const GLushort *) source;
39217117f1b4Smrg         GLuint *dst = (GLuint *) dest;
39227117f1b4Smrg         GLuint i;
39237117f1b4Smrg         for (i = 0; i < n; i++) {
39247117f1b4Smrg            dst[i] = src[i] | (src[i] << 16);
39257117f1b4Smrg         }
39267117f1b4Smrg         return;
39277117f1b4Smrg      }
39287117f1b4Smrg      /* XXX may want to add additional cases here someday */
39297117f1b4Smrg   }
39307117f1b4Smrg
39317117f1b4Smrg   /* general case path follows */
39327117f1b4Smrg
39337117f1b4Smrg   if (dstType == GL_FLOAT) {
39347117f1b4Smrg      depthValues = (GLfloat *) dest;
39357117f1b4Smrg   }
39367117f1b4Smrg   else {
39377117f1b4Smrg      depthValues = depthTemp;
39387117f1b4Smrg   }
39397117f1b4Smrg
39407117f1b4Smrg   /* Convert incoming values to GLfloat.  Some conversions will require
39417117f1b4Smrg    * clamping, below.
39427117f1b4Smrg    */
39437117f1b4Smrg   switch (srcType) {
39447117f1b4Smrg      case GL_BYTE:
39457117f1b4Smrg         DEPTH_VALUES(GLbyte, BYTE_TO_FLOAT);
39467117f1b4Smrg         needClamp = GL_TRUE;
39477117f1b4Smrg         break;
39487117f1b4Smrg      case GL_UNSIGNED_BYTE:
39497117f1b4Smrg         DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT);
39507117f1b4Smrg         break;
39517117f1b4Smrg      case GL_SHORT:
39527117f1b4Smrg         DEPTH_VALUES(GLshort, SHORT_TO_FLOAT);
39537117f1b4Smrg         needClamp = GL_TRUE;
39547117f1b4Smrg         break;
39557117f1b4Smrg      case GL_UNSIGNED_SHORT:
39567117f1b4Smrg         DEPTH_VALUES(GLushort, USHORT_TO_FLOAT);
39577117f1b4Smrg         break;
39587117f1b4Smrg      case GL_INT:
39597117f1b4Smrg         DEPTH_VALUES(GLint, INT_TO_FLOAT);
39607117f1b4Smrg         needClamp = GL_TRUE;
39617117f1b4Smrg         break;
39627117f1b4Smrg      case GL_UNSIGNED_INT:
39637117f1b4Smrg         DEPTH_VALUES(GLuint, UINT_TO_FLOAT);
39647117f1b4Smrg         break;
39657117f1b4Smrg      case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
39667117f1b4Smrg         if (dstType == GL_UNSIGNED_INT &&
39677117f1b4Smrg             depthScale == (GLfloat) 0xffffff &&
39687117f1b4Smrg             ctx->Pixel.DepthScale == 1.0 &&
39697117f1b4Smrg             ctx->Pixel.DepthBias == 0.0) {
39707117f1b4Smrg            const GLuint *src = (const GLuint *) source;
39717117f1b4Smrg            GLuint *zValues = (GLuint *) dest;
39727117f1b4Smrg            GLuint i;
39737117f1b4Smrg            for (i = 0; i < n; i++) {
39747117f1b4Smrg                GLuint value = src[i];
39757117f1b4Smrg                if (srcPacking->SwapBytes) {
39767117f1b4Smrg                    SWAP4BYTE(value);
39777117f1b4Smrg                }
39787117f1b4Smrg                zValues[i] = value & 0xffffff00;
39797117f1b4Smrg            }
39807117f1b4Smrg            return;
39817117f1b4Smrg         }
39827117f1b4Smrg         else {
39837117f1b4Smrg            const GLuint *src = (const GLuint *) source;
39847117f1b4Smrg            const GLfloat scale = 1.0f / 0xffffff;
39857117f1b4Smrg            GLuint i;
39867117f1b4Smrg            for (i = 0; i < n; i++) {
39877117f1b4Smrg                GLuint value = src[i];
39887117f1b4Smrg                if (srcPacking->SwapBytes) {
39897117f1b4Smrg                    SWAP4BYTE(value);
39907117f1b4Smrg                }
39917117f1b4Smrg                depthValues[i] = (value >> 8) * scale;
39927117f1b4Smrg            }
39937117f1b4Smrg         }
39947117f1b4Smrg         break;
39957117f1b4Smrg      case GL_FLOAT:
39967117f1b4Smrg         DEPTH_VALUES(GLfloat, 1*);
39977117f1b4Smrg         needClamp = GL_TRUE;
39987117f1b4Smrg         break;
39997117f1b4Smrg      case GL_HALF_FLOAT_ARB:
40007117f1b4Smrg         {
40017117f1b4Smrg            GLuint i;
40027117f1b4Smrg            const GLhalfARB *src = (const GLhalfARB *) source;
40037117f1b4Smrg            for (i = 0; i < n; i++) {
40047117f1b4Smrg               GLhalfARB value = src[i];
40057117f1b4Smrg               if (srcPacking->SwapBytes) {
40067117f1b4Smrg                  SWAP2BYTE(value);
40077117f1b4Smrg               }
40087117f1b4Smrg               depthValues[i] = _mesa_half_to_float(value);
40097117f1b4Smrg            }
40107117f1b4Smrg            needClamp = GL_TRUE;
40117117f1b4Smrg         }
40127117f1b4Smrg         break;
40137117f1b4Smrg      default:
40147117f1b4Smrg         _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
40157117f1b4Smrg         return;
40167117f1b4Smrg   }
40177117f1b4Smrg
40187117f1b4Smrg   /* apply depth scale and bias */
40197117f1b4Smrg   {
40207117f1b4Smrg      const GLfloat scale = ctx->Pixel.DepthScale;
40217117f1b4Smrg      const GLfloat bias = ctx->Pixel.DepthBias;
40227117f1b4Smrg      if (scale != 1.0 || bias != 0.0) {
40237117f1b4Smrg         GLuint i;
40247117f1b4Smrg         for (i = 0; i < n; i++) {
40257117f1b4Smrg            depthValues[i] = depthValues[i] * scale + bias;
40267117f1b4Smrg         }
40277117f1b4Smrg         needClamp = GL_TRUE;
40287117f1b4Smrg      }
40297117f1b4Smrg   }
40307117f1b4Smrg
40317117f1b4Smrg   /* clamp to [0, 1] */
40327117f1b4Smrg   if (needClamp) {
40337117f1b4Smrg      GLuint i;
40347117f1b4Smrg      for (i = 0; i < n; i++) {
40357117f1b4Smrg         depthValues[i] = CLAMP(depthValues[i], 0.0, 1.0);
40367117f1b4Smrg      }
40377117f1b4Smrg   }
40387117f1b4Smrg
40397117f1b4Smrg   /*
40407117f1b4Smrg    * Convert values to dstType
40417117f1b4Smrg    */
40427117f1b4Smrg   if (dstType == GL_UNSIGNED_INT) {
40437117f1b4Smrg      GLuint *zValues = (GLuint *) dest;
40447117f1b4Smrg      GLuint i;
40457117f1b4Smrg      if (depthScale <= (GLfloat) 0xffffff) {
40467117f1b4Smrg         /* no overflow worries */
40477117f1b4Smrg         for (i = 0; i < n; i++) {
40487117f1b4Smrg            zValues[i] = (GLuint) (depthValues[i] * depthScale);
40497117f1b4Smrg         }
40507117f1b4Smrg      }
40517117f1b4Smrg      else {
40527117f1b4Smrg         /* need to use double precision to prevent overflow problems */
40537117f1b4Smrg         for (i = 0; i < n; i++) {
40547117f1b4Smrg            GLdouble z = depthValues[i] * depthScale;
40557117f1b4Smrg            if (z >= (GLdouble) 0xffffffff)
40567117f1b4Smrg               zValues[i] = 0xffffffff;
40577117f1b4Smrg            else
40587117f1b4Smrg               zValues[i] = (GLuint) z;
40597117f1b4Smrg         }
40607117f1b4Smrg      }
40617117f1b4Smrg   }
40627117f1b4Smrg   else if (dstType == GL_UNSIGNED_SHORT) {
40637117f1b4Smrg      GLushort *zValues = (GLushort *) dest;
40647117f1b4Smrg      GLuint i;
40657117f1b4Smrg      ASSERT(depthScale <= 65535.0);
40667117f1b4Smrg      for (i = 0; i < n; i++) {
40677117f1b4Smrg         zValues[i] = (GLushort) (depthValues[i] * depthScale);
40687117f1b4Smrg      }
40697117f1b4Smrg   }
40707117f1b4Smrg   else {
40717117f1b4Smrg      ASSERT(dstType == GL_FLOAT);
40727117f1b4Smrg      ASSERT(depthScale == 1.0F);
40737117f1b4Smrg   }
40747117f1b4Smrg}
40757117f1b4Smrg
40767117f1b4Smrg
40777117f1b4Smrg/*
40787117f1b4Smrg * Pack an array of depth values.  The values are floats in [0,1].
40797117f1b4Smrg */
40807117f1b4Smrgvoid
40817117f1b4Smrg_mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest,
40827117f1b4Smrg                       GLenum dstType, const GLfloat *depthSpan,
40837117f1b4Smrg                       const struct gl_pixelstore_attrib *dstPacking )
40847117f1b4Smrg{
40857117f1b4Smrg   GLfloat depthCopy[MAX_WIDTH];
40867117f1b4Smrg
40877117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
40887117f1b4Smrg
40897117f1b4Smrg   if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
40907117f1b4Smrg      _mesa_memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
40917117f1b4Smrg      _mesa_scale_and_bias_depth(ctx, n, depthCopy);
40927117f1b4Smrg      depthSpan = depthCopy;
40937117f1b4Smrg   }
40947117f1b4Smrg
40957117f1b4Smrg   switch (dstType) {
40967117f1b4Smrg   case GL_UNSIGNED_BYTE:
40977117f1b4Smrg      {
40987117f1b4Smrg         GLubyte *dst = (GLubyte *) dest;
40997117f1b4Smrg         GLuint i;
41007117f1b4Smrg         for (i = 0; i < n; i++) {
41017117f1b4Smrg            dst[i] = FLOAT_TO_UBYTE( depthSpan[i] );
41027117f1b4Smrg         }
41037117f1b4Smrg      }
41047117f1b4Smrg      break;
41057117f1b4Smrg   case GL_BYTE:
41067117f1b4Smrg      {
41077117f1b4Smrg         GLbyte *dst = (GLbyte *) dest;
41087117f1b4Smrg         GLuint i;
41097117f1b4Smrg         for (i = 0; i < n; i++) {
41107117f1b4Smrg            dst[i] = FLOAT_TO_BYTE( depthSpan[i] );
41117117f1b4Smrg         }
41127117f1b4Smrg      }
41137117f1b4Smrg      break;
41147117f1b4Smrg   case GL_UNSIGNED_SHORT:
41157117f1b4Smrg      {
41167117f1b4Smrg         GLushort *dst = (GLushort *) dest;
41177117f1b4Smrg         GLuint i;
41187117f1b4Smrg         for (i = 0; i < n; i++) {
41197117f1b4Smrg            CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]);
41207117f1b4Smrg         }
41217117f1b4Smrg         if (dstPacking->SwapBytes) {
41227117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
41237117f1b4Smrg         }
41247117f1b4Smrg      }
41257117f1b4Smrg      break;
41267117f1b4Smrg   case GL_SHORT:
41277117f1b4Smrg      {
41287117f1b4Smrg         GLshort *dst = (GLshort *) dest;
41297117f1b4Smrg         GLuint i;
41307117f1b4Smrg         for (i = 0; i < n; i++) {
41317117f1b4Smrg            dst[i] = FLOAT_TO_SHORT( depthSpan[i] );
41327117f1b4Smrg         }
41337117f1b4Smrg         if (dstPacking->SwapBytes) {
41347117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
41357117f1b4Smrg         }
41367117f1b4Smrg      }
41377117f1b4Smrg      break;
41387117f1b4Smrg   case GL_UNSIGNED_INT:
41397117f1b4Smrg      {
41407117f1b4Smrg         GLuint *dst = (GLuint *) dest;
41417117f1b4Smrg         GLuint i;
41427117f1b4Smrg         for (i = 0; i < n; i++) {
41437117f1b4Smrg            dst[i] = FLOAT_TO_UINT( depthSpan[i] );
41447117f1b4Smrg         }
41457117f1b4Smrg         if (dstPacking->SwapBytes) {
41467117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
41477117f1b4Smrg         }
41487117f1b4Smrg      }
41497117f1b4Smrg      break;
41507117f1b4Smrg   case GL_INT:
41517117f1b4Smrg      {
41527117f1b4Smrg         GLint *dst = (GLint *) dest;
41537117f1b4Smrg         GLuint i;
41547117f1b4Smrg         for (i = 0; i < n; i++) {
41557117f1b4Smrg            dst[i] = FLOAT_TO_INT( depthSpan[i] );
41567117f1b4Smrg         }
41577117f1b4Smrg         if (dstPacking->SwapBytes) {
41587117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
41597117f1b4Smrg         }
41607117f1b4Smrg      }
41617117f1b4Smrg      break;
41627117f1b4Smrg   case GL_FLOAT:
41637117f1b4Smrg      {
41647117f1b4Smrg         GLfloat *dst = (GLfloat *) dest;
41657117f1b4Smrg         GLuint i;
41667117f1b4Smrg         for (i = 0; i < n; i++) {
41677117f1b4Smrg            dst[i] = depthSpan[i];
41687117f1b4Smrg         }
41697117f1b4Smrg         if (dstPacking->SwapBytes) {
41707117f1b4Smrg            _mesa_swap4( (GLuint *) dst, n );
41717117f1b4Smrg         }
41727117f1b4Smrg      }
41737117f1b4Smrg      break;
41747117f1b4Smrg   case GL_HALF_FLOAT_ARB:
41757117f1b4Smrg      {
41767117f1b4Smrg         GLhalfARB *dst = (GLhalfARB *) dest;
41777117f1b4Smrg         GLuint i;
41787117f1b4Smrg         for (i = 0; i < n; i++) {
41797117f1b4Smrg            dst[i] = _mesa_float_to_half(depthSpan[i]);
41807117f1b4Smrg         }
41817117f1b4Smrg         if (dstPacking->SwapBytes) {
41827117f1b4Smrg            _mesa_swap2( (GLushort *) dst, n );
41837117f1b4Smrg         }
41847117f1b4Smrg      }
41857117f1b4Smrg      break;
41867117f1b4Smrg   default:
41877117f1b4Smrg      _mesa_problem(ctx, "bad type in _mesa_pack_depth_span");
41887117f1b4Smrg   }
41897117f1b4Smrg}
41907117f1b4Smrg
41917117f1b4Smrg
41927117f1b4Smrg
41937117f1b4Smrg/**
41947117f1b4Smrg * Pack depth and stencil values as GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8.
41957117f1b4Smrg */
41967117f1b4Smrgvoid
41977117f1b4Smrg_mesa_pack_depth_stencil_span(const GLcontext *ctx, GLuint n, GLuint *dest,
41987117f1b4Smrg                              const GLfloat *depthVals,
41997117f1b4Smrg                              const GLstencil *stencilVals,
42007117f1b4Smrg                              const struct gl_pixelstore_attrib *dstPacking)
42017117f1b4Smrg{
42027117f1b4Smrg   GLfloat depthCopy[MAX_WIDTH];
42037117f1b4Smrg   GLstencil stencilCopy[MAX_WIDTH];
42047117f1b4Smrg   GLuint i;
42057117f1b4Smrg
42067117f1b4Smrg   ASSERT(n <= MAX_WIDTH);
42077117f1b4Smrg
42087117f1b4Smrg   if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
42097117f1b4Smrg      _mesa_memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
42107117f1b4Smrg      _mesa_scale_and_bias_depth(ctx, n, depthCopy);
42117117f1b4Smrg      depthVals = depthCopy;
42127117f1b4Smrg   }
42137117f1b4Smrg
42147117f1b4Smrg   if (ctx->Pixel.IndexShift ||
42157117f1b4Smrg       ctx->Pixel.IndexOffset ||
42167117f1b4Smrg       ctx->Pixel.MapStencilFlag) {
42177117f1b4Smrg      _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
42187117f1b4Smrg      _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
42197117f1b4Smrg      stencilVals = stencilCopy;
42207117f1b4Smrg   }
42217117f1b4Smrg
42227117f1b4Smrg   for (i = 0; i < n; i++) {
42237117f1b4Smrg      GLuint z = (GLuint) (depthVals[i] * 0xffffff);
42247117f1b4Smrg      dest[i] = (z << 8) | (stencilVals[i] & 0xff);
42257117f1b4Smrg   }
42267117f1b4Smrg
42277117f1b4Smrg   if (dstPacking->SwapBytes) {
42287117f1b4Smrg      _mesa_swap4(dest, n);
42297117f1b4Smrg   }
42307117f1b4Smrg}
42317117f1b4Smrg
42327117f1b4Smrg
42337117f1b4Smrg
42347117f1b4Smrg
42357117f1b4Smrg/**
42367117f1b4Smrg * Unpack image data.  Apply byte swapping, byte flipping (bitmap).
42377117f1b4Smrg * Return all image data in a contiguous block.  This is used when we
42387117f1b4Smrg * compile glDrawPixels, glTexImage, etc into a display list.  We
42397117f1b4Smrg * need a copy of the data in a standard format.
42407117f1b4Smrg */
42417117f1b4Smrgvoid *
42427117f1b4Smrg_mesa_unpack_image( GLuint dimensions,
42437117f1b4Smrg                    GLsizei width, GLsizei height, GLsizei depth,
42447117f1b4Smrg                    GLenum format, GLenum type, const GLvoid *pixels,
42457117f1b4Smrg                    const struct gl_pixelstore_attrib *unpack )
42467117f1b4Smrg{
42477117f1b4Smrg   GLint bytesPerRow, compsPerRow;
42487117f1b4Smrg   GLboolean flipBytes, swap2, swap4;
42497117f1b4Smrg
42507117f1b4Smrg   if (!pixels)
42517117f1b4Smrg      return NULL;  /* not necessarily an error */
42527117f1b4Smrg
42537117f1b4Smrg   if (width <= 0 || height <= 0 || depth <= 0)
42547117f1b4Smrg      return NULL;  /* generate error later */
42557117f1b4Smrg
42567117f1b4Smrg   if (type == GL_BITMAP) {
42577117f1b4Smrg      bytesPerRow = (width + 7) >> 3;
42587117f1b4Smrg      flipBytes = unpack->LsbFirst;
42597117f1b4Smrg      swap2 = swap4 = GL_FALSE;
42607117f1b4Smrg      compsPerRow = 0;
42617117f1b4Smrg   }
42627117f1b4Smrg   else {
42637117f1b4Smrg      const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
42647117f1b4Smrg      GLint components = _mesa_components_in_format(format);
42657117f1b4Smrg      GLint bytesPerComp;
42667117f1b4Smrg
42677117f1b4Smrg      if (_mesa_type_is_packed(type))
42687117f1b4Smrg          components = 1;
42697117f1b4Smrg
42707117f1b4Smrg      if (bytesPerPixel <= 0 || components <= 0)
42717117f1b4Smrg         return NULL;   /* bad format or type.  generate error later */
42727117f1b4Smrg      bytesPerRow = bytesPerPixel * width;
42737117f1b4Smrg      bytesPerComp = bytesPerPixel / components;
42747117f1b4Smrg      flipBytes = GL_FALSE;
42757117f1b4Smrg      swap2 = (bytesPerComp == 2) && unpack->SwapBytes;
42767117f1b4Smrg      swap4 = (bytesPerComp == 4) && unpack->SwapBytes;
42777117f1b4Smrg      compsPerRow = components * width;
42787117f1b4Smrg      assert(compsPerRow >= width);
42797117f1b4Smrg   }
42807117f1b4Smrg
42817117f1b4Smrg   {
42827117f1b4Smrg      GLubyte *destBuffer
42837117f1b4Smrg         = (GLubyte *) _mesa_malloc(bytesPerRow * height * depth);
42847117f1b4Smrg      GLubyte *dst;
42857117f1b4Smrg      GLint img, row;
42867117f1b4Smrg      if (!destBuffer)
42877117f1b4Smrg         return NULL;   /* generate GL_OUT_OF_MEMORY later */
42887117f1b4Smrg
42897117f1b4Smrg      dst = destBuffer;
42907117f1b4Smrg      for (img = 0; img < depth; img++) {
42917117f1b4Smrg         for (row = 0; row < height; row++) {
42927117f1b4Smrg            const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels,
42937117f1b4Smrg                               width, height, format, type, img, row, 0);
42947117f1b4Smrg
42957117f1b4Smrg            if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) {
42967117f1b4Smrg               GLint i;
42977117f1b4Smrg               flipBytes = GL_FALSE;
42987117f1b4Smrg               if (unpack->LsbFirst) {
42997117f1b4Smrg                  GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7);
43007117f1b4Smrg                  GLubyte dstMask = 128;
43017117f1b4Smrg                  const GLubyte *s = src;
43027117f1b4Smrg                  GLubyte *d = dst;
43037117f1b4Smrg                  *d = 0;
43047117f1b4Smrg                  for (i = 0; i < width; i++) {
43057117f1b4Smrg                     if (*s & srcMask) {
43067117f1b4Smrg                        *d |= dstMask;
43077117f1b4Smrg                     }
43087117f1b4Smrg                     if (srcMask == 128) {
43097117f1b4Smrg                        srcMask = 1;
43107117f1b4Smrg                        s++;
43117117f1b4Smrg                     }
43127117f1b4Smrg                     else {
43137117f1b4Smrg                        srcMask = srcMask << 1;
43147117f1b4Smrg                     }
43157117f1b4Smrg                     if (dstMask == 1) {
43167117f1b4Smrg                        dstMask = 128;
43177117f1b4Smrg                        d++;
43187117f1b4Smrg                        *d = 0;
43197117f1b4Smrg                     }
43207117f1b4Smrg                     else {
43217117f1b4Smrg                        dstMask = dstMask >> 1;
43227117f1b4Smrg                     }
43237117f1b4Smrg                  }
43247117f1b4Smrg               }
43257117f1b4Smrg               else {
43267117f1b4Smrg                  GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7);
43277117f1b4Smrg                  GLubyte dstMask = 128;
43287117f1b4Smrg                  const GLubyte *s = src;
43297117f1b4Smrg                  GLubyte *d = dst;
43307117f1b4Smrg                  *d = 0;
43317117f1b4Smrg                  for (i = 0; i < width; i++) {
43327117f1b4Smrg                     if (*s & srcMask) {
43337117f1b4Smrg                        *d |= dstMask;
43347117f1b4Smrg                     }
43357117f1b4Smrg                     if (srcMask == 1) {
43367117f1b4Smrg                        srcMask = 128;
43377117f1b4Smrg                        s++;
43387117f1b4Smrg                     }
43397117f1b4Smrg                     else {
43407117f1b4Smrg                        srcMask = srcMask >> 1;
43417117f1b4Smrg                     }
43427117f1b4Smrg                     if (dstMask == 1) {
43437117f1b4Smrg                        dstMask = 128;
43447117f1b4Smrg                        d++;
43457117f1b4Smrg                        *d = 0;
43467117f1b4Smrg                     }
43477117f1b4Smrg                     else {
43487117f1b4Smrg                        dstMask = dstMask >> 1;
43497117f1b4Smrg                     }
43507117f1b4Smrg                  }
43517117f1b4Smrg               }
43527117f1b4Smrg            }
43537117f1b4Smrg            else {
43547117f1b4Smrg               _mesa_memcpy(dst, src, bytesPerRow);
43557117f1b4Smrg            }
43567117f1b4Smrg
43577117f1b4Smrg            /* byte flipping/swapping */
43587117f1b4Smrg            if (flipBytes) {
43597117f1b4Smrg               flip_bytes((GLubyte *) dst, bytesPerRow);
43607117f1b4Smrg            }
43617117f1b4Smrg            else if (swap2) {
43627117f1b4Smrg               _mesa_swap2((GLushort*) dst, compsPerRow);
43637117f1b4Smrg            }
43647117f1b4Smrg            else if (swap4) {
43657117f1b4Smrg               _mesa_swap4((GLuint*) dst, compsPerRow);
43667117f1b4Smrg            }
43677117f1b4Smrg            dst += bytesPerRow;
43687117f1b4Smrg         }
43697117f1b4Smrg      }
43707117f1b4Smrg      return destBuffer;
43717117f1b4Smrg   }
43727117f1b4Smrg}
43737117f1b4Smrg
43747117f1b4Smrg#endif /* _HAVE_FULL_GL */
43757117f1b4Smrg
43767117f1b4Smrg
43777117f1b4Smrg
43787117f1b4Smrg/**
43797117f1b4Smrg * Convert an array of RGBA colors from one datatype to another.
43807117f1b4Smrg * NOTE: src may equal dst.  In that case, we use a temporary buffer.
43817117f1b4Smrg */
43827117f1b4Smrgvoid
43837117f1b4Smrg_mesa_convert_colors(GLenum srcType, const GLvoid *src,
43847117f1b4Smrg                     GLenum dstType, GLvoid *dst,
43857117f1b4Smrg                     GLuint count, const GLubyte mask[])
43867117f1b4Smrg{
43877117f1b4Smrg   GLuint tempBuffer[MAX_WIDTH][4];
43887117f1b4Smrg   const GLboolean useTemp = (src == dst);
43897117f1b4Smrg
43907117f1b4Smrg   ASSERT(srcType != dstType);
43917117f1b4Smrg
43927117f1b4Smrg   switch (srcType) {
43937117f1b4Smrg   case GL_UNSIGNED_BYTE:
43947117f1b4Smrg      if (dstType == GL_UNSIGNED_SHORT) {
43957117f1b4Smrg         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
43967117f1b4Smrg         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
43977117f1b4Smrg         GLuint i;
43987117f1b4Smrg         for (i = 0; i < count; i++) {
43997117f1b4Smrg            if (!mask || mask[i]) {
44007117f1b4Smrg               dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]);
44017117f1b4Smrg               dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]);
44027117f1b4Smrg               dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]);
44037117f1b4Smrg               dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]);
44047117f1b4Smrg            }
44057117f1b4Smrg         }
44067117f1b4Smrg         if (useTemp)
44077117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
44087117f1b4Smrg      }
44097117f1b4Smrg      else {
44107117f1b4Smrg         const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src;
44117117f1b4Smrg         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
44127117f1b4Smrg         GLuint i;
44137117f1b4Smrg         ASSERT(dstType == GL_FLOAT);
44147117f1b4Smrg         for (i = 0; i < count; i++) {
44157117f1b4Smrg            if (!mask || mask[i]) {
44167117f1b4Smrg               dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]);
44177117f1b4Smrg               dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]);
44187117f1b4Smrg               dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]);
44197117f1b4Smrg               dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]);
44207117f1b4Smrg            }
44217117f1b4Smrg         }
44227117f1b4Smrg         if (useTemp)
44237117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
44247117f1b4Smrg      }
44257117f1b4Smrg      break;
44267117f1b4Smrg   case GL_UNSIGNED_SHORT:
44277117f1b4Smrg      if (dstType == GL_UNSIGNED_BYTE) {
44287117f1b4Smrg         const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
44297117f1b4Smrg         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);
44307117f1b4Smrg         GLuint i;
44317117f1b4Smrg         for (i = 0; i < count; i++) {
44327117f1b4Smrg            if (!mask || mask[i]) {
44337117f1b4Smrg               dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]);
44347117f1b4Smrg               dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]);
44357117f1b4Smrg               dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]);
44367117f1b4Smrg               dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]);
44377117f1b4Smrg            }
44387117f1b4Smrg         }
44397117f1b4Smrg         if (useTemp)
44407117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
44417117f1b4Smrg      }
44427117f1b4Smrg      else {
44437117f1b4Smrg         const GLushort (*src2)[4] = (const GLushort (*)[4]) src;
44447117f1b4Smrg         GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst);
44457117f1b4Smrg         GLuint i;
44467117f1b4Smrg         ASSERT(dstType == GL_FLOAT);
44477117f1b4Smrg         for (i = 0; i < count; i++) {
44487117f1b4Smrg            if (!mask || mask[i]) {
44497117f1b4Smrg               dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]);
44507117f1b4Smrg               dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]);
44517117f1b4Smrg               dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]);
44527117f1b4Smrg               dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]);
44537117f1b4Smrg            }
44547117f1b4Smrg         }
44557117f1b4Smrg         if (useTemp)
44567117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat));
44577117f1b4Smrg      }
44587117f1b4Smrg      break;
44597117f1b4Smrg   case GL_FLOAT:
44607117f1b4Smrg      if (dstType == GL_UNSIGNED_BYTE) {
44617117f1b4Smrg         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
44627117f1b4Smrg         GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst);
44637117f1b4Smrg         GLuint i;
44647117f1b4Smrg         for (i = 0; i < count; i++) {
44657117f1b4Smrg            if (!mask || mask[i]) {
44667117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][RCOMP], src4[i][RCOMP]);
44677117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][GCOMP], src4[i][GCOMP]);
44687117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][BCOMP], src4[i][BCOMP]);
44697117f1b4Smrg               UNCLAMPED_FLOAT_TO_UBYTE(dst1[i][ACOMP], src4[i][ACOMP]);
44707117f1b4Smrg            }
44717117f1b4Smrg         }
44727117f1b4Smrg         if (useTemp)
44737117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte));
44747117f1b4Smrg      }
44757117f1b4Smrg      else {
44767117f1b4Smrg         const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src;
44777117f1b4Smrg         GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst);
44787117f1b4Smrg         GLuint i;
44797117f1b4Smrg         ASSERT(dstType == GL_UNSIGNED_SHORT);
44807117f1b4Smrg         for (i = 0; i < count; i++) {
44817117f1b4Smrg            if (!mask || mask[i]) {
44827117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]);
44837117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]);
44847117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]);
44857117f1b4Smrg               UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]);
44867117f1b4Smrg            }
44877117f1b4Smrg         }
44887117f1b4Smrg         if (useTemp)
44897117f1b4Smrg            _mesa_memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort));
44907117f1b4Smrg      }
44917117f1b4Smrg      break;
44927117f1b4Smrg   default:
44937117f1b4Smrg      _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors");
44947117f1b4Smrg   }
44957117f1b4Smrg}
44967117f1b4Smrg
44977117f1b4Smrg
44987117f1b4Smrg
44997117f1b4Smrg
45007117f1b4Smrg/**
45017117f1b4Smrg * Perform basic clipping for glDrawPixels.  The image's position and size
45027117f1b4Smrg * and the unpack SkipPixels and SkipRows are adjusted so that the image
45037117f1b4Smrg * region is entirely within the window and scissor bounds.
45047117f1b4Smrg * NOTE: this will only work when glPixelZoom is (1, 1) or (1, -1).
45057117f1b4Smrg * If Pixel.ZoomY is -1, *destY will be changed to be the first row which
45067117f1b4Smrg * we'll actually write.  Beforehand, *destY-1 is the first drawing row.
45077117f1b4Smrg *
45087117f1b4Smrg * \return  GL_TRUE if image is ready for drawing or
45097117f1b4Smrg *          GL_FALSE if image was completely clipped away (draw nothing)
45107117f1b4Smrg */
45117117f1b4SmrgGLboolean
45127117f1b4Smrg_mesa_clip_drawpixels(const GLcontext *ctx,
45137117f1b4Smrg                      GLint *destX, GLint *destY,
45147117f1b4Smrg                      GLsizei *width, GLsizei *height,
45157117f1b4Smrg                      struct gl_pixelstore_attrib *unpack)
45167117f1b4Smrg{
45177117f1b4Smrg   const GLframebuffer *buffer = ctx->DrawBuffer;
45187117f1b4Smrg
45197117f1b4Smrg   if (unpack->RowLength == 0) {
45207117f1b4Smrg      unpack->RowLength = *width;
45217117f1b4Smrg   }
45227117f1b4Smrg
45237117f1b4Smrg   ASSERT(ctx->Pixel.ZoomX == 1.0F);
45247117f1b4Smrg   ASSERT(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F);
45257117f1b4Smrg
45267117f1b4Smrg   /* left clipping */
45277117f1b4Smrg   if (*destX < buffer->_Xmin) {
45287117f1b4Smrg      unpack->SkipPixels += (buffer->_Xmin - *destX);
45297117f1b4Smrg      *width -= (buffer->_Xmin - *destX);
45307117f1b4Smrg      *destX = buffer->_Xmin;
45317117f1b4Smrg   }
45327117f1b4Smrg   /* right clipping */
45337117f1b4Smrg   if (*destX + *width > buffer->_Xmax)
45347117f1b4Smrg      *width -= (*destX + *width - buffer->_Xmax);
45357117f1b4Smrg
45367117f1b4Smrg   if (*width <= 0)
45377117f1b4Smrg      return GL_FALSE;
45387117f1b4Smrg
45397117f1b4Smrg   if (ctx->Pixel.ZoomY == 1.0F) {
45407117f1b4Smrg      /* bottom clipping */
45417117f1b4Smrg      if (*destY < buffer->_Ymin) {
45427117f1b4Smrg         unpack->SkipRows += (buffer->_Ymin - *destY);
45437117f1b4Smrg         *height -= (buffer->_Ymin - *destY);
45447117f1b4Smrg         *destY = buffer->_Ymin;
45457117f1b4Smrg      }
45467117f1b4Smrg      /* top clipping */
45477117f1b4Smrg      if (*destY + *height > buffer->_Ymax)
45487117f1b4Smrg         *height -= (*destY + *height - buffer->_Ymax);
45497117f1b4Smrg   }
45507117f1b4Smrg   else { /* upside down */
45517117f1b4Smrg      /* top clipping */
45527117f1b4Smrg      if (*destY > buffer->_Ymax) {
45537117f1b4Smrg         unpack->SkipRows += (*destY - buffer->_Ymax);
45547117f1b4Smrg         *height -= (*destY - buffer->_Ymax);
45557117f1b4Smrg         *destY = buffer->_Ymax;
45567117f1b4Smrg      }
45577117f1b4Smrg      /* bottom clipping */
45587117f1b4Smrg      if (*destY - *height < buffer->_Ymin)
45597117f1b4Smrg         *height -= (buffer->_Ymin - (*destY - *height));
45607117f1b4Smrg      /* adjust destY so it's the first row to write to */
45617117f1b4Smrg      (*destY)--;
45627117f1b4Smrg   }
45637117f1b4Smrg
45647117f1b4Smrg   if (*height <= 0)
45657117f1b4Smrg      return GL_TRUE;
45667117f1b4Smrg
45677117f1b4Smrg   return GL_TRUE;
45687117f1b4Smrg}
45697117f1b4Smrg
45707117f1b4Smrg
45717117f1b4Smrg/**
45727117f1b4Smrg * Perform clipping for glReadPixels.  The image's window position
45737117f1b4Smrg * and size, and the pack skipPixels, skipRows and rowLength are adjusted
45747117f1b4Smrg * so that the image region is entirely within the window bounds.
45757117f1b4Smrg * Note: this is different from _mesa_clip_drawpixels() in that the
45767117f1b4Smrg * scissor box is ignored, and we use the bounds of the current readbuffer
45777117f1b4Smrg * surface.
45787117f1b4Smrg *
45797117f1b4Smrg * \return  GL_TRUE if image is ready for drawing or
45807117f1b4Smrg *          GL_FALSE if image was completely clipped away (draw nothing)
45817117f1b4Smrg */
45827117f1b4SmrgGLboolean
45837117f1b4Smrg_mesa_clip_readpixels(const GLcontext *ctx,
45847117f1b4Smrg                      GLint *srcX, GLint *srcY,
45857117f1b4Smrg                      GLsizei *width, GLsizei *height,
45867117f1b4Smrg                      struct gl_pixelstore_attrib *pack)
45877117f1b4Smrg{
45887117f1b4Smrg   const GLframebuffer *buffer = ctx->ReadBuffer;
45897117f1b4Smrg
45907117f1b4Smrg   if (pack->RowLength == 0) {
45917117f1b4Smrg      pack->RowLength = *width;
45927117f1b4Smrg   }
45937117f1b4Smrg
45947117f1b4Smrg   /* left clipping */
45957117f1b4Smrg   if (*srcX < 0) {
45967117f1b4Smrg      pack->SkipPixels += (0 - *srcX);
45977117f1b4Smrg      *width -= (0 - *srcX);
45987117f1b4Smrg      *srcX = 0;
45997117f1b4Smrg   }
46007117f1b4Smrg   /* right clipping */
46017117f1b4Smrg   if (*srcX + *width > (GLsizei) buffer->Width)
46027117f1b4Smrg      *width -= (*srcX + *width - buffer->Width);
46037117f1b4Smrg
46047117f1b4Smrg   if (*width <= 0)
46057117f1b4Smrg      return GL_FALSE;
46067117f1b4Smrg
46077117f1b4Smrg   /* bottom clipping */
46087117f1b4Smrg   if (*srcY < 0) {
46097117f1b4Smrg      pack->SkipRows += (0 - *srcY);
46107117f1b4Smrg      *height -= (0 - *srcY);
46117117f1b4Smrg      *srcY = 0;
46127117f1b4Smrg   }
46137117f1b4Smrg   /* top clipping */
46147117f1b4Smrg   if (*srcY + *height > (GLsizei) buffer->Height)
46157117f1b4Smrg      *height -= (*srcY + *height - buffer->Height);
46167117f1b4Smrg
46177117f1b4Smrg   if (*height <= 0)
46187117f1b4Smrg      return GL_TRUE;
46197117f1b4Smrg
46207117f1b4Smrg   return GL_TRUE;
46217117f1b4Smrg}
46227117f1b4Smrg
46237117f1b4Smrg
46247117f1b4Smrg/**
46257117f1b4Smrg * Clip the rectangle defined by (x, y, width, height) against the bounds
46267117f1b4Smrg * specified by [xmin, xmax) and [ymin, ymax).
46277117f1b4Smrg * \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise.
46287117f1b4Smrg */
46297117f1b4SmrgGLboolean
46307117f1b4Smrg_mesa_clip_to_region(GLint xmin, GLint ymin,
46317117f1b4Smrg                     GLint xmax, GLint ymax,
46327117f1b4Smrg                     GLint *x, GLint *y,
46337117f1b4Smrg                     GLsizei *width, GLsizei *height )
46347117f1b4Smrg{
46357117f1b4Smrg   /* left clipping */
46367117f1b4Smrg   if (*x < xmin) {
46377117f1b4Smrg      *width -= (xmin - *x);
46387117f1b4Smrg      *x = xmin;
46397117f1b4Smrg   }
46407117f1b4Smrg
46417117f1b4Smrg   /* right clipping */
46427117f1b4Smrg   if (*x + *width > xmax)
46437117f1b4Smrg      *width -= (*x + *width - xmax - 1);
46447117f1b4Smrg
46457117f1b4Smrg   if (*width <= 0)
46467117f1b4Smrg      return GL_FALSE;
46477117f1b4Smrg
46487117f1b4Smrg   /* bottom (or top) clipping */
46497117f1b4Smrg   if (*y < ymin) {
46507117f1b4Smrg      *height -= (ymin - *y);
46517117f1b4Smrg      *y = ymin;
46527117f1b4Smrg   }
46537117f1b4Smrg
46547117f1b4Smrg   /* top (or bottom) clipping */
46557117f1b4Smrg   if (*y + *height > ymax)
46567117f1b4Smrg      *height -= (*y + *height - ymax - 1);
46577117f1b4Smrg
46587117f1b4Smrg   if (*height <= 0)
46597117f1b4Smrg      return GL_FALSE;
46607117f1b4Smrg
46617117f1b4Smrg   return GL_TRUE;
46627117f1b4Smrg}
4663