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