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