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