1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file pixel.c 28848b8605Smrg * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer) 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg#include "glheader.h" 32848b8605Smrg#include "bufferobj.h" 33848b8605Smrg#include "context.h" 34848b8605Smrg#include "macros.h" 35848b8605Smrg#include "pixel.h" 36848b8605Smrg#include "pbo.h" 37848b8605Smrg#include "mtypes.h" 38848b8605Smrg 39848b8605Smrg 40848b8605Smrg/**********************************************************************/ 41848b8605Smrg/***** glPixelZoom *****/ 42848b8605Smrg/**********************************************************************/ 43848b8605Smrg 44848b8605Smrgvoid GLAPIENTRY 45848b8605Smrg_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ) 46848b8605Smrg{ 47848b8605Smrg GET_CURRENT_CONTEXT(ctx); 48848b8605Smrg 49848b8605Smrg if (ctx->Pixel.ZoomX == xfactor && 50848b8605Smrg ctx->Pixel.ZoomY == yfactor) 51848b8605Smrg return; 52848b8605Smrg 53848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 54848b8605Smrg ctx->Pixel.ZoomX = xfactor; 55848b8605Smrg ctx->Pixel.ZoomY = yfactor; 56848b8605Smrg} 57848b8605Smrg 58848b8605Smrg 59848b8605Smrg 60848b8605Smrg/**********************************************************************/ 61848b8605Smrg/***** glPixelMap *****/ 62848b8605Smrg/**********************************************************************/ 63848b8605Smrg 64848b8605Smrg/** 65848b8605Smrg * Return pointer to a pixelmap by name. 66848b8605Smrg */ 67848b8605Smrgstatic struct gl_pixelmap * 68848b8605Smrgget_pixelmap(struct gl_context *ctx, GLenum map) 69848b8605Smrg{ 70848b8605Smrg switch (map) { 71848b8605Smrg case GL_PIXEL_MAP_I_TO_I: 72848b8605Smrg return &ctx->PixelMaps.ItoI; 73848b8605Smrg case GL_PIXEL_MAP_S_TO_S: 74848b8605Smrg return &ctx->PixelMaps.StoS; 75848b8605Smrg case GL_PIXEL_MAP_I_TO_R: 76848b8605Smrg return &ctx->PixelMaps.ItoR; 77848b8605Smrg case GL_PIXEL_MAP_I_TO_G: 78848b8605Smrg return &ctx->PixelMaps.ItoG; 79848b8605Smrg case GL_PIXEL_MAP_I_TO_B: 80848b8605Smrg return &ctx->PixelMaps.ItoB; 81848b8605Smrg case GL_PIXEL_MAP_I_TO_A: 82848b8605Smrg return &ctx->PixelMaps.ItoA; 83848b8605Smrg case GL_PIXEL_MAP_R_TO_R: 84848b8605Smrg return &ctx->PixelMaps.RtoR; 85848b8605Smrg case GL_PIXEL_MAP_G_TO_G: 86848b8605Smrg return &ctx->PixelMaps.GtoG; 87848b8605Smrg case GL_PIXEL_MAP_B_TO_B: 88848b8605Smrg return &ctx->PixelMaps.BtoB; 89848b8605Smrg case GL_PIXEL_MAP_A_TO_A: 90848b8605Smrg return &ctx->PixelMaps.AtoA; 91848b8605Smrg default: 92848b8605Smrg return NULL; 93848b8605Smrg } 94848b8605Smrg} 95848b8605Smrg 96848b8605Smrg 97848b8605Smrg/** 98848b8605Smrg * Helper routine used by the other _mesa_PixelMap() functions. 99848b8605Smrg */ 100848b8605Smrgstatic void 101848b8605Smrgstore_pixelmap(struct gl_context *ctx, GLenum map, GLsizei mapsize, 102848b8605Smrg const GLfloat *values) 103848b8605Smrg{ 104848b8605Smrg GLint i; 105848b8605Smrg struct gl_pixelmap *pm = get_pixelmap(ctx, map); 106848b8605Smrg if (!pm) { 107848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)"); 108848b8605Smrg return; 109848b8605Smrg } 110848b8605Smrg 111848b8605Smrg switch (map) { 112848b8605Smrg case GL_PIXEL_MAP_S_TO_S: 113848b8605Smrg /* special case */ 114848b8605Smrg ctx->PixelMaps.StoS.Size = mapsize; 115848b8605Smrg for (i = 0; i < mapsize; i++) { 116848b8605Smrg ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]); 117848b8605Smrg } 118848b8605Smrg break; 119848b8605Smrg case GL_PIXEL_MAP_I_TO_I: 120848b8605Smrg /* special case */ 121848b8605Smrg ctx->PixelMaps.ItoI.Size = mapsize; 122848b8605Smrg for (i = 0; i < mapsize; i++) { 123848b8605Smrg ctx->PixelMaps.ItoI.Map[i] = values[i]; 124848b8605Smrg } 125848b8605Smrg break; 126848b8605Smrg default: 127848b8605Smrg /* general case */ 128848b8605Smrg pm->Size = mapsize; 129848b8605Smrg for (i = 0; i < mapsize; i++) { 130848b8605Smrg GLfloat val = CLAMP(values[i], 0.0F, 1.0F); 131848b8605Smrg pm->Map[i] = val; 132848b8605Smrg } 133848b8605Smrg } 134848b8605Smrg} 135848b8605Smrg 136848b8605Smrg 137848b8605Smrg/** 138848b8605Smrg * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap(). 139848b8605Smrg */ 140848b8605Smrgstatic GLboolean 141848b8605Smrgvalidate_pbo_access(struct gl_context *ctx, 142848b8605Smrg struct gl_pixelstore_attrib *pack, GLsizei mapsize, 143848b8605Smrg GLenum format, GLenum type, GLsizei clientMemSize, 144848b8605Smrg const GLvoid *ptr) 145848b8605Smrg{ 146848b8605Smrg GLboolean ok; 147848b8605Smrg 148848b8605Smrg /* Note, need to use DefaultPacking and Unpack's buffer object */ 149848b8605Smrg _mesa_reference_buffer_object(ctx, 150848b8605Smrg &ctx->DefaultPacking.BufferObj, 151848b8605Smrg pack->BufferObj); 152848b8605Smrg 153848b8605Smrg ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 154848b8605Smrg format, type, clientMemSize, ptr); 155848b8605Smrg 156848b8605Smrg /* restore */ 157848b8605Smrg _mesa_reference_buffer_object(ctx, 158848b8605Smrg &ctx->DefaultPacking.BufferObj, 159848b8605Smrg ctx->Shared->NullBufferObj); 160848b8605Smrg 161848b8605Smrg if (!ok) { 162848b8605Smrg if (_mesa_is_bufferobj(pack->BufferObj)) { 163848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 164848b8605Smrg "gl[Get]PixelMap*v(out of bounds PBO access)"); 165848b8605Smrg } else { 166848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 167848b8605Smrg "glGetnPixelMap*vARB(out of bounds access:" 168848b8605Smrg " bufSize (%d) is too small)", clientMemSize); 169848b8605Smrg } 170848b8605Smrg } 171848b8605Smrg return ok; 172848b8605Smrg} 173848b8605Smrg 174848b8605Smrg 175848b8605Smrgvoid GLAPIENTRY 176848b8605Smrg_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) 177848b8605Smrg{ 178848b8605Smrg GET_CURRENT_CONTEXT(ctx); 179848b8605Smrg 180848b8605Smrg /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */ 181848b8605Smrg if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 182848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 183848b8605Smrg return; 184848b8605Smrg } 185848b8605Smrg 186848b8605Smrg if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 187848b8605Smrg /* test that mapsize is a power of two */ 188848b8605Smrg if (!_mesa_is_pow_two(mapsize)) { 189848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 190848b8605Smrg return; 191848b8605Smrg } 192848b8605Smrg } 193848b8605Smrg 194848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 195848b8605Smrg 196848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 197848b8605Smrg GL_FLOAT, INT_MAX, values)) { 198848b8605Smrg return; 199848b8605Smrg } 200848b8605Smrg 201848b8605Smrg values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 202848b8605Smrg if (!values) { 203848b8605Smrg if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 204848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 205848b8605Smrg "glPixelMapfv(PBO is mapped)"); 206848b8605Smrg } 207848b8605Smrg return; 208848b8605Smrg } 209848b8605Smrg 210848b8605Smrg store_pixelmap(ctx, map, mapsize, values); 211848b8605Smrg 212848b8605Smrg _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 213848b8605Smrg} 214848b8605Smrg 215848b8605Smrg 216848b8605Smrgvoid GLAPIENTRY 217848b8605Smrg_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) 218848b8605Smrg{ 219848b8605Smrg GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 220848b8605Smrg GET_CURRENT_CONTEXT(ctx); 221848b8605Smrg 222848b8605Smrg if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 223848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 224848b8605Smrg return; 225848b8605Smrg } 226848b8605Smrg 227848b8605Smrg if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 228848b8605Smrg /* test that mapsize is a power of two */ 229848b8605Smrg if (!_mesa_is_pow_two(mapsize)) { 230848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 231848b8605Smrg return; 232848b8605Smrg } 233848b8605Smrg } 234848b8605Smrg 235848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 236848b8605Smrg 237848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 238848b8605Smrg GL_UNSIGNED_INT, INT_MAX, values)) { 239848b8605Smrg return; 240848b8605Smrg } 241848b8605Smrg 242848b8605Smrg values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 243848b8605Smrg if (!values) { 244848b8605Smrg if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 245848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 246848b8605Smrg "glPixelMapuiv(PBO is mapped)"); 247848b8605Smrg } 248848b8605Smrg return; 249848b8605Smrg } 250848b8605Smrg 251848b8605Smrg /* convert to floats */ 252848b8605Smrg if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 253848b8605Smrg GLint i; 254848b8605Smrg for (i = 0; i < mapsize; i++) { 255848b8605Smrg fvalues[i] = (GLfloat) values[i]; 256848b8605Smrg } 257848b8605Smrg } 258848b8605Smrg else { 259848b8605Smrg GLint i; 260848b8605Smrg for (i = 0; i < mapsize; i++) { 261848b8605Smrg fvalues[i] = UINT_TO_FLOAT( values[i] ); 262848b8605Smrg } 263848b8605Smrg } 264848b8605Smrg 265848b8605Smrg _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 266848b8605Smrg 267848b8605Smrg store_pixelmap(ctx, map, mapsize, fvalues); 268848b8605Smrg} 269848b8605Smrg 270848b8605Smrg 271848b8605Smrgvoid GLAPIENTRY 272848b8605Smrg_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) 273848b8605Smrg{ 274848b8605Smrg GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 275848b8605Smrg GET_CURRENT_CONTEXT(ctx); 276848b8605Smrg 277848b8605Smrg if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 278848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 279848b8605Smrg return; 280848b8605Smrg } 281848b8605Smrg 282848b8605Smrg if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 283848b8605Smrg /* test that mapsize is a power of two */ 284848b8605Smrg if (!_mesa_is_pow_two(mapsize)) { 285b8e80941Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 286848b8605Smrg return; 287848b8605Smrg } 288848b8605Smrg } 289848b8605Smrg 290848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 291848b8605Smrg 292848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 293848b8605Smrg GL_UNSIGNED_SHORT, INT_MAX, values)) { 294848b8605Smrg return; 295848b8605Smrg } 296848b8605Smrg 297848b8605Smrg values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 298848b8605Smrg if (!values) { 299848b8605Smrg if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 300848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 301848b8605Smrg "glPixelMapusv(PBO is mapped)"); 302848b8605Smrg } 303848b8605Smrg return; 304848b8605Smrg } 305848b8605Smrg 306848b8605Smrg /* convert to floats */ 307848b8605Smrg if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 308848b8605Smrg GLint i; 309848b8605Smrg for (i = 0; i < mapsize; i++) { 310848b8605Smrg fvalues[i] = (GLfloat) values[i]; 311848b8605Smrg } 312848b8605Smrg } 313848b8605Smrg else { 314848b8605Smrg GLint i; 315848b8605Smrg for (i = 0; i < mapsize; i++) { 316848b8605Smrg fvalues[i] = USHORT_TO_FLOAT( values[i] ); 317848b8605Smrg } 318848b8605Smrg } 319848b8605Smrg 320848b8605Smrg _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 321848b8605Smrg 322848b8605Smrg store_pixelmap(ctx, map, mapsize, fvalues); 323848b8605Smrg} 324848b8605Smrg 325848b8605Smrg 326848b8605Smrgvoid GLAPIENTRY 327848b8605Smrg_mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values ) 328848b8605Smrg{ 329848b8605Smrg GET_CURRENT_CONTEXT(ctx); 330848b8605Smrg GLint mapsize, i; 331848b8605Smrg const struct gl_pixelmap *pm; 332848b8605Smrg 333848b8605Smrg pm = get_pixelmap(ctx, map); 334848b8605Smrg if (!pm) { 335848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)"); 336848b8605Smrg return; 337848b8605Smrg } 338848b8605Smrg 339848b8605Smrg mapsize = pm->Size; 340848b8605Smrg 341848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 342848b8605Smrg GL_FLOAT, bufSize, values)) { 343848b8605Smrg return; 344848b8605Smrg } 345848b8605Smrg 346848b8605Smrg values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 347848b8605Smrg if (!values) { 348848b8605Smrg if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 349848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 350848b8605Smrg "glGetPixelMapfv(PBO is mapped)"); 351848b8605Smrg } 352848b8605Smrg return; 353848b8605Smrg } 354848b8605Smrg 355848b8605Smrg if (map == GL_PIXEL_MAP_S_TO_S) { 356848b8605Smrg /* special case */ 357848b8605Smrg for (i = 0; i < mapsize; i++) { 358848b8605Smrg values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i]; 359848b8605Smrg } 360848b8605Smrg } 361848b8605Smrg else { 362848b8605Smrg memcpy(values, pm->Map, mapsize * sizeof(GLfloat)); 363848b8605Smrg } 364848b8605Smrg 365848b8605Smrg _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 366848b8605Smrg} 367848b8605Smrg 368848b8605Smrg 369848b8605Smrgvoid GLAPIENTRY 370848b8605Smrg_mesa_GetPixelMapfv( GLenum map, GLfloat *values ) 371848b8605Smrg{ 372848b8605Smrg _mesa_GetnPixelMapfvARB(map, INT_MAX, values); 373848b8605Smrg} 374848b8605Smrg 375848b8605Smrgvoid GLAPIENTRY 376848b8605Smrg_mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values ) 377848b8605Smrg{ 378848b8605Smrg GET_CURRENT_CONTEXT(ctx); 379848b8605Smrg GLint mapsize, i; 380848b8605Smrg const struct gl_pixelmap *pm; 381848b8605Smrg 382848b8605Smrg pm = get_pixelmap(ctx, map); 383848b8605Smrg if (!pm) { 384848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)"); 385848b8605Smrg return; 386848b8605Smrg } 387848b8605Smrg 388848b8605Smrg mapsize = pm->Size; 389848b8605Smrg 390848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 391848b8605Smrg GL_UNSIGNED_INT, bufSize, values)) { 392848b8605Smrg return; 393848b8605Smrg } 394848b8605Smrg 395848b8605Smrg values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 396848b8605Smrg if (!values) { 397848b8605Smrg if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 398848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 399848b8605Smrg "glGetPixelMapuiv(PBO is mapped)"); 400848b8605Smrg } 401848b8605Smrg return; 402848b8605Smrg } 403848b8605Smrg 404848b8605Smrg if (map == GL_PIXEL_MAP_S_TO_S) { 405848b8605Smrg /* special case */ 406848b8605Smrg memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); 407848b8605Smrg } 408848b8605Smrg else { 409848b8605Smrg for (i = 0; i < mapsize; i++) { 410848b8605Smrg values[i] = FLOAT_TO_UINT( pm->Map[i] ); 411848b8605Smrg } 412848b8605Smrg } 413848b8605Smrg 414848b8605Smrg _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 415848b8605Smrg} 416848b8605Smrg 417848b8605Smrg 418848b8605Smrgvoid GLAPIENTRY 419848b8605Smrg_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) 420848b8605Smrg{ 421848b8605Smrg _mesa_GetnPixelMapuivARB(map, INT_MAX, values); 422848b8605Smrg} 423848b8605Smrg 424848b8605Smrgvoid GLAPIENTRY 425848b8605Smrg_mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values ) 426848b8605Smrg{ 427848b8605Smrg GET_CURRENT_CONTEXT(ctx); 428848b8605Smrg GLint mapsize, i; 429848b8605Smrg const struct gl_pixelmap *pm; 430848b8605Smrg 431848b8605Smrg pm = get_pixelmap(ctx, map); 432848b8605Smrg if (!pm) { 433848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)"); 434848b8605Smrg return; 435848b8605Smrg } 436848b8605Smrg 437848b8605Smrg mapsize = pm->Size; 438848b8605Smrg 439848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 440848b8605Smrg GL_UNSIGNED_SHORT, bufSize, values)) { 441848b8605Smrg return; 442848b8605Smrg } 443848b8605Smrg 444848b8605Smrg values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 445848b8605Smrg if (!values) { 446848b8605Smrg if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 447848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 448848b8605Smrg "glGetPixelMapusv(PBO is mapped)"); 449848b8605Smrg } 450848b8605Smrg return; 451848b8605Smrg } 452848b8605Smrg 453848b8605Smrg switch (map) { 454848b8605Smrg /* special cases */ 455848b8605Smrg case GL_PIXEL_MAP_I_TO_I: 456848b8605Smrg for (i = 0; i < mapsize; i++) { 457b8e80941Smrg values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0F, 65535.0F); 458848b8605Smrg } 459848b8605Smrg break; 460848b8605Smrg case GL_PIXEL_MAP_S_TO_S: 461848b8605Smrg for (i = 0; i < mapsize; i++) { 462b8e80941Smrg values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0F, 65535.0F); 463848b8605Smrg } 464848b8605Smrg break; 465848b8605Smrg default: 466848b8605Smrg for (i = 0; i < mapsize; i++) { 467848b8605Smrg CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] ); 468848b8605Smrg } 469848b8605Smrg } 470848b8605Smrg 471848b8605Smrg _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 472848b8605Smrg} 473848b8605Smrg 474848b8605Smrg 475848b8605Smrgvoid GLAPIENTRY 476848b8605Smrg_mesa_GetPixelMapusv( GLenum map, GLushort *values ) 477848b8605Smrg{ 478848b8605Smrg _mesa_GetnPixelMapusvARB(map, INT_MAX, values); 479848b8605Smrg} 480848b8605Smrg 481848b8605Smrg 482848b8605Smrg/**********************************************************************/ 483848b8605Smrg/***** glPixelTransfer *****/ 484848b8605Smrg/**********************************************************************/ 485848b8605Smrg 486848b8605Smrg 487848b8605Smrg/* 488848b8605Smrg * Implements glPixelTransfer[fi] whether called immediately or from a 489848b8605Smrg * display list. 490848b8605Smrg */ 491848b8605Smrgvoid GLAPIENTRY 492848b8605Smrg_mesa_PixelTransferf( GLenum pname, GLfloat param ) 493848b8605Smrg{ 494848b8605Smrg GET_CURRENT_CONTEXT(ctx); 495848b8605Smrg 496848b8605Smrg switch (pname) { 497848b8605Smrg case GL_MAP_COLOR: 498848b8605Smrg if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE)) 499848b8605Smrg return; 500848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 501848b8605Smrg ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; 502848b8605Smrg break; 503848b8605Smrg case GL_MAP_STENCIL: 504848b8605Smrg if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE)) 505848b8605Smrg return; 506848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 507848b8605Smrg ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; 508848b8605Smrg break; 509848b8605Smrg case GL_INDEX_SHIFT: 510848b8605Smrg if (ctx->Pixel.IndexShift == (GLint) param) 511848b8605Smrg return; 512848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 513848b8605Smrg ctx->Pixel.IndexShift = (GLint) param; 514848b8605Smrg break; 515848b8605Smrg case GL_INDEX_OFFSET: 516848b8605Smrg if (ctx->Pixel.IndexOffset == (GLint) param) 517848b8605Smrg return; 518848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 519848b8605Smrg ctx->Pixel.IndexOffset = (GLint) param; 520848b8605Smrg break; 521848b8605Smrg case GL_RED_SCALE: 522848b8605Smrg if (ctx->Pixel.RedScale == param) 523848b8605Smrg return; 524848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 525848b8605Smrg ctx->Pixel.RedScale = param; 526848b8605Smrg break; 527848b8605Smrg case GL_RED_BIAS: 528848b8605Smrg if (ctx->Pixel.RedBias == param) 529848b8605Smrg return; 530848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 531848b8605Smrg ctx->Pixel.RedBias = param; 532848b8605Smrg break; 533848b8605Smrg case GL_GREEN_SCALE: 534848b8605Smrg if (ctx->Pixel.GreenScale == param) 535848b8605Smrg return; 536848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 537848b8605Smrg ctx->Pixel.GreenScale = param; 538848b8605Smrg break; 539848b8605Smrg case GL_GREEN_BIAS: 540848b8605Smrg if (ctx->Pixel.GreenBias == param) 541848b8605Smrg return; 542848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 543848b8605Smrg ctx->Pixel.GreenBias = param; 544848b8605Smrg break; 545848b8605Smrg case GL_BLUE_SCALE: 546848b8605Smrg if (ctx->Pixel.BlueScale == param) 547848b8605Smrg return; 548848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 549848b8605Smrg ctx->Pixel.BlueScale = param; 550848b8605Smrg break; 551848b8605Smrg case GL_BLUE_BIAS: 552848b8605Smrg if (ctx->Pixel.BlueBias == param) 553848b8605Smrg return; 554848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 555848b8605Smrg ctx->Pixel.BlueBias = param; 556848b8605Smrg break; 557848b8605Smrg case GL_ALPHA_SCALE: 558848b8605Smrg if (ctx->Pixel.AlphaScale == param) 559848b8605Smrg return; 560848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 561848b8605Smrg ctx->Pixel.AlphaScale = param; 562848b8605Smrg break; 563848b8605Smrg case GL_ALPHA_BIAS: 564848b8605Smrg if (ctx->Pixel.AlphaBias == param) 565848b8605Smrg return; 566848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 567848b8605Smrg ctx->Pixel.AlphaBias = param; 568848b8605Smrg break; 569848b8605Smrg case GL_DEPTH_SCALE: 570848b8605Smrg if (ctx->Pixel.DepthScale == param) 571848b8605Smrg return; 572848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 573848b8605Smrg ctx->Pixel.DepthScale = param; 574848b8605Smrg break; 575848b8605Smrg case GL_DEPTH_BIAS: 576848b8605Smrg if (ctx->Pixel.DepthBias == param) 577848b8605Smrg return; 578848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 579848b8605Smrg ctx->Pixel.DepthBias = param; 580848b8605Smrg break; 581848b8605Smrg default: 582848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); 583848b8605Smrg return; 584848b8605Smrg } 585848b8605Smrg} 586848b8605Smrg 587848b8605Smrg 588848b8605Smrgvoid GLAPIENTRY 589848b8605Smrg_mesa_PixelTransferi( GLenum pname, GLint param ) 590848b8605Smrg{ 591848b8605Smrg _mesa_PixelTransferf( pname, (GLfloat) param ); 592848b8605Smrg} 593848b8605Smrg 594848b8605Smrg 595848b8605Smrg 596848b8605Smrg/**********************************************************************/ 597848b8605Smrg/***** State Management *****/ 598848b8605Smrg/**********************************************************************/ 599848b8605Smrg 600b8e80941Smrg 601b8e80941Smrg/** 602b8e80941Smrg * Update mesa pixel transfer derived state to indicate which operations are 603b8e80941Smrg * enabled. 604848b8605Smrg */ 605b8e80941Smrgvoid 606b8e80941Smrg_mesa_update_pixel( struct gl_context *ctx ) 607848b8605Smrg{ 608848b8605Smrg GLuint mask = 0; 609848b8605Smrg 610848b8605Smrg if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || 611848b8605Smrg ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || 612848b8605Smrg ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || 613848b8605Smrg ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) 614848b8605Smrg mask |= IMAGE_SCALE_BIAS_BIT; 615848b8605Smrg 616848b8605Smrg if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) 617848b8605Smrg mask |= IMAGE_SHIFT_OFFSET_BIT; 618848b8605Smrg 619848b8605Smrg if (ctx->Pixel.MapColorFlag) 620848b8605Smrg mask |= IMAGE_MAP_COLOR_BIT; 621848b8605Smrg 622848b8605Smrg ctx->_ImageTransferState = mask; 623848b8605Smrg} 624848b8605Smrg 625848b8605Smrg 626848b8605Smrg/**********************************************************************/ 627848b8605Smrg/***** Initialization *****/ 628848b8605Smrg/**********************************************************************/ 629848b8605Smrg 630848b8605Smrgstatic void 631848b8605Smrginit_pixelmap(struct gl_pixelmap *map) 632848b8605Smrg{ 633848b8605Smrg map->Size = 1; 634848b8605Smrg map->Map[0] = 0.0; 635848b8605Smrg} 636848b8605Smrg 637848b8605Smrg 638848b8605Smrg/** 639848b8605Smrg * Initialize the context's PIXEL attribute group. 640848b8605Smrg */ 641848b8605Smrgvoid 642848b8605Smrg_mesa_init_pixel( struct gl_context *ctx ) 643848b8605Smrg{ 644848b8605Smrg /* Pixel group */ 645848b8605Smrg ctx->Pixel.RedBias = 0.0; 646848b8605Smrg ctx->Pixel.RedScale = 1.0; 647848b8605Smrg ctx->Pixel.GreenBias = 0.0; 648848b8605Smrg ctx->Pixel.GreenScale = 1.0; 649848b8605Smrg ctx->Pixel.BlueBias = 0.0; 650848b8605Smrg ctx->Pixel.BlueScale = 1.0; 651848b8605Smrg ctx->Pixel.AlphaBias = 0.0; 652848b8605Smrg ctx->Pixel.AlphaScale = 1.0; 653848b8605Smrg ctx->Pixel.DepthBias = 0.0; 654848b8605Smrg ctx->Pixel.DepthScale = 1.0; 655848b8605Smrg ctx->Pixel.IndexOffset = 0; 656848b8605Smrg ctx->Pixel.IndexShift = 0; 657848b8605Smrg ctx->Pixel.ZoomX = 1.0; 658848b8605Smrg ctx->Pixel.ZoomY = 1.0; 659848b8605Smrg ctx->Pixel.MapColorFlag = GL_FALSE; 660848b8605Smrg ctx->Pixel.MapStencilFlag = GL_FALSE; 661848b8605Smrg init_pixelmap(&ctx->PixelMaps.StoS); 662848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoI); 663848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoR); 664848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoG); 665848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoB); 666848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoA); 667848b8605Smrg init_pixelmap(&ctx->PixelMaps.RtoR); 668848b8605Smrg init_pixelmap(&ctx->PixelMaps.GtoG); 669848b8605Smrg init_pixelmap(&ctx->PixelMaps.BtoB); 670848b8605Smrg init_pixelmap(&ctx->PixelMaps.AtoA); 671848b8605Smrg 672848b8605Smrg if (ctx->Visual.doubleBufferMode) { 673848b8605Smrg ctx->Pixel.ReadBuffer = GL_BACK; 674848b8605Smrg } 675848b8605Smrg else { 676848b8605Smrg ctx->Pixel.ReadBuffer = GL_FRONT; 677848b8605Smrg } 678848b8605Smrg 679848b8605Smrg /* Miscellaneous */ 680848b8605Smrg ctx->_ImageTransferState = 0; 681848b8605Smrg} 682