pack.c revision b8e80941
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THEA AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21848b8605Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22848b8605Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file pack.c 28848b8605Smrg * Image and pixel span packing and unpacking. 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg 32848b8605Smrg/* 33848b8605Smrg * XXX: MSVC takes forever to compile this module for x86_64 unless we disable 34848b8605Smrg * this global optimization. 35848b8605Smrg * 36848b8605Smrg * See also: 37848b8605Smrg * - http://msdn.microsoft.com/en-us/library/1yk3ydd7.aspx 38848b8605Smrg * - http://msdn.microsoft.com/en-us/library/chh3fb0k.aspx 39848b8605Smrg */ 40848b8605Smrg#if defined(_MSC_VER) && defined(_M_X64) 41848b8605Smrg# pragma optimize( "g", off ) 42848b8605Smrg#endif 43848b8605Smrg 44848b8605Smrg 45b8e80941Smrg#include "errors.h" 46848b8605Smrg#include "glheader.h" 47848b8605Smrg#include "enums.h" 48848b8605Smrg#include "image.h" 49848b8605Smrg#include "imports.h" 50848b8605Smrg#include "macros.h" 51848b8605Smrg#include "mtypes.h" 52848b8605Smrg#include "pack.h" 53848b8605Smrg#include "pixeltransfer.h" 54848b8605Smrg#include "imports.h" 55848b8605Smrg#include "glformats.h" 56b8e80941Smrg#include "format_utils.h" 57b8e80941Smrg#include "format_pack.h" 58848b8605Smrg 59848b8605Smrg 60848b8605Smrg/** 61848b8605Smrg * Flip the 8 bits in each byte of the given array. 62848b8605Smrg * 63848b8605Smrg * \param p array. 64848b8605Smrg * \param n number of bytes. 65848b8605Smrg * 66848b8605Smrg * \todo try this trick to flip bytes someday: 67848b8605Smrg * \code 68848b8605Smrg * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); 69848b8605Smrg * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); 70848b8605Smrg * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); 71848b8605Smrg * \endcode 72848b8605Smrg */ 73848b8605Smrgstatic void 74848b8605Smrgflip_bytes( GLubyte *p, GLuint n ) 75848b8605Smrg{ 76848b8605Smrg GLuint i, a, b; 77848b8605Smrg for (i = 0; i < n; i++) { 78848b8605Smrg b = (GLuint) p[i]; /* words are often faster than bytes */ 79848b8605Smrg a = ((b & 0x01) << 7) | 80848b8605Smrg ((b & 0x02) << 5) | 81848b8605Smrg ((b & 0x04) << 3) | 82848b8605Smrg ((b & 0x08) << 1) | 83848b8605Smrg ((b & 0x10) >> 1) | 84848b8605Smrg ((b & 0x20) >> 3) | 85848b8605Smrg ((b & 0x40) >> 5) | 86848b8605Smrg ((b & 0x80) >> 7); 87848b8605Smrg p[i] = (GLubyte) a; 88848b8605Smrg } 89848b8605Smrg} 90848b8605Smrg 91848b8605Smrg 92848b8605Smrg 93848b8605Smrg/* 94848b8605Smrg * Unpack a 32x32 pixel polygon stipple from user memory using the 95848b8605Smrg * current pixel unpack settings. 96848b8605Smrg */ 97848b8605Smrgvoid 98848b8605Smrg_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32], 99848b8605Smrg const struct gl_pixelstore_attrib *unpacking ) 100848b8605Smrg{ 101b8e80941Smrg GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, 102b8e80941Smrg GL_BITMAP, pattern, unpacking); 103848b8605Smrg if (ptrn) { 104848b8605Smrg /* Convert pattern from GLubytes to GLuints and handle big/little 105848b8605Smrg * endian differences 106848b8605Smrg */ 107848b8605Smrg GLubyte *p = ptrn; 108848b8605Smrg GLint i; 109848b8605Smrg for (i = 0; i < 32; i++) { 110848b8605Smrg dest[i] = (p[0] << 24) 111848b8605Smrg | (p[1] << 16) 112848b8605Smrg | (p[2] << 8) 113848b8605Smrg | (p[3] ); 114848b8605Smrg p += 4; 115848b8605Smrg } 116848b8605Smrg free(ptrn); 117848b8605Smrg } 118848b8605Smrg} 119848b8605Smrg 120848b8605Smrg 121848b8605Smrg/* 122848b8605Smrg * Pack polygon stipple into user memory given current pixel packing 123848b8605Smrg * settings. 124848b8605Smrg */ 125848b8605Smrgvoid 126848b8605Smrg_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest, 127848b8605Smrg const struct gl_pixelstore_attrib *packing ) 128848b8605Smrg{ 129848b8605Smrg /* Convert pattern from GLuints to GLubytes to handle big/little 130848b8605Smrg * endian differences. 131848b8605Smrg */ 132848b8605Smrg GLubyte ptrn[32*4]; 133848b8605Smrg GLint i; 134848b8605Smrg for (i = 0; i < 32; i++) { 135848b8605Smrg ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff); 136848b8605Smrg ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff); 137848b8605Smrg ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff); 138848b8605Smrg ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff); 139848b8605Smrg } 140848b8605Smrg 141848b8605Smrg _mesa_pack_bitmap(32, 32, ptrn, dest, packing); 142848b8605Smrg} 143848b8605Smrg 144848b8605Smrg 145848b8605Smrg/* 146848b8605Smrg * Pack bitmap data. 147848b8605Smrg */ 148848b8605Smrgvoid 149848b8605Smrg_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, 150848b8605Smrg GLubyte *dest, const struct gl_pixelstore_attrib *packing ) 151848b8605Smrg{ 152848b8605Smrg GLint row, width_in_bytes; 153848b8605Smrg const GLubyte *src; 154848b8605Smrg 155848b8605Smrg if (!source) 156848b8605Smrg return; 157848b8605Smrg 158b8e80941Smrg width_in_bytes = DIV_ROUND_UP( width, 8 ); 159848b8605Smrg src = source; 160848b8605Smrg for (row = 0; row < height; row++) { 161848b8605Smrg GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest, 162848b8605Smrg width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); 163848b8605Smrg if (!dst) 164848b8605Smrg return; 165848b8605Smrg 166848b8605Smrg if ((packing->SkipPixels & 7) == 0) { 167848b8605Smrg memcpy( dst, src, width_in_bytes ); 168848b8605Smrg if (packing->LsbFirst) { 169848b8605Smrg flip_bytes( dst, width_in_bytes ); 170848b8605Smrg } 171848b8605Smrg } 172848b8605Smrg else { 173848b8605Smrg /* handling SkipPixels is a bit tricky (no pun intended!) */ 174848b8605Smrg GLint i; 175848b8605Smrg if (packing->LsbFirst) { 176848b8605Smrg GLubyte srcMask = 128; 177848b8605Smrg GLubyte dstMask = 1 << (packing->SkipPixels & 0x7); 178848b8605Smrg const GLubyte *s = src; 179848b8605Smrg GLubyte *d = dst; 180848b8605Smrg *d = 0; 181848b8605Smrg for (i = 0; i < width; i++) { 182848b8605Smrg if (*s & srcMask) { 183848b8605Smrg *d |= dstMask; 184848b8605Smrg } 185848b8605Smrg if (srcMask == 1) { 186848b8605Smrg srcMask = 128; 187848b8605Smrg s++; 188848b8605Smrg } 189848b8605Smrg else { 190848b8605Smrg srcMask = srcMask >> 1; 191848b8605Smrg } 192848b8605Smrg if (dstMask == 128) { 193848b8605Smrg dstMask = 1; 194848b8605Smrg d++; 195848b8605Smrg *d = 0; 196848b8605Smrg } 197848b8605Smrg else { 198848b8605Smrg dstMask = dstMask << 1; 199848b8605Smrg } 200848b8605Smrg } 201848b8605Smrg } 202848b8605Smrg else { 203848b8605Smrg GLubyte srcMask = 128; 204848b8605Smrg GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7); 205848b8605Smrg const GLubyte *s = src; 206848b8605Smrg GLubyte *d = dst; 207848b8605Smrg *d = 0; 208848b8605Smrg for (i = 0; i < width; i++) { 209848b8605Smrg if (*s & srcMask) { 210848b8605Smrg *d |= dstMask; 211848b8605Smrg } 212848b8605Smrg if (srcMask == 1) { 213848b8605Smrg srcMask = 128; 214848b8605Smrg s++; 215848b8605Smrg } 216848b8605Smrg else { 217848b8605Smrg srcMask = srcMask >> 1; 218848b8605Smrg } 219848b8605Smrg if (dstMask == 1) { 220848b8605Smrg dstMask = 128; 221848b8605Smrg d++; 222848b8605Smrg *d = 0; 223848b8605Smrg } 224848b8605Smrg else { 225848b8605Smrg dstMask = dstMask >> 1; 226848b8605Smrg } 227848b8605Smrg } 228848b8605Smrg } 229848b8605Smrg } 230848b8605Smrg src += width_in_bytes; 231848b8605Smrg } 232848b8605Smrg} 233848b8605Smrg 234848b8605Smrg 235b8e80941Smrg#define SWAP2BYTE(VALUE) \ 236b8e80941Smrg { \ 237b8e80941Smrg GLubyte *bytes = (GLubyte *) &(VALUE); \ 238b8e80941Smrg GLubyte tmp = bytes[0]; \ 239b8e80941Smrg bytes[0] = bytes[1]; \ 240b8e80941Smrg bytes[1] = tmp; \ 241848b8605Smrg } 242848b8605Smrg 243b8e80941Smrg#define SWAP4BYTE(VALUE) \ 244b8e80941Smrg { \ 245b8e80941Smrg GLubyte *bytes = (GLubyte *) &(VALUE); \ 246b8e80941Smrg GLubyte tmp = bytes[0]; \ 247b8e80941Smrg bytes[0] = bytes[3]; \ 248b8e80941Smrg bytes[3] = tmp; \ 249b8e80941Smrg tmp = bytes[1]; \ 250b8e80941Smrg bytes[1] = bytes[2]; \ 251b8e80941Smrg bytes[2] = tmp; \ 252848b8605Smrg } 253848b8605Smrg 254848b8605Smrg 255848b8605Smrgstatic void 256b8e80941Smrgextract_uint_indexes(GLuint n, GLuint indexes[], 257b8e80941Smrg GLenum srcFormat, GLenum srcType, const GLvoid *src, 258b8e80941Smrg const struct gl_pixelstore_attrib *unpack ) 259848b8605Smrg{ 260b8e80941Smrg assert(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX); 261848b8605Smrg 262b8e80941Smrg assert(srcType == GL_BITMAP || 263b8e80941Smrg srcType == GL_UNSIGNED_BYTE || 264b8e80941Smrg srcType == GL_BYTE || 265b8e80941Smrg srcType == GL_UNSIGNED_SHORT || 266b8e80941Smrg srcType == GL_SHORT || 267b8e80941Smrg srcType == GL_UNSIGNED_INT || 268b8e80941Smrg srcType == GL_INT || 269b8e80941Smrg srcType == GL_UNSIGNED_INT_24_8_EXT || 270b8e80941Smrg srcType == GL_HALF_FLOAT_ARB || 271b8e80941Smrg srcType == GL_HALF_FLOAT_OES || 272b8e80941Smrg srcType == GL_FLOAT || 273b8e80941Smrg srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 274848b8605Smrg 275b8e80941Smrg switch (srcType) { 276b8e80941Smrg case GL_BITMAP: 277b8e80941Smrg { 278b8e80941Smrg GLubyte *ubsrc = (GLubyte *) src; 279b8e80941Smrg if (unpack->LsbFirst) { 280b8e80941Smrg GLubyte mask = 1 << (unpack->SkipPixels & 0x7); 281b8e80941Smrg GLuint i; 282b8e80941Smrg for (i = 0; i < n; i++) { 283b8e80941Smrg indexes[i] = (*ubsrc & mask) ? 1 : 0; 284b8e80941Smrg if (mask == 128) { 285b8e80941Smrg mask = 1; 286b8e80941Smrg ubsrc++; 287b8e80941Smrg } 288b8e80941Smrg else { 289b8e80941Smrg mask = mask << 1; 290b8e80941Smrg } 291b8e80941Smrg } 292b8e80941Smrg } 293b8e80941Smrg else { 294b8e80941Smrg GLubyte mask = 128 >> (unpack->SkipPixels & 0x7); 295b8e80941Smrg GLuint i; 296b8e80941Smrg for (i = 0; i < n; i++) { 297b8e80941Smrg indexes[i] = (*ubsrc & mask) ? 1 : 0; 298b8e80941Smrg if (mask == 1) { 299b8e80941Smrg mask = 128; 300b8e80941Smrg ubsrc++; 301b8e80941Smrg } 302b8e80941Smrg else { 303b8e80941Smrg mask = mask >> 1; 304b8e80941Smrg } 305b8e80941Smrg } 306b8e80941Smrg } 307848b8605Smrg } 308b8e80941Smrg break; 309b8e80941Smrg case GL_UNSIGNED_BYTE: 310b8e80941Smrg { 311b8e80941Smrg GLuint i; 312b8e80941Smrg const GLubyte *s = (const GLubyte *) src; 313b8e80941Smrg for (i = 0; i < n; i++) 314b8e80941Smrg indexes[i] = s[i]; 315848b8605Smrg } 316b8e80941Smrg break; 317b8e80941Smrg case GL_BYTE: 318b8e80941Smrg { 319b8e80941Smrg GLuint i; 320b8e80941Smrg const GLbyte *s = (const GLbyte *) src; 321b8e80941Smrg for (i = 0; i < n; i++) 322b8e80941Smrg indexes[i] = s[i]; 323848b8605Smrg } 324b8e80941Smrg break; 325b8e80941Smrg case GL_UNSIGNED_SHORT: 326b8e80941Smrg { 327b8e80941Smrg GLuint i; 328b8e80941Smrg const GLushort *s = (const GLushort *) src; 329b8e80941Smrg if (unpack->SwapBytes) { 330b8e80941Smrg for (i = 0; i < n; i++) { 331b8e80941Smrg GLushort value = s[i]; 332b8e80941Smrg SWAP2BYTE(value); 333b8e80941Smrg indexes[i] = value; 334b8e80941Smrg } 335b8e80941Smrg } 336b8e80941Smrg else { 337b8e80941Smrg for (i = 0; i < n; i++) 338b8e80941Smrg indexes[i] = s[i]; 339b8e80941Smrg } 340848b8605Smrg } 341b8e80941Smrg break; 342b8e80941Smrg case GL_SHORT: 343b8e80941Smrg { 344b8e80941Smrg GLuint i; 345b8e80941Smrg const GLshort *s = (const GLshort *) src; 346b8e80941Smrg if (unpack->SwapBytes) { 347b8e80941Smrg for (i = 0; i < n; i++) { 348b8e80941Smrg GLshort value = s[i]; 349b8e80941Smrg SWAP2BYTE(value); 350b8e80941Smrg indexes[i] = value; 351b8e80941Smrg } 352b8e80941Smrg } 353b8e80941Smrg else { 354b8e80941Smrg for (i = 0; i < n; i++) 355b8e80941Smrg indexes[i] = s[i]; 356b8e80941Smrg } 357848b8605Smrg } 358b8e80941Smrg break; 359b8e80941Smrg case GL_UNSIGNED_INT: 360b8e80941Smrg { 361b8e80941Smrg GLuint i; 362b8e80941Smrg const GLuint *s = (const GLuint *) src; 363b8e80941Smrg if (unpack->SwapBytes) { 364848b8605Smrg for (i = 0; i < n; i++) { 365b8e80941Smrg GLuint value = s[i]; 366b8e80941Smrg SWAP4BYTE(value); 367b8e80941Smrg indexes[i] = value; 368848b8605Smrg } 369848b8605Smrg } 370b8e80941Smrg else { 371b8e80941Smrg for (i = 0; i < n; i++) 372b8e80941Smrg indexes[i] = s[i]; 373848b8605Smrg } 374848b8605Smrg } 375b8e80941Smrg break; 376b8e80941Smrg case GL_INT: 377b8e80941Smrg { 378b8e80941Smrg GLuint i; 379b8e80941Smrg const GLint *s = (const GLint *) src; 380b8e80941Smrg if (unpack->SwapBytes) { 381b8e80941Smrg for (i = 0; i < n; i++) { 382b8e80941Smrg GLint value = s[i]; 383b8e80941Smrg SWAP4BYTE(value); 384b8e80941Smrg indexes[i] = value; 385b8e80941Smrg } 386b8e80941Smrg } 387b8e80941Smrg else { 388b8e80941Smrg for (i = 0; i < n; i++) 389b8e80941Smrg indexes[i] = s[i]; 390b8e80941Smrg } 391848b8605Smrg } 392b8e80941Smrg break; 393b8e80941Smrg case GL_FLOAT: 394b8e80941Smrg { 395b8e80941Smrg GLuint i; 396b8e80941Smrg const GLfloat *s = (const GLfloat *) src; 397b8e80941Smrg if (unpack->SwapBytes) { 398b8e80941Smrg for (i = 0; i < n; i++) { 399b8e80941Smrg GLfloat value = s[i]; 400b8e80941Smrg SWAP4BYTE(value); 401b8e80941Smrg indexes[i] = (GLuint) value; 402b8e80941Smrg } 403b8e80941Smrg } 404b8e80941Smrg else { 405b8e80941Smrg for (i = 0; i < n; i++) 406b8e80941Smrg indexes[i] = (GLuint) s[i]; 407b8e80941Smrg } 408848b8605Smrg } 409b8e80941Smrg break; 410b8e80941Smrg case GL_HALF_FLOAT_ARB: 411b8e80941Smrg case GL_HALF_FLOAT_OES: 412b8e80941Smrg { 413b8e80941Smrg GLuint i; 414b8e80941Smrg const GLhalfARB *s = (const GLhalfARB *) src; 415b8e80941Smrg if (unpack->SwapBytes) { 416b8e80941Smrg for (i = 0; i < n; i++) { 417b8e80941Smrg GLhalfARB value = s[i]; 418b8e80941Smrg SWAP2BYTE(value); 419b8e80941Smrg indexes[i] = (GLuint) _mesa_half_to_float(value); 420b8e80941Smrg } 421b8e80941Smrg } 422b8e80941Smrg else { 423b8e80941Smrg for (i = 0; i < n; i++) 424b8e80941Smrg indexes[i] = (GLuint) _mesa_half_to_float(s[i]); 425b8e80941Smrg } 426848b8605Smrg } 427b8e80941Smrg break; 428b8e80941Smrg case GL_UNSIGNED_INT_24_8_EXT: 429b8e80941Smrg { 430b8e80941Smrg GLuint i; 431b8e80941Smrg const GLuint *s = (const GLuint *) src; 432b8e80941Smrg if (unpack->SwapBytes) { 433b8e80941Smrg for (i = 0; i < n; i++) { 434b8e80941Smrg GLuint value = s[i]; 435b8e80941Smrg SWAP4BYTE(value); 436b8e80941Smrg indexes[i] = value & 0xff; /* lower 8 bits */ 437b8e80941Smrg } 438b8e80941Smrg } 439b8e80941Smrg else { 440b8e80941Smrg for (i = 0; i < n; i++) 441b8e80941Smrg indexes[i] = s[i] & 0xff; /* lower 8 bits */ 442b8e80941Smrg } 443848b8605Smrg } 444b8e80941Smrg break; 445b8e80941Smrg case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 446b8e80941Smrg { 447b8e80941Smrg GLuint i; 448b8e80941Smrg const GLuint *s = (const GLuint *) src; 449b8e80941Smrg if (unpack->SwapBytes) { 450b8e80941Smrg for (i = 0; i < n; i++) { 451b8e80941Smrg GLuint value = s[i*2+1]; 452b8e80941Smrg SWAP4BYTE(value); 453b8e80941Smrg indexes[i] = value & 0xff; /* lower 8 bits */ 454b8e80941Smrg } 455b8e80941Smrg } 456b8e80941Smrg else { 457b8e80941Smrg for (i = 0; i < n; i++) 458b8e80941Smrg indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */ 459b8e80941Smrg } 460b8e80941Smrg } 461b8e80941Smrg break; 462848b8605Smrg 463b8e80941Smrg default: 464b8e80941Smrg unreachable("bad srcType in extract_uint_indexes"); 465b8e80941Smrg } 466848b8605Smrg} 467848b8605Smrg 468848b8605Smrg 469848b8605Smrg/* 470848b8605Smrg * Unpack a row of stencil data from a client buffer according to 471848b8605Smrg * the pixel unpacking parameters. 472848b8605Smrg * This is (or will be) used by glDrawPixels 473848b8605Smrg * 474848b8605Smrg * Args: ctx - the context 475848b8605Smrg * n - number of pixels 476848b8605Smrg * dstType - destination data type 477848b8605Smrg * dest - destination array 478848b8605Smrg * srcType - source pixel type 479848b8605Smrg * source - source data pointer 480848b8605Smrg * srcPacking - pixel unpacking parameters 481848b8605Smrg * transferOps - apply offset/bias/lookup ops? 482848b8605Smrg */ 483848b8605Smrgvoid 484848b8605Smrg_mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, 485848b8605Smrg GLenum dstType, GLvoid *dest, 486848b8605Smrg GLenum srcType, const GLvoid *source, 487848b8605Smrg const struct gl_pixelstore_attrib *srcPacking, 488848b8605Smrg GLbitfield transferOps ) 489848b8605Smrg{ 490b8e80941Smrg assert(srcType == GL_BITMAP || 491848b8605Smrg srcType == GL_UNSIGNED_BYTE || 492848b8605Smrg srcType == GL_BYTE || 493848b8605Smrg srcType == GL_UNSIGNED_SHORT || 494848b8605Smrg srcType == GL_SHORT || 495848b8605Smrg srcType == GL_UNSIGNED_INT || 496848b8605Smrg srcType == GL_INT || 497848b8605Smrg srcType == GL_UNSIGNED_INT_24_8_EXT || 498848b8605Smrg srcType == GL_HALF_FLOAT_ARB || 499b8e80941Smrg srcType == GL_HALF_FLOAT_OES || 500848b8605Smrg srcType == GL_FLOAT || 501848b8605Smrg srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 502848b8605Smrg 503b8e80941Smrg assert(dstType == GL_UNSIGNED_BYTE || 504848b8605Smrg dstType == GL_UNSIGNED_SHORT || 505848b8605Smrg dstType == GL_UNSIGNED_INT || 506848b8605Smrg dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 507848b8605Smrg 508848b8605Smrg /* only shift and offset apply to stencil */ 509848b8605Smrg transferOps &= IMAGE_SHIFT_OFFSET_BIT; 510848b8605Smrg 511848b8605Smrg /* 512848b8605Smrg * Try simple cases first 513848b8605Smrg */ 514848b8605Smrg if (transferOps == 0 && 515848b8605Smrg !ctx->Pixel.MapStencilFlag && 516848b8605Smrg srcType == GL_UNSIGNED_BYTE && 517848b8605Smrg dstType == GL_UNSIGNED_BYTE) { 518848b8605Smrg memcpy(dest, source, n * sizeof(GLubyte)); 519848b8605Smrg } 520848b8605Smrg else if (transferOps == 0 && 521848b8605Smrg !ctx->Pixel.MapStencilFlag && 522848b8605Smrg srcType == GL_UNSIGNED_INT && 523848b8605Smrg dstType == GL_UNSIGNED_INT && 524848b8605Smrg !srcPacking->SwapBytes) { 525848b8605Smrg memcpy(dest, source, n * sizeof(GLuint)); 526848b8605Smrg } 527848b8605Smrg else { 528848b8605Smrg /* 529848b8605Smrg * general solution 530848b8605Smrg */ 531848b8605Smrg GLuint *indexes = malloc(n * sizeof(GLuint)); 532848b8605Smrg 533848b8605Smrg if (!indexes) { 534848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking"); 535848b8605Smrg return; 536848b8605Smrg } 537848b8605Smrg 538848b8605Smrg extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source, 539848b8605Smrg srcPacking); 540848b8605Smrg 541848b8605Smrg if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { 542848b8605Smrg /* shift and offset indexes */ 543848b8605Smrg _mesa_shift_and_offset_ci(ctx, n, indexes); 544848b8605Smrg } 545848b8605Smrg 546848b8605Smrg if (ctx->Pixel.MapStencilFlag) { 547848b8605Smrg /* Apply stencil lookup table */ 548848b8605Smrg const GLuint mask = ctx->PixelMaps.StoS.Size - 1; 549848b8605Smrg GLuint i; 550848b8605Smrg for (i = 0; i < n; i++) { 551848b8605Smrg indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ]; 552848b8605Smrg } 553848b8605Smrg } 554848b8605Smrg 555848b8605Smrg /* convert to dest type */ 556848b8605Smrg switch (dstType) { 557848b8605Smrg case GL_UNSIGNED_BYTE: 558848b8605Smrg { 559848b8605Smrg GLubyte *dst = (GLubyte *) dest; 560848b8605Smrg GLuint i; 561848b8605Smrg for (i = 0; i < n; i++) { 562848b8605Smrg dst[i] = (GLubyte) (indexes[i] & 0xff); 563848b8605Smrg } 564848b8605Smrg } 565848b8605Smrg break; 566848b8605Smrg case GL_UNSIGNED_SHORT: 567848b8605Smrg { 568848b8605Smrg GLuint *dst = (GLuint *) dest; 569848b8605Smrg GLuint i; 570848b8605Smrg for (i = 0; i < n; i++) { 571848b8605Smrg dst[i] = (GLushort) (indexes[i] & 0xffff); 572848b8605Smrg } 573848b8605Smrg } 574848b8605Smrg break; 575848b8605Smrg case GL_UNSIGNED_INT: 576848b8605Smrg memcpy(dest, indexes, n * sizeof(GLuint)); 577848b8605Smrg break; 578848b8605Smrg case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 579848b8605Smrg { 580848b8605Smrg GLuint *dst = (GLuint *) dest; 581848b8605Smrg GLuint i; 582848b8605Smrg for (i = 0; i < n; i++) { 583848b8605Smrg dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */ 584848b8605Smrg } 585848b8605Smrg } 586848b8605Smrg break; 587848b8605Smrg default: 588b8e80941Smrg unreachable("bad dstType in _mesa_unpack_stencil_span"); 589848b8605Smrg } 590848b8605Smrg 591848b8605Smrg free(indexes); 592848b8605Smrg } 593848b8605Smrg} 594848b8605Smrg 595848b8605Smrg 596848b8605Smrgvoid 597848b8605Smrg_mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, 598848b8605Smrg GLenum dstType, GLvoid *dest, const GLubyte *source, 599848b8605Smrg const struct gl_pixelstore_attrib *dstPacking ) 600848b8605Smrg{ 601848b8605Smrg GLubyte *stencil = malloc(n * sizeof(GLubyte)); 602848b8605Smrg 603848b8605Smrg if (!stencil) { 604848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing"); 605848b8605Smrg return; 606848b8605Smrg } 607848b8605Smrg 608848b8605Smrg if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || 609848b8605Smrg ctx->Pixel.MapStencilFlag) { 610848b8605Smrg /* make a copy of input */ 611848b8605Smrg memcpy(stencil, source, n * sizeof(GLubyte)); 612848b8605Smrg _mesa_apply_stencil_transfer_ops(ctx, n, stencil); 613848b8605Smrg source = stencil; 614848b8605Smrg } 615848b8605Smrg 616848b8605Smrg switch (dstType) { 617848b8605Smrg case GL_UNSIGNED_BYTE: 618848b8605Smrg memcpy(dest, source, n); 619848b8605Smrg break; 620848b8605Smrg case GL_BYTE: 621848b8605Smrg { 622848b8605Smrg GLbyte *dst = (GLbyte *) dest; 623848b8605Smrg GLuint i; 624848b8605Smrg for (i=0;i<n;i++) { 625848b8605Smrg dst[i] = (GLbyte) (source[i] & 0x7f); 626848b8605Smrg } 627848b8605Smrg } 628848b8605Smrg break; 629848b8605Smrg case GL_UNSIGNED_SHORT: 630848b8605Smrg { 631848b8605Smrg GLushort *dst = (GLushort *) dest; 632848b8605Smrg GLuint i; 633848b8605Smrg for (i=0;i<n;i++) { 634848b8605Smrg dst[i] = (GLushort) source[i]; 635848b8605Smrg } 636848b8605Smrg if (dstPacking->SwapBytes) { 637848b8605Smrg _mesa_swap2( (GLushort *) dst, n ); 638848b8605Smrg } 639848b8605Smrg } 640848b8605Smrg break; 641848b8605Smrg case GL_SHORT: 642848b8605Smrg { 643848b8605Smrg GLshort *dst = (GLshort *) dest; 644848b8605Smrg GLuint i; 645848b8605Smrg for (i=0;i<n;i++) { 646848b8605Smrg dst[i] = (GLshort) source[i]; 647848b8605Smrg } 648848b8605Smrg if (dstPacking->SwapBytes) { 649848b8605Smrg _mesa_swap2( (GLushort *) dst, n ); 650848b8605Smrg } 651848b8605Smrg } 652848b8605Smrg break; 653848b8605Smrg case GL_UNSIGNED_INT: 654848b8605Smrg { 655848b8605Smrg GLuint *dst = (GLuint *) dest; 656848b8605Smrg GLuint i; 657848b8605Smrg for (i=0;i<n;i++) { 658848b8605Smrg dst[i] = (GLuint) source[i]; 659848b8605Smrg } 660848b8605Smrg if (dstPacking->SwapBytes) { 661848b8605Smrg _mesa_swap4( (GLuint *) dst, n ); 662848b8605Smrg } 663848b8605Smrg } 664848b8605Smrg break; 665848b8605Smrg case GL_INT: 666848b8605Smrg { 667848b8605Smrg GLint *dst = (GLint *) dest; 668848b8605Smrg GLuint i; 669848b8605Smrg for (i=0;i<n;i++) { 670848b8605Smrg dst[i] = (GLint) source[i]; 671848b8605Smrg } 672848b8605Smrg if (dstPacking->SwapBytes) { 673848b8605Smrg _mesa_swap4( (GLuint *) dst, n ); 674848b8605Smrg } 675848b8605Smrg } 676848b8605Smrg break; 677848b8605Smrg case GL_FLOAT: 678848b8605Smrg { 679848b8605Smrg GLfloat *dst = (GLfloat *) dest; 680848b8605Smrg GLuint i; 681848b8605Smrg for (i=0;i<n;i++) { 682848b8605Smrg dst[i] = (GLfloat) source[i]; 683848b8605Smrg } 684848b8605Smrg if (dstPacking->SwapBytes) { 685848b8605Smrg _mesa_swap4( (GLuint *) dst, n ); 686848b8605Smrg } 687848b8605Smrg } 688848b8605Smrg break; 689848b8605Smrg case GL_HALF_FLOAT_ARB: 690b8e80941Smrg case GL_HALF_FLOAT_OES: 691848b8605Smrg { 692848b8605Smrg GLhalfARB *dst = (GLhalfARB *) dest; 693848b8605Smrg GLuint i; 694848b8605Smrg for (i=0;i<n;i++) { 695848b8605Smrg dst[i] = _mesa_float_to_half( (float) source[i] ); 696848b8605Smrg } 697848b8605Smrg if (dstPacking->SwapBytes) { 698848b8605Smrg _mesa_swap2( (GLushort *) dst, n ); 699848b8605Smrg } 700848b8605Smrg } 701848b8605Smrg break; 702848b8605Smrg case GL_BITMAP: 703848b8605Smrg if (dstPacking->LsbFirst) { 704848b8605Smrg GLubyte *dst = (GLubyte *) dest; 705848b8605Smrg GLint shift = 0; 706848b8605Smrg GLuint i; 707848b8605Smrg for (i = 0; i < n; i++) { 708848b8605Smrg if (shift == 0) 709848b8605Smrg *dst = 0; 710848b8605Smrg *dst |= ((source[i] != 0) << shift); 711848b8605Smrg shift++; 712848b8605Smrg if (shift == 8) { 713848b8605Smrg shift = 0; 714848b8605Smrg dst++; 715848b8605Smrg } 716848b8605Smrg } 717848b8605Smrg } 718848b8605Smrg else { 719848b8605Smrg GLubyte *dst = (GLubyte *) dest; 720848b8605Smrg GLint shift = 7; 721848b8605Smrg GLuint i; 722848b8605Smrg for (i = 0; i < n; i++) { 723848b8605Smrg if (shift == 7) 724848b8605Smrg *dst = 0; 725848b8605Smrg *dst |= ((source[i] != 0) << shift); 726848b8605Smrg shift--; 727848b8605Smrg if (shift < 0) { 728848b8605Smrg shift = 7; 729848b8605Smrg dst++; 730848b8605Smrg } 731848b8605Smrg } 732848b8605Smrg } 733848b8605Smrg break; 734848b8605Smrg default: 735b8e80941Smrg unreachable("bad type in _mesa_pack_index_span"); 736848b8605Smrg } 737848b8605Smrg 738848b8605Smrg free(stencil); 739848b8605Smrg} 740848b8605Smrg 741848b8605Smrg#define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT) \ 742848b8605Smrg do { \ 743848b8605Smrg GLuint i; \ 744848b8605Smrg const GLTYPE *src = (const GLTYPE *)source; \ 745848b8605Smrg for (i = 0; i < n; i++) { \ 746848b8605Smrg GLTYPE value = src[i]; \ 747848b8605Smrg if (srcPacking->SwapBytes) { \ 748848b8605Smrg if (sizeof(GLTYPE) == 2) { \ 749848b8605Smrg SWAP2BYTE(value); \ 750848b8605Smrg } else if (sizeof(GLTYPE) == 4) { \ 751848b8605Smrg SWAP4BYTE(value); \ 752848b8605Smrg } \ 753848b8605Smrg } \ 754848b8605Smrg depthValues[i] = GLTYPE2FLOAT(value); \ 755848b8605Smrg } \ 756848b8605Smrg } while (0) 757848b8605Smrg 758848b8605Smrg 759848b8605Smrg/** 760848b8605Smrg * Unpack a row of depth/z values from memory, returning GLushort, GLuint 761848b8605Smrg * or GLfloat values. 762848b8605Smrg * The glPixelTransfer (scale/bias) params will be applied. 763848b8605Smrg * 764848b8605Smrg * \param dstType one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT 765848b8605Smrg * \param depthMax max value for returned GLushort or GLuint values 766848b8605Smrg * (ignored for GLfloat). 767848b8605Smrg */ 768848b8605Smrgvoid 769848b8605Smrg_mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, 770848b8605Smrg GLenum dstType, GLvoid *dest, GLuint depthMax, 771848b8605Smrg GLenum srcType, const GLvoid *source, 772848b8605Smrg const struct gl_pixelstore_attrib *srcPacking ) 773848b8605Smrg{ 774848b8605Smrg GLfloat *depthTemp = NULL, *depthValues; 775848b8605Smrg GLboolean needClamp = GL_FALSE; 776848b8605Smrg 777848b8605Smrg /* Look for special cases first. 778848b8605Smrg * Not only are these faster, they're less prone to numeric conversion 779848b8605Smrg * problems. Otherwise, converting from an int type to a float then 780848b8605Smrg * back to an int type can introduce errors that will show up as 781848b8605Smrg * artifacts in things like depth peeling which uses glCopyTexImage. 782848b8605Smrg */ 783b8e80941Smrg if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F) { 784848b8605Smrg if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) { 785848b8605Smrg const GLuint *src = (const GLuint *) source; 786848b8605Smrg GLushort *dst = (GLushort *) dest; 787848b8605Smrg GLuint i; 788848b8605Smrg for (i = 0; i < n; i++) { 789848b8605Smrg dst[i] = src[i] >> 16; 790848b8605Smrg } 791848b8605Smrg return; 792848b8605Smrg } 793848b8605Smrg if (srcType == GL_UNSIGNED_SHORT 794848b8605Smrg && dstType == GL_UNSIGNED_INT 795848b8605Smrg && depthMax == 0xffffffff) { 796848b8605Smrg const GLushort *src = (const GLushort *) source; 797848b8605Smrg GLuint *dst = (GLuint *) dest; 798848b8605Smrg GLuint i; 799848b8605Smrg for (i = 0; i < n; i++) { 800848b8605Smrg dst[i] = src[i] | (src[i] << 16); 801848b8605Smrg } 802848b8605Smrg return; 803848b8605Smrg } 804848b8605Smrg if (srcType == GL_UNSIGNED_INT_24_8 805848b8605Smrg && dstType == GL_UNSIGNED_INT 806848b8605Smrg && depthMax == 0xffffff) { 807848b8605Smrg const GLuint *src = (const GLuint *) source; 808848b8605Smrg GLuint *dst = (GLuint *) dest; 809848b8605Smrg GLuint i; 810848b8605Smrg for (i = 0; i < n; i++) { 811848b8605Smrg dst[i] = src[i] >> 8; 812848b8605Smrg } 813848b8605Smrg return; 814848b8605Smrg } 815848b8605Smrg /* XXX may want to add additional cases here someday */ 816848b8605Smrg } 817848b8605Smrg 818848b8605Smrg /* general case path follows */ 819848b8605Smrg 820848b8605Smrg if (dstType == GL_FLOAT) { 821848b8605Smrg depthValues = (GLfloat *) dest; 822848b8605Smrg } 823848b8605Smrg else { 824848b8605Smrg depthTemp = malloc(n * sizeof(GLfloat)); 825848b8605Smrg if (!depthTemp) { 826848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); 827848b8605Smrg return; 828848b8605Smrg } 829848b8605Smrg 830848b8605Smrg depthValues = depthTemp; 831848b8605Smrg } 832848b8605Smrg 833848b8605Smrg /* Convert incoming values to GLfloat. Some conversions will require 834848b8605Smrg * clamping, below. 835848b8605Smrg */ 836848b8605Smrg switch (srcType) { 837848b8605Smrg case GL_BYTE: 838848b8605Smrg DEPTH_VALUES(GLbyte, BYTE_TO_FLOATZ); 839848b8605Smrg needClamp = GL_TRUE; 840848b8605Smrg break; 841848b8605Smrg case GL_UNSIGNED_BYTE: 842848b8605Smrg DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT); 843848b8605Smrg break; 844848b8605Smrg case GL_SHORT: 845848b8605Smrg DEPTH_VALUES(GLshort, SHORT_TO_FLOATZ); 846848b8605Smrg needClamp = GL_TRUE; 847848b8605Smrg break; 848848b8605Smrg case GL_UNSIGNED_SHORT: 849848b8605Smrg DEPTH_VALUES(GLushort, USHORT_TO_FLOAT); 850848b8605Smrg break; 851848b8605Smrg case GL_INT: 852848b8605Smrg DEPTH_VALUES(GLint, INT_TO_FLOAT); 853848b8605Smrg needClamp = GL_TRUE; 854848b8605Smrg break; 855848b8605Smrg case GL_UNSIGNED_INT: 856848b8605Smrg DEPTH_VALUES(GLuint, UINT_TO_FLOAT); 857848b8605Smrg break; 858848b8605Smrg case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */ 859848b8605Smrg if (dstType == GL_UNSIGNED_INT_24_8_EXT && 860848b8605Smrg depthMax == 0xffffff && 861b8e80941Smrg ctx->Pixel.DepthScale == 1.0F && 862b8e80941Smrg ctx->Pixel.DepthBias == 0.0F) { 863848b8605Smrg const GLuint *src = (const GLuint *) source; 864848b8605Smrg GLuint *zValues = (GLuint *) dest; 865848b8605Smrg GLuint i; 866848b8605Smrg for (i = 0; i < n; i++) { 867848b8605Smrg GLuint value = src[i]; 868848b8605Smrg if (srcPacking->SwapBytes) { 869848b8605Smrg SWAP4BYTE(value); 870848b8605Smrg } 871848b8605Smrg zValues[i] = value & 0xffffff00; 872848b8605Smrg } 873848b8605Smrg free(depthTemp); 874848b8605Smrg return; 875848b8605Smrg } 876848b8605Smrg else { 877848b8605Smrg const GLuint *src = (const GLuint *) source; 878848b8605Smrg const GLfloat scale = 1.0f / 0xffffff; 879848b8605Smrg GLuint i; 880848b8605Smrg for (i = 0; i < n; i++) { 881848b8605Smrg GLuint value = src[i]; 882848b8605Smrg if (srcPacking->SwapBytes) { 883848b8605Smrg SWAP4BYTE(value); 884848b8605Smrg } 885848b8605Smrg depthValues[i] = (value >> 8) * scale; 886848b8605Smrg } 887848b8605Smrg } 888848b8605Smrg break; 889848b8605Smrg case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 890848b8605Smrg { 891848b8605Smrg GLuint i; 892848b8605Smrg const GLfloat *src = (const GLfloat *)source; 893848b8605Smrg for (i = 0; i < n; i++) { 894848b8605Smrg GLfloat value = src[i * 2]; 895848b8605Smrg if (srcPacking->SwapBytes) { 896848b8605Smrg SWAP4BYTE(value); 897848b8605Smrg } 898848b8605Smrg depthValues[i] = value; 899848b8605Smrg } 900848b8605Smrg needClamp = GL_TRUE; 901848b8605Smrg } 902848b8605Smrg break; 903848b8605Smrg case GL_FLOAT: 904848b8605Smrg DEPTH_VALUES(GLfloat, 1*); 905848b8605Smrg needClamp = GL_TRUE; 906848b8605Smrg break; 907848b8605Smrg case GL_HALF_FLOAT_ARB: 908b8e80941Smrg case GL_HALF_FLOAT_OES: 909848b8605Smrg { 910848b8605Smrg GLuint i; 911848b8605Smrg const GLhalfARB *src = (const GLhalfARB *) source; 912848b8605Smrg for (i = 0; i < n; i++) { 913848b8605Smrg GLhalfARB value = src[i]; 914848b8605Smrg if (srcPacking->SwapBytes) { 915848b8605Smrg SWAP2BYTE(value); 916848b8605Smrg } 917848b8605Smrg depthValues[i] = _mesa_half_to_float(value); 918848b8605Smrg } 919848b8605Smrg needClamp = GL_TRUE; 920848b8605Smrg } 921848b8605Smrg break; 922848b8605Smrg default: 923848b8605Smrg _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()"); 924848b8605Smrg free(depthTemp); 925848b8605Smrg return; 926848b8605Smrg } 927848b8605Smrg 928848b8605Smrg /* apply depth scale and bias */ 929848b8605Smrg { 930848b8605Smrg const GLfloat scale = ctx->Pixel.DepthScale; 931848b8605Smrg const GLfloat bias = ctx->Pixel.DepthBias; 932b8e80941Smrg if (scale != 1.0F || bias != 0.0F) { 933848b8605Smrg GLuint i; 934848b8605Smrg for (i = 0; i < n; i++) { 935848b8605Smrg depthValues[i] = depthValues[i] * scale + bias; 936848b8605Smrg } 937848b8605Smrg needClamp = GL_TRUE; 938848b8605Smrg } 939848b8605Smrg } 940848b8605Smrg 941848b8605Smrg /* clamp to [0, 1] */ 942848b8605Smrg if (needClamp) { 943848b8605Smrg GLuint i; 944848b8605Smrg for (i = 0; i < n; i++) { 945b8e80941Smrg depthValues[i] = CLAMP(depthValues[i], 0.0F, 1.0F); 946848b8605Smrg } 947848b8605Smrg } 948848b8605Smrg 949848b8605Smrg /* 950848b8605Smrg * Convert values to dstType 951848b8605Smrg */ 952848b8605Smrg if (dstType == GL_UNSIGNED_INT) { 953848b8605Smrg GLuint *zValues = (GLuint *) dest; 954848b8605Smrg GLuint i; 955848b8605Smrg if (depthMax <= 0xffffff) { 956848b8605Smrg /* no overflow worries */ 957848b8605Smrg for (i = 0; i < n; i++) { 958848b8605Smrg zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax); 959848b8605Smrg } 960848b8605Smrg } 961848b8605Smrg else { 962848b8605Smrg /* need to use double precision to prevent overflow problems */ 963848b8605Smrg for (i = 0; i < n; i++) { 964848b8605Smrg GLdouble z = depthValues[i] * (GLdouble) depthMax; 965848b8605Smrg if (z >= (GLdouble) 0xffffffff) 966848b8605Smrg zValues[i] = 0xffffffff; 967848b8605Smrg else 968848b8605Smrg zValues[i] = (GLuint) z; 969848b8605Smrg } 970848b8605Smrg } 971848b8605Smrg } 972848b8605Smrg else if (dstType == GL_UNSIGNED_SHORT) { 973848b8605Smrg GLushort *zValues = (GLushort *) dest; 974848b8605Smrg GLuint i; 975b8e80941Smrg assert(depthMax <= 0xffff); 976848b8605Smrg for (i = 0; i < n; i++) { 977848b8605Smrg zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax); 978848b8605Smrg } 979848b8605Smrg } 980848b8605Smrg else if (dstType == GL_FLOAT) { 981848b8605Smrg /* Nothing to do. depthValues is pointing to dest. */ 982848b8605Smrg } 983848b8605Smrg else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) { 984848b8605Smrg GLfloat *zValues = (GLfloat*) dest; 985848b8605Smrg GLuint i; 986848b8605Smrg for (i = 0; i < n; i++) { 987848b8605Smrg zValues[i*2] = depthValues[i]; 988848b8605Smrg } 989848b8605Smrg } 990848b8605Smrg else { 991b8e80941Smrg assert(0); 992848b8605Smrg } 993848b8605Smrg 994848b8605Smrg free(depthTemp); 995848b8605Smrg} 996848b8605Smrg 997848b8605Smrg 998848b8605Smrg/* 999848b8605Smrg * Pack an array of depth values. The values are floats in [0,1]. 1000848b8605Smrg */ 1001848b8605Smrgvoid 1002848b8605Smrg_mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, 1003848b8605Smrg GLenum dstType, const GLfloat *depthSpan, 1004848b8605Smrg const struct gl_pixelstore_attrib *dstPacking ) 1005848b8605Smrg{ 1006848b8605Smrg GLfloat *depthCopy = malloc(n * sizeof(GLfloat)); 1007848b8605Smrg if (!depthCopy) { 1008848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); 1009848b8605Smrg return; 1010848b8605Smrg } 1011848b8605Smrg 1012b8e80941Smrg if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) { 1013848b8605Smrg memcpy(depthCopy, depthSpan, n * sizeof(GLfloat)); 1014848b8605Smrg _mesa_scale_and_bias_depth(ctx, n, depthCopy); 1015848b8605Smrg depthSpan = depthCopy; 1016848b8605Smrg } 1017848b8605Smrg 1018848b8605Smrg switch (dstType) { 1019848b8605Smrg case GL_UNSIGNED_BYTE: 1020848b8605Smrg { 1021848b8605Smrg GLubyte *dst = (GLubyte *) dest; 1022848b8605Smrg GLuint i; 1023848b8605Smrg for (i = 0; i < n; i++) { 1024848b8605Smrg dst[i] = FLOAT_TO_UBYTE( depthSpan[i] ); 1025848b8605Smrg } 1026848b8605Smrg } 1027848b8605Smrg break; 1028848b8605Smrg case GL_BYTE: 1029848b8605Smrg { 1030848b8605Smrg GLbyte *dst = (GLbyte *) dest; 1031848b8605Smrg GLuint i; 1032848b8605Smrg for (i = 0; i < n; i++) { 1033848b8605Smrg dst[i] = FLOAT_TO_BYTE( depthSpan[i] ); 1034848b8605Smrg } 1035848b8605Smrg } 1036848b8605Smrg break; 1037848b8605Smrg case GL_UNSIGNED_SHORT: 1038848b8605Smrg { 1039848b8605Smrg GLushort *dst = (GLushort *) dest; 1040848b8605Smrg GLuint i; 1041848b8605Smrg for (i = 0; i < n; i++) { 1042848b8605Smrg CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]); 1043848b8605Smrg } 1044848b8605Smrg if (dstPacking->SwapBytes) { 1045848b8605Smrg _mesa_swap2( (GLushort *) dst, n ); 1046848b8605Smrg } 1047848b8605Smrg } 1048848b8605Smrg break; 1049848b8605Smrg case GL_SHORT: 1050848b8605Smrg { 1051848b8605Smrg GLshort *dst = (GLshort *) dest; 1052848b8605Smrg GLuint i; 1053848b8605Smrg for (i = 0; i < n; i++) { 1054848b8605Smrg dst[i] = FLOAT_TO_SHORT( depthSpan[i] ); 1055848b8605Smrg } 1056848b8605Smrg if (dstPacking->SwapBytes) { 1057848b8605Smrg _mesa_swap2( (GLushort *) dst, n ); 1058848b8605Smrg } 1059848b8605Smrg } 1060848b8605Smrg break; 1061b8e80941Smrg case GL_UNSIGNED_INT_24_8: 1062b8e80941Smrg { 1063b8e80941Smrg const GLdouble scale = (GLdouble) 0xffffff; 1064b8e80941Smrg GLuint *dst = (GLuint *) dest; 1065b8e80941Smrg GLuint i; 1066b8e80941Smrg for (i = 0; i < n; i++) { 1067b8e80941Smrg GLuint z = (GLuint) (depthSpan[i] * scale); 1068b8e80941Smrg assert(z <= 0xffffff); 1069b8e80941Smrg dst[i] = (z << 8); 1070b8e80941Smrg } 1071b8e80941Smrg if (dstPacking->SwapBytes) { 1072b8e80941Smrg _mesa_swap4( (GLuint *) dst, n ); 1073b8e80941Smrg } 1074b8e80941Smrg break; 1075b8e80941Smrg } 1076848b8605Smrg case GL_UNSIGNED_INT: 1077848b8605Smrg { 1078848b8605Smrg GLuint *dst = (GLuint *) dest; 1079848b8605Smrg GLuint i; 1080848b8605Smrg for (i = 0; i < n; i++) { 1081848b8605Smrg dst[i] = FLOAT_TO_UINT( depthSpan[i] ); 1082848b8605Smrg } 1083848b8605Smrg if (dstPacking->SwapBytes) { 1084848b8605Smrg _mesa_swap4( (GLuint *) dst, n ); 1085848b8605Smrg } 1086848b8605Smrg } 1087848b8605Smrg break; 1088848b8605Smrg case GL_INT: 1089848b8605Smrg { 1090848b8605Smrg GLint *dst = (GLint *) dest; 1091848b8605Smrg GLuint i; 1092848b8605Smrg for (i = 0; i < n; i++) { 1093848b8605Smrg dst[i] = FLOAT_TO_INT( depthSpan[i] ); 1094848b8605Smrg } 1095848b8605Smrg if (dstPacking->SwapBytes) { 1096848b8605Smrg _mesa_swap4( (GLuint *) dst, n ); 1097848b8605Smrg } 1098848b8605Smrg } 1099848b8605Smrg break; 1100848b8605Smrg case GL_FLOAT: 1101848b8605Smrg { 1102848b8605Smrg GLfloat *dst = (GLfloat *) dest; 1103848b8605Smrg GLuint i; 1104848b8605Smrg for (i = 0; i < n; i++) { 1105848b8605Smrg dst[i] = depthSpan[i]; 1106848b8605Smrg } 1107848b8605Smrg if (dstPacking->SwapBytes) { 1108848b8605Smrg _mesa_swap4( (GLuint *) dst, n ); 1109848b8605Smrg } 1110848b8605Smrg } 1111848b8605Smrg break; 1112848b8605Smrg case GL_HALF_FLOAT_ARB: 1113b8e80941Smrg case GL_HALF_FLOAT_OES: 1114848b8605Smrg { 1115848b8605Smrg GLhalfARB *dst = (GLhalfARB *) dest; 1116848b8605Smrg GLuint i; 1117848b8605Smrg for (i = 0; i < n; i++) { 1118848b8605Smrg dst[i] = _mesa_float_to_half(depthSpan[i]); 1119848b8605Smrg } 1120848b8605Smrg if (dstPacking->SwapBytes) { 1121848b8605Smrg _mesa_swap2( (GLushort *) dst, n ); 1122848b8605Smrg } 1123848b8605Smrg } 1124848b8605Smrg break; 1125848b8605Smrg default: 1126b8e80941Smrg unreachable("bad type in _mesa_pack_depth_span()"); 1127848b8605Smrg } 1128848b8605Smrg 1129848b8605Smrg free(depthCopy); 1130848b8605Smrg} 1131848b8605Smrg 1132848b8605Smrg 1133848b8605Smrg 1134848b8605Smrg/** 1135848b8605Smrg * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc) 1136848b8605Smrg */ 1137848b8605Smrgvoid 1138848b8605Smrg_mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n, 1139848b8605Smrg GLenum dstType, GLuint *dest, 1140848b8605Smrg const GLfloat *depthVals, 1141848b8605Smrg const GLubyte *stencilVals, 1142848b8605Smrg const struct gl_pixelstore_attrib *dstPacking) 1143848b8605Smrg{ 1144848b8605Smrg GLfloat *depthCopy = malloc(n * sizeof(GLfloat)); 1145848b8605Smrg GLubyte *stencilCopy = malloc(n * sizeof(GLubyte)); 1146848b8605Smrg GLuint i; 1147848b8605Smrg 1148848b8605Smrg if (!depthCopy || !stencilCopy) { 1149848b8605Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); 1150848b8605Smrg free(depthCopy); 1151848b8605Smrg free(stencilCopy); 1152848b8605Smrg return; 1153848b8605Smrg } 1154848b8605Smrg 1155b8e80941Smrg if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) { 1156848b8605Smrg memcpy(depthCopy, depthVals, n * sizeof(GLfloat)); 1157848b8605Smrg _mesa_scale_and_bias_depth(ctx, n, depthCopy); 1158848b8605Smrg depthVals = depthCopy; 1159848b8605Smrg } 1160848b8605Smrg 1161848b8605Smrg if (ctx->Pixel.IndexShift || 1162848b8605Smrg ctx->Pixel.IndexOffset || 1163848b8605Smrg ctx->Pixel.MapStencilFlag) { 1164848b8605Smrg memcpy(stencilCopy, stencilVals, n * sizeof(GLubyte)); 1165848b8605Smrg _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy); 1166848b8605Smrg stencilVals = stencilCopy; 1167848b8605Smrg } 1168848b8605Smrg 1169848b8605Smrg switch (dstType) { 1170848b8605Smrg case GL_UNSIGNED_INT_24_8: 1171848b8605Smrg for (i = 0; i < n; i++) { 1172848b8605Smrg GLuint z = (GLuint) (depthVals[i] * 0xffffff); 1173848b8605Smrg dest[i] = (z << 8) | (stencilVals[i] & 0xff); 1174848b8605Smrg } 1175848b8605Smrg break; 1176848b8605Smrg case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 1177848b8605Smrg for (i = 0; i < n; i++) { 1178848b8605Smrg ((GLfloat*)dest)[i*2] = depthVals[i]; 1179848b8605Smrg dest[i*2+1] = stencilVals[i] & 0xff; 1180848b8605Smrg } 1181848b8605Smrg break; 1182848b8605Smrg } 1183848b8605Smrg 1184848b8605Smrg if (dstPacking->SwapBytes) { 1185848b8605Smrg _mesa_swap4(dest, n); 1186848b8605Smrg } 1187848b8605Smrg 1188848b8605Smrg free(depthCopy); 1189848b8605Smrg free(stencilCopy); 1190848b8605Smrg} 1191848b8605Smrg 1192848b8605Smrg 1193848b8605Smrg 1194848b8605Smrg/** 1195848b8605Smrg * Unpack image data. Apply byte swapping, byte flipping (bitmap). 1196848b8605Smrg * Return all image data in a contiguous block. This is used when we 1197848b8605Smrg * compile glDrawPixels, glTexImage, etc into a display list. We 1198848b8605Smrg * need a copy of the data in a standard format. 1199848b8605Smrg */ 1200848b8605Smrgvoid * 1201848b8605Smrg_mesa_unpack_image( GLuint dimensions, 1202848b8605Smrg GLsizei width, GLsizei height, GLsizei depth, 1203848b8605Smrg GLenum format, GLenum type, const GLvoid *pixels, 1204848b8605Smrg const struct gl_pixelstore_attrib *unpack ) 1205848b8605Smrg{ 1206848b8605Smrg GLint bytesPerRow, compsPerRow; 1207848b8605Smrg GLboolean flipBytes, swap2, swap4; 1208848b8605Smrg 1209848b8605Smrg if (!pixels) 1210848b8605Smrg return NULL; /* not necessarily an error */ 1211848b8605Smrg 1212848b8605Smrg if (width <= 0 || height <= 0 || depth <= 0) 1213848b8605Smrg return NULL; /* generate error later */ 1214848b8605Smrg 1215848b8605Smrg if (type == GL_BITMAP) { 1216848b8605Smrg bytesPerRow = (width + 7) >> 3; 1217848b8605Smrg flipBytes = unpack->LsbFirst; 1218848b8605Smrg swap2 = swap4 = GL_FALSE; 1219848b8605Smrg compsPerRow = 0; 1220848b8605Smrg } 1221848b8605Smrg else { 1222848b8605Smrg const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); 1223848b8605Smrg GLint components = _mesa_components_in_format(format); 1224848b8605Smrg GLint bytesPerComp; 1225848b8605Smrg 1226848b8605Smrg if (_mesa_type_is_packed(type)) 1227848b8605Smrg components = 1; 1228848b8605Smrg 1229848b8605Smrg if (bytesPerPixel <= 0 || components <= 0) 1230848b8605Smrg return NULL; /* bad format or type. generate error later */ 1231848b8605Smrg bytesPerRow = bytesPerPixel * width; 1232848b8605Smrg bytesPerComp = bytesPerPixel / components; 1233848b8605Smrg flipBytes = GL_FALSE; 1234848b8605Smrg swap2 = (bytesPerComp == 2) && unpack->SwapBytes; 1235848b8605Smrg swap4 = (bytesPerComp == 4) && unpack->SwapBytes; 1236848b8605Smrg compsPerRow = components * width; 1237848b8605Smrg assert(compsPerRow >= width); 1238848b8605Smrg } 1239848b8605Smrg 1240848b8605Smrg { 1241848b8605Smrg GLubyte *destBuffer 1242848b8605Smrg = malloc(bytesPerRow * height * depth); 1243848b8605Smrg GLubyte *dst; 1244848b8605Smrg GLint img, row; 1245848b8605Smrg if (!destBuffer) 1246848b8605Smrg return NULL; /* generate GL_OUT_OF_MEMORY later */ 1247848b8605Smrg 1248848b8605Smrg dst = destBuffer; 1249848b8605Smrg for (img = 0; img < depth; img++) { 1250848b8605Smrg for (row = 0; row < height; row++) { 1251848b8605Smrg const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels, 1252848b8605Smrg width, height, format, type, img, row, 0); 1253848b8605Smrg 1254848b8605Smrg if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) { 1255848b8605Smrg GLint i; 1256848b8605Smrg flipBytes = GL_FALSE; 1257848b8605Smrg if (unpack->LsbFirst) { 1258848b8605Smrg GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7); 1259848b8605Smrg GLubyte dstMask = 128; 1260848b8605Smrg const GLubyte *s = src; 1261848b8605Smrg GLubyte *d = dst; 1262848b8605Smrg *d = 0; 1263848b8605Smrg for (i = 0; i < width; i++) { 1264848b8605Smrg if (*s & srcMask) { 1265848b8605Smrg *d |= dstMask; 1266848b8605Smrg } 1267848b8605Smrg if (srcMask == 128) { 1268848b8605Smrg srcMask = 1; 1269848b8605Smrg s++; 1270848b8605Smrg } 1271848b8605Smrg else { 1272848b8605Smrg srcMask = srcMask << 1; 1273848b8605Smrg } 1274848b8605Smrg if (dstMask == 1) { 1275848b8605Smrg dstMask = 128; 1276848b8605Smrg d++; 1277848b8605Smrg *d = 0; 1278848b8605Smrg } 1279848b8605Smrg else { 1280848b8605Smrg dstMask = dstMask >> 1; 1281848b8605Smrg } 1282848b8605Smrg } 1283848b8605Smrg } 1284848b8605Smrg else { 1285848b8605Smrg GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7); 1286848b8605Smrg GLubyte dstMask = 128; 1287848b8605Smrg const GLubyte *s = src; 1288848b8605Smrg GLubyte *d = dst; 1289848b8605Smrg *d = 0; 1290848b8605Smrg for (i = 0; i < width; i++) { 1291848b8605Smrg if (*s & srcMask) { 1292848b8605Smrg *d |= dstMask; 1293848b8605Smrg } 1294848b8605Smrg if (srcMask == 1) { 1295848b8605Smrg srcMask = 128; 1296848b8605Smrg s++; 1297848b8605Smrg } 1298848b8605Smrg else { 1299848b8605Smrg srcMask = srcMask >> 1; 1300848b8605Smrg } 1301848b8605Smrg if (dstMask == 1) { 1302848b8605Smrg dstMask = 128; 1303848b8605Smrg d++; 1304848b8605Smrg *d = 0; 1305848b8605Smrg } 1306848b8605Smrg else { 1307848b8605Smrg dstMask = dstMask >> 1; 1308848b8605Smrg } 1309848b8605Smrg } 1310848b8605Smrg } 1311848b8605Smrg } 1312848b8605Smrg else { 1313848b8605Smrg memcpy(dst, src, bytesPerRow); 1314848b8605Smrg } 1315848b8605Smrg 1316848b8605Smrg /* byte flipping/swapping */ 1317848b8605Smrg if (flipBytes) { 1318848b8605Smrg flip_bytes((GLubyte *) dst, bytesPerRow); 1319848b8605Smrg } 1320848b8605Smrg else if (swap2) { 1321848b8605Smrg _mesa_swap2((GLushort*) dst, compsPerRow); 1322848b8605Smrg } 1323848b8605Smrg else if (swap4) { 1324848b8605Smrg _mesa_swap4((GLuint*) dst, compsPerRow); 1325848b8605Smrg } 1326848b8605Smrg dst += bytesPerRow; 1327848b8605Smrg } 1328848b8605Smrg } 1329848b8605Smrg return destBuffer; 1330848b8605Smrg } 1331848b8605Smrg} 1332848b8605Smrg 1333848b8605Smrgvoid 1334b8e80941Smrg_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], 1335b8e80941Smrg GLvoid *dstAddr, GLenum dst_format, 1336b8e80941Smrg GLbitfield transferOps) 1337848b8605Smrg{ 1338b8e80941Smrg int i; 1339b8e80941Smrg GLfloat *dst = (GLfloat *) dstAddr; 1340848b8605Smrg 1341b8e80941Smrg switch (dst_format) { 1342848b8605Smrg case GL_LUMINANCE: 1343b8e80941Smrg if (transferOps & IMAGE_CLAMP_BIT) { 1344b8e80941Smrg for (i = 0; i < n; i++) { 1345b8e80941Smrg GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1346b8e80941Smrg dst[i] = CLAMP(sum, 0.0F, 1.0F); 1347b8e80941Smrg } 1348b8e80941Smrg } else { 1349b8e80941Smrg for (i = 0; i < n; i++) { 1350b8e80941Smrg dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1351b8e80941Smrg } 1352848b8605Smrg } 1353b8e80941Smrg return; 1354848b8605Smrg case GL_LUMINANCE_ALPHA: 1355b8e80941Smrg if (transferOps & IMAGE_CLAMP_BIT) { 1356b8e80941Smrg for (i = 0; i < n; i++) { 1357b8e80941Smrg GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1358b8e80941Smrg dst[2*i] = CLAMP(sum, 0.0F, 1.0F); 1359b8e80941Smrg dst[2*i+1] = rgba[i][ACOMP]; 1360b8e80941Smrg } 1361b8e80941Smrg } else { 1362b8e80941Smrg for (i = 0; i < n; i++) { 1363b8e80941Smrg dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 1364b8e80941Smrg dst[2*i+1] = rgba[i][ACOMP]; 1365b8e80941Smrg } 1366848b8605Smrg } 1367b8e80941Smrg return; 1368848b8605Smrg default: 1369b8e80941Smrg assert(!"Unsupported format"); 1370b8e80941Smrg } 1371b8e80941Smrg} 1372b8e80941Smrg 1373b8e80941Smrgstatic int32_t 1374b8e80941Smrgclamp_sint64_to_sint32(int64_t src) 1375b8e80941Smrg{ 1376b8e80941Smrg return CLAMP(src, INT32_MIN, INT32_MAX); 1377b8e80941Smrg} 1378b8e80941Smrg 1379b8e80941Smrgstatic int32_t 1380b8e80941Smrgclamp_sint64_to_uint32(int64_t src) 1381b8e80941Smrg{ 1382b8e80941Smrg return CLAMP(src, 0, UINT32_MAX); 1383b8e80941Smrg} 1384b8e80941Smrg 1385b8e80941Smrgstatic int32_t 1386b8e80941Smrgclamp_uint64_to_uint32(uint64_t src) 1387b8e80941Smrg{ 1388b8e80941Smrg return MIN2(src, UINT32_MAX); 1389b8e80941Smrg} 1390b8e80941Smrg 1391b8e80941Smrgstatic int32_t 1392b8e80941Smrgclamp_uint64_to_sint32(uint64_t src) 1393b8e80941Smrg{ 1394b8e80941Smrg return MIN2(src, INT32_MAX); 1395b8e80941Smrg} 1396b8e80941Smrg 1397b8e80941Smrgstatic int32_t 1398b8e80941Smrgconvert_integer_luminance64(int64_t src64, int bits, 1399b8e80941Smrg bool dst_is_signed, bool src_is_signed) 1400b8e80941Smrg{ 1401b8e80941Smrg int32_t src32; 1402b8e80941Smrg 1403b8e80941Smrg /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need 1404b8e80941Smrg * any signed<->unsigned conversion too. 1405b8e80941Smrg */ 1406b8e80941Smrg if (src_is_signed && dst_is_signed) 1407b8e80941Smrg src32 = clamp_sint64_to_sint32(src64); 1408b8e80941Smrg else if (src_is_signed && !dst_is_signed) 1409b8e80941Smrg src32 = clamp_sint64_to_uint32(src64); 1410b8e80941Smrg else if (!src_is_signed && dst_is_signed) 1411b8e80941Smrg src32 = clamp_uint64_to_sint32(src64); 1412b8e80941Smrg else 1413b8e80941Smrg src32 = clamp_uint64_to_uint32(src64); 1414b8e80941Smrg 1415b8e80941Smrg /* If the dst type is < 32-bit, we need an extra clamp */ 1416b8e80941Smrg if (bits == 32) { 1417b8e80941Smrg return src32; 1418b8e80941Smrg } else { 1419b8e80941Smrg if (dst_is_signed) 1420b8e80941Smrg return _mesa_signed_to_signed(src32, bits); 1421b8e80941Smrg else 1422b8e80941Smrg return _mesa_unsigned_to_unsigned(src32, bits); 1423848b8605Smrg } 1424848b8605Smrg} 1425848b8605Smrg 1426b8e80941Smrgstatic int32_t 1427b8e80941Smrgconvert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed) 1428b8e80941Smrg{ 1429b8e80941Smrg if (src_is_signed && dst_is_signed) 1430b8e80941Smrg return _mesa_signed_to_signed(src, bits); 1431b8e80941Smrg else if (src_is_signed && !dst_is_signed) 1432b8e80941Smrg return _mesa_signed_to_unsigned(src, bits); 1433b8e80941Smrg else if (!src_is_signed && dst_is_signed) 1434b8e80941Smrg return _mesa_unsigned_to_signed(src, bits); 1435b8e80941Smrg else 1436b8e80941Smrg return _mesa_unsigned_to_unsigned(src, bits); 1437b8e80941Smrg} 1438848b8605Smrg 1439848b8605Smrgvoid 1440b8e80941Smrg_mesa_pack_luminance_from_rgba_integer(GLuint n, 1441b8e80941Smrg GLuint rgba[][4], bool rgba_is_signed, 1442b8e80941Smrg GLvoid *dstAddr, 1443b8e80941Smrg GLenum dst_format, 1444b8e80941Smrg GLenum dst_type) 1445848b8605Smrg{ 1446b8e80941Smrg int i; 1447b8e80941Smrg int64_t lum64; 1448b8e80941Smrg int32_t lum32, alpha; 1449b8e80941Smrg bool dst_is_signed; 1450b8e80941Smrg int dst_bits; 1451b8e80941Smrg 1452b8e80941Smrg assert(dst_format == GL_LUMINANCE_INTEGER_EXT || 1453b8e80941Smrg dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT); 1454b8e80941Smrg 1455b8e80941Smrg /* We first compute luminance values as a 64-bit addition of the 1456b8e80941Smrg * 32-bit R,G,B components, then we clamp the result to the dst type size. 1457b8e80941Smrg * 1458b8e80941Smrg * Notice that this operation involves casting the 32-bit R,G,B components 1459b8e80941Smrg * to 64-bit before the addition. Since rgba is defined as a GLuint array 1460b8e80941Smrg * we need to be careful when rgba packs signed data and make sure 1461b8e80941Smrg * that we cast to a 32-bit signed integer values before casting them to 1462b8e80941Smrg * 64-bit signed integers. 1463b8e80941Smrg */ 1464b8e80941Smrg dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT || 1465b8e80941Smrg dst_type == GL_INT); 1466848b8605Smrg 1467b8e80941Smrg dst_bits = _mesa_sizeof_type(dst_type) * 8; 1468b8e80941Smrg assert(dst_bits > 0); 1469b8e80941Smrg 1470b8e80941Smrg switch (dst_format) { 1471b8e80941Smrg case GL_LUMINANCE_INTEGER_EXT: 1472848b8605Smrg for (i = 0; i < n; i++) { 1473b8e80941Smrg if (!rgba_is_signed) { 1474b8e80941Smrg lum64 = (uint64_t) rgba[i][RCOMP] + 1475b8e80941Smrg (uint64_t) rgba[i][GCOMP] + 1476b8e80941Smrg (uint64_t) rgba[i][BCOMP]; 1477b8e80941Smrg } else { 1478b8e80941Smrg lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + 1479b8e80941Smrg (int64_t) ((int32_t) rgba[i][GCOMP]) + 1480b8e80941Smrg (int64_t) ((int32_t) rgba[i][BCOMP]); 1481b8e80941Smrg } 1482b8e80941Smrg lum32 = convert_integer_luminance64(lum64, dst_bits, 1483b8e80941Smrg dst_is_signed, rgba_is_signed); 1484b8e80941Smrg switch (dst_type) { 1485b8e80941Smrg case GL_BYTE: 1486b8e80941Smrg case GL_UNSIGNED_BYTE: { 1487b8e80941Smrg GLbyte *dst = (GLbyte *) dstAddr; 1488b8e80941Smrg dst[i] = lum32; 1489b8e80941Smrg break; 1490b8e80941Smrg } 1491b8e80941Smrg case GL_SHORT: 1492b8e80941Smrg case GL_UNSIGNED_SHORT: { 1493b8e80941Smrg GLshort *dst = (GLshort *) dstAddr; 1494b8e80941Smrg dst[i] = lum32; 1495b8e80941Smrg break; 1496b8e80941Smrg } 1497b8e80941Smrg case GL_INT: 1498b8e80941Smrg case GL_UNSIGNED_INT: { 1499b8e80941Smrg GLint *dst = (GLint *) dstAddr; 1500b8e80941Smrg dst[i] = lum32; 1501b8e80941Smrg break; 1502b8e80941Smrg } 1503b8e80941Smrg } 1504848b8605Smrg } 1505b8e80941Smrg return; 1506b8e80941Smrg case GL_LUMINANCE_ALPHA_INTEGER_EXT: 1507848b8605Smrg for (i = 0; i < n; i++) { 1508b8e80941Smrg if (!rgba_is_signed) { 1509b8e80941Smrg lum64 = (uint64_t) rgba[i][RCOMP] + 1510b8e80941Smrg (uint64_t) rgba[i][GCOMP] + 1511b8e80941Smrg (uint64_t) rgba[i][BCOMP]; 1512b8e80941Smrg } else { 1513b8e80941Smrg lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + 1514b8e80941Smrg (int64_t) ((int32_t) rgba[i][GCOMP]) + 1515b8e80941Smrg (int64_t) ((int32_t) rgba[i][BCOMP]); 1516b8e80941Smrg } 1517b8e80941Smrg lum32 = convert_integer_luminance64(lum64, dst_bits, 1518b8e80941Smrg dst_is_signed, rgba_is_signed); 1519b8e80941Smrg alpha = convert_integer(rgba[i][ACOMP], dst_bits, 1520b8e80941Smrg dst_is_signed, rgba_is_signed); 1521b8e80941Smrg switch (dst_type) { 1522b8e80941Smrg case GL_BYTE: 1523b8e80941Smrg case GL_UNSIGNED_BYTE: { 1524b8e80941Smrg GLbyte *dst = (GLbyte *) dstAddr; 1525b8e80941Smrg dst[2*i] = lum32; 1526b8e80941Smrg dst[2*i+1] = alpha; 1527b8e80941Smrg break; 1528b8e80941Smrg } 1529b8e80941Smrg case GL_SHORT: 1530b8e80941Smrg case GL_UNSIGNED_SHORT: { 1531b8e80941Smrg GLshort *dst = (GLshort *) dstAddr; 1532b8e80941Smrg dst[i] = lum32; 1533b8e80941Smrg dst[2*i+1] = alpha; 1534b8e80941Smrg break; 1535b8e80941Smrg } 1536b8e80941Smrg case GL_INT: 1537b8e80941Smrg case GL_UNSIGNED_INT: { 1538b8e80941Smrg GLint *dst = (GLint *) dstAddr; 1539b8e80941Smrg dst[i] = lum32; 1540b8e80941Smrg dst[2*i+1] = alpha; 1541b8e80941Smrg break; 1542b8e80941Smrg } 1543b8e80941Smrg } 1544848b8605Smrg } 1545b8e80941Smrg return; 1546848b8605Smrg } 1547848b8605Smrg} 1548848b8605Smrg 1549b8e80941SmrgGLfloat * 1550b8e80941Smrg_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims, 1551b8e80941Smrg const void *src, GLenum srcFormat, GLenum srcType, 1552b8e80941Smrg int srcWidth, int srcHeight, int srcDepth, 1553b8e80941Smrg const struct gl_pixelstore_attrib *srcPacking, 1554b8e80941Smrg GLbitfield transferOps) 1555b8e80941Smrg{ 1556b8e80941Smrg int count, img; 1557b8e80941Smrg GLuint *indexes; 1558b8e80941Smrg GLfloat *rgba, *dstPtr; 1559b8e80941Smrg 1560b8e80941Smrg count = srcWidth * srcHeight; 1561b8e80941Smrg indexes = malloc(count * sizeof(GLuint)); 1562b8e80941Smrg if (!indexes) { 1563b8e80941Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); 1564b8e80941Smrg return NULL; 1565b8e80941Smrg } 1566b8e80941Smrg 1567b8e80941Smrg rgba = malloc(4 * count * srcDepth * sizeof(GLfloat)); 1568b8e80941Smrg if (!rgba) { 1569b8e80941Smrg free(indexes); 1570b8e80941Smrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); 1571b8e80941Smrg return NULL; 1572b8e80941Smrg } 1573b8e80941Smrg 1574b8e80941Smrg /* Convert indexes to RGBA float */ 1575b8e80941Smrg dstPtr = rgba; 1576b8e80941Smrg for (img = 0; img < srcDepth; img++) { 1577b8e80941Smrg const GLubyte *srcPtr = 1578b8e80941Smrg (const GLubyte *) _mesa_image_address(dims, srcPacking, src, 1579b8e80941Smrg srcWidth, srcHeight, 1580b8e80941Smrg srcFormat, srcType, 1581b8e80941Smrg img, 0, 0); 1582b8e80941Smrg 1583b8e80941Smrg extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking); 1584b8e80941Smrg 1585b8e80941Smrg if (transferOps & IMAGE_SHIFT_OFFSET_BIT) 1586b8e80941Smrg _mesa_shift_and_offset_ci(ctx, count, indexes); 1587b8e80941Smrg 1588b8e80941Smrg _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr); 1589848b8605Smrg 1590b8e80941Smrg /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting 1591b8e80941Smrg * with color indexes. 1592b8e80941Smrg */ 1593b8e80941Smrg transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); 1594b8e80941Smrg _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr); 1595b8e80941Smrg 1596b8e80941Smrg dstPtr += srcHeight * srcWidth * 4; 1597b8e80941Smrg } 1598b8e80941Smrg 1599b8e80941Smrg free(indexes); 1600b8e80941Smrg 1601b8e80941Smrg return rgba; 1602b8e80941Smrg} 1603b8e80941Smrg 1604b8e80941SmrgGLubyte * 1605b8e80941Smrg_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims, 1606b8e80941Smrg const void *src, GLenum srcFormat, GLenum srcType, 1607b8e80941Smrg int srcWidth, int srcHeight, int srcDepth, 1608b8e80941Smrg const struct gl_pixelstore_attrib *srcPacking, 1609b8e80941Smrg GLbitfield transferOps) 1610b8e80941Smrg{ 1611b8e80941Smrg GLfloat *rgba; 1612b8e80941Smrg GLubyte *dst; 1613b8e80941Smrg int count, i; 1614b8e80941Smrg 1615b8e80941Smrg transferOps |= IMAGE_CLAMP_BIT; 1616b8e80941Smrg rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims, 1617b8e80941Smrg src, srcFormat, srcType, 1618b8e80941Smrg srcWidth, srcHeight, srcDepth, 1619b8e80941Smrg srcPacking, transferOps); 1620b8e80941Smrg 1621b8e80941Smrg count = srcWidth * srcHeight * srcDepth; 1622b8e80941Smrg dst = malloc(count * 4 * sizeof(GLubyte)); 1623b8e80941Smrg for (i = 0; i < count; i++) { 1624b8e80941Smrg CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]); 1625b8e80941Smrg CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]); 1626b8e80941Smrg CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]); 1627b8e80941Smrg CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]); 1628b8e80941Smrg } 1629b8e80941Smrg 1630b8e80941Smrg free(rgba); 1631b8e80941Smrg 1632b8e80941Smrg return dst; 1633b8e80941Smrg} 1634