pixel.c revision 7117f1b4
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.3 4 * 5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25#include "glheader.h" 26#include "bufferobj.h" 27#include "colormac.h" 28#include "context.h" 29#include "image.h" 30#include "macros.h" 31#include "pixel.h" 32#include "mtypes.h" 33 34 35/**********************************************************************/ 36/***** glPixelZoom *****/ 37/**********************************************************************/ 38 39 40 41void GLAPIENTRY 42_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ) 43{ 44 GET_CURRENT_CONTEXT(ctx); 45 46 if (ctx->Pixel.ZoomX == xfactor && 47 ctx->Pixel.ZoomY == yfactor) 48 return; 49 50 FLUSH_VERTICES(ctx, _NEW_PIXEL); 51 ctx->Pixel.ZoomX = xfactor; 52 ctx->Pixel.ZoomY = yfactor; 53} 54 55 56 57/**********************************************************************/ 58/***** glPixelStore *****/ 59/**********************************************************************/ 60 61 62void GLAPIENTRY 63_mesa_PixelStorei( GLenum pname, GLint param ) 64{ 65 /* NOTE: this call can't be compiled into the display list */ 66 GET_CURRENT_CONTEXT(ctx); 67 ASSERT_OUTSIDE_BEGIN_END(ctx); 68 69 switch (pname) { 70 case GL_PACK_SWAP_BYTES: 71 if (param == (GLint)ctx->Pack.SwapBytes) 72 return; 73 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 74 ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE; 75 break; 76 case GL_PACK_LSB_FIRST: 77 if (param == (GLint)ctx->Pack.LsbFirst) 78 return; 79 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 80 ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE; 81 break; 82 case GL_PACK_ROW_LENGTH: 83 if (param<0) { 84 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 85 return; 86 } 87 if (ctx->Pack.RowLength == param) 88 return; 89 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 90 ctx->Pack.RowLength = param; 91 break; 92 case GL_PACK_IMAGE_HEIGHT: 93 if (param<0) { 94 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 95 return; 96 } 97 if (ctx->Pack.ImageHeight == param) 98 return; 99 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 100 ctx->Pack.ImageHeight = param; 101 break; 102 case GL_PACK_SKIP_PIXELS: 103 if (param<0) { 104 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 105 return; 106 } 107 if (ctx->Pack.SkipPixels == param) 108 return; 109 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 110 ctx->Pack.SkipPixels = param; 111 break; 112 case GL_PACK_SKIP_ROWS: 113 if (param<0) { 114 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 115 return; 116 } 117 if (ctx->Pack.SkipRows == param) 118 return; 119 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 120 ctx->Pack.SkipRows = param; 121 break; 122 case GL_PACK_SKIP_IMAGES: 123 if (param<0) { 124 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 125 return; 126 } 127 if (ctx->Pack.SkipImages == param) 128 return; 129 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 130 ctx->Pack.SkipImages = param; 131 break; 132 case GL_PACK_ALIGNMENT: 133 if (param!=1 && param!=2 && param!=4 && param!=8) { 134 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 135 return; 136 } 137 if (ctx->Pack.Alignment == param) 138 return; 139 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 140 ctx->Pack.Alignment = param; 141 break; 142 case GL_PACK_INVERT_MESA: 143 if (!ctx->Extensions.MESA_pack_invert) { 144 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" ); 145 return; 146 } 147 if (ctx->Pack.Invert == param) 148 return; 149 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 150 ctx->Pack.Invert = param; 151 break; 152 153 case GL_UNPACK_SWAP_BYTES: 154 if (param == (GLint)ctx->Unpack.SwapBytes) 155 return; 156 if ((GLint)ctx->Unpack.SwapBytes == param) 157 return; 158 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 159 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE; 160 break; 161 case GL_UNPACK_LSB_FIRST: 162 if (param == (GLint)ctx->Unpack.LsbFirst) 163 return; 164 if ((GLint)ctx->Unpack.LsbFirst == param) 165 return; 166 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 167 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; 168 break; 169 case GL_UNPACK_ROW_LENGTH: 170 if (param<0) { 171 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 172 return; 173 } 174 if (ctx->Unpack.RowLength == param) 175 return; 176 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 177 ctx->Unpack.RowLength = param; 178 break; 179 case GL_UNPACK_IMAGE_HEIGHT: 180 if (param<0) { 181 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 182 return; 183 } 184 if (ctx->Unpack.ImageHeight == param) 185 return; 186 187 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 188 ctx->Unpack.ImageHeight = param; 189 break; 190 case GL_UNPACK_SKIP_PIXELS: 191 if (param<0) { 192 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 193 return; 194 } 195 if (ctx->Unpack.SkipPixels == param) 196 return; 197 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 198 ctx->Unpack.SkipPixels = param; 199 break; 200 case GL_UNPACK_SKIP_ROWS: 201 if (param<0) { 202 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 203 return; 204 } 205 if (ctx->Unpack.SkipRows == param) 206 return; 207 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 208 ctx->Unpack.SkipRows = param; 209 break; 210 case GL_UNPACK_SKIP_IMAGES: 211 if (param < 0) { 212 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); 213 return; 214 } 215 if (ctx->Unpack.SkipImages == param) 216 return; 217 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 218 ctx->Unpack.SkipImages = param; 219 break; 220 case GL_UNPACK_ALIGNMENT: 221 if (param!=1 && param!=2 && param!=4 && param!=8) { 222 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" ); 223 return; 224 } 225 if (ctx->Unpack.Alignment == param) 226 return; 227 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 228 ctx->Unpack.Alignment = param; 229 break; 230 case GL_UNPACK_CLIENT_STORAGE_APPLE: 231 if (param == (GLint)ctx->Unpack.ClientStorage) 232 return; 233 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); 234 ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE; 235 break; 236 default: 237 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" ); 238 return; 239 } 240} 241 242 243void GLAPIENTRY 244_mesa_PixelStoref( GLenum pname, GLfloat param ) 245{ 246 _mesa_PixelStorei( pname, (GLint) param ); 247} 248 249 250 251/**********************************************************************/ 252/***** glPixelMap *****/ 253/**********************************************************************/ 254 255/** 256 * Return pointer to a pixelmap by name. 257 */ 258static struct gl_pixelmap * 259get_pixelmap(GLcontext *ctx, GLenum map) 260{ 261 switch (map) { 262 case GL_PIXEL_MAP_I_TO_I: 263 return &ctx->PixelMaps.ItoI; 264 case GL_PIXEL_MAP_S_TO_S: 265 return &ctx->PixelMaps.StoS; 266 case GL_PIXEL_MAP_I_TO_R: 267 return &ctx->PixelMaps.ItoR; 268 case GL_PIXEL_MAP_I_TO_G: 269 return &ctx->PixelMaps.ItoG; 270 case GL_PIXEL_MAP_I_TO_B: 271 return &ctx->PixelMaps.ItoB; 272 case GL_PIXEL_MAP_I_TO_A: 273 return &ctx->PixelMaps.ItoA; 274 case GL_PIXEL_MAP_R_TO_R: 275 return &ctx->PixelMaps.RtoR; 276 case GL_PIXEL_MAP_G_TO_G: 277 return &ctx->PixelMaps.GtoG; 278 case GL_PIXEL_MAP_B_TO_B: 279 return &ctx->PixelMaps.BtoB; 280 case GL_PIXEL_MAP_A_TO_A: 281 return &ctx->PixelMaps.AtoA; 282 default: 283 return NULL; 284 } 285} 286 287 288/** 289 * Helper routine used by the other _mesa_PixelMap() functions. 290 */ 291static void 292store_pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize, 293 const GLfloat *values) 294{ 295 GLint i; 296 struct gl_pixelmap *pm = get_pixelmap(ctx, map); 297 if (!pm) { 298 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)"); 299 return; 300 } 301 302 switch (map) { 303 case GL_PIXEL_MAP_S_TO_S: 304 /* special case */ 305 ctx->PixelMaps.StoS.Size = mapsize; 306 for (i = 0; i < mapsize; i++) { 307 ctx->PixelMaps.StoS.Map[i] = IROUND(values[i]); 308 } 309 break; 310 case GL_PIXEL_MAP_I_TO_I: 311 /* special case */ 312 ctx->PixelMaps.ItoI.Size = mapsize; 313 for (i = 0; i < mapsize; i++) { 314 ctx->PixelMaps.ItoI.Map[i] = values[i]; 315 } 316 break; 317 default: 318 /* general case */ 319 pm->Size = mapsize; 320 for (i = 0; i < mapsize; i++) { 321 GLfloat val = CLAMP(values[i], 0.0F, 1.0F); 322 pm->Map[i] = val; 323 pm->Map8[i] = (GLint) (val * 255.0F); 324 } 325 } 326} 327 328 329void GLAPIENTRY 330_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) 331{ 332 GET_CURRENT_CONTEXT(ctx); 333 ASSERT_OUTSIDE_BEGIN_END(ctx); 334 335 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */ 336 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 337 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 338 return; 339 } 340 341 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 342 /* test that mapsize is a power of two */ 343 if (_mesa_bitcount((GLuint) mapsize) != 1) { 344 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 345 return; 346 } 347 } 348 349 FLUSH_VERTICES(ctx, _NEW_PIXEL); 350 351 if (ctx->Unpack.BufferObj->Name) { 352 /* unpack pixelmap from PBO */ 353 GLubyte *buf; 354 /* Note, need to use DefaultPacking and Unpack's buffer object */ 355 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj; 356 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 357 GL_INTENSITY, GL_FLOAT, values)) { 358 _mesa_error(ctx, GL_INVALID_OPERATION, 359 "glPixelMapfv(invalid PBO access)"); 360 return; 361 } 362 /* restore */ 363 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 364 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 365 GL_READ_ONLY_ARB, 366 ctx->Unpack.BufferObj); 367 if (!buf) { 368 /* buffer is already mapped - that's an error */ 369 _mesa_error(ctx, GL_INVALID_OPERATION, 370 "glPixelMapfv(PBO is mapped)"); 371 return; 372 } 373 values = (const GLfloat *) ADD_POINTERS(buf, values); 374 } 375 else if (!values) { 376 return; 377 } 378 379 store_pixelmap(ctx, map, mapsize, values); 380 381 if (ctx->Unpack.BufferObj->Name) { 382 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 383 ctx->Unpack.BufferObj); 384 } 385} 386 387 388void GLAPIENTRY 389_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) 390{ 391 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 392 GET_CURRENT_CONTEXT(ctx); 393 ASSERT_OUTSIDE_BEGIN_END(ctx); 394 395 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 396 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 397 return; 398 } 399 400 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 401 /* test that mapsize is a power of two */ 402 if (_mesa_bitcount((GLuint) mapsize) != 1) { 403 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 404 return; 405 } 406 } 407 408 FLUSH_VERTICES(ctx, _NEW_PIXEL); 409 410 if (ctx->Unpack.BufferObj->Name) { 411 /* unpack pixelmap from PBO */ 412 GLubyte *buf; 413 /* Note, need to use DefaultPacking and Unpack's buffer object */ 414 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj; 415 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 416 GL_INTENSITY, GL_UNSIGNED_INT, values)) { 417 _mesa_error(ctx, GL_INVALID_OPERATION, 418 "glPixelMapuiv(invalid PBO access)"); 419 return; 420 } 421 /* restore */ 422 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 423 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 424 GL_READ_ONLY_ARB, 425 ctx->Unpack.BufferObj); 426 if (!buf) { 427 /* buffer is already mapped - that's an error */ 428 _mesa_error(ctx, GL_INVALID_OPERATION, 429 "glPixelMapuiv(PBO is mapped)"); 430 return; 431 } 432 values = (const GLuint *) ADD_POINTERS(buf, values); 433 } 434 else if (!values) { 435 return; 436 } 437 438 /* convert to floats */ 439 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 440 GLint i; 441 for (i = 0; i < mapsize; i++) { 442 fvalues[i] = (GLfloat) values[i]; 443 } 444 } 445 else { 446 GLint i; 447 for (i = 0; i < mapsize; i++) { 448 fvalues[i] = UINT_TO_FLOAT( values[i] ); 449 } 450 } 451 452 if (ctx->Unpack.BufferObj->Name) { 453 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 454 ctx->Unpack.BufferObj); 455 } 456 457 store_pixelmap(ctx, map, mapsize, fvalues); 458} 459 460 461void GLAPIENTRY 462_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) 463{ 464 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 465 GET_CURRENT_CONTEXT(ctx); 466 ASSERT_OUTSIDE_BEGIN_END(ctx); 467 468 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 469 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 470 return; 471 } 472 473 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 474 /* test that mapsize is a power of two */ 475 if (_mesa_bitcount((GLuint) mapsize) != 1) { 476 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 477 return; 478 } 479 } 480 481 FLUSH_VERTICES(ctx, _NEW_PIXEL); 482 483 if (ctx->Unpack.BufferObj->Name) { 484 /* unpack pixelmap from PBO */ 485 GLubyte *buf; 486 /* Note, need to use DefaultPacking and Unpack's buffer object */ 487 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj; 488 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 489 GL_INTENSITY, GL_UNSIGNED_SHORT, 490 values)) { 491 _mesa_error(ctx, GL_INVALID_OPERATION, 492 "glPixelMapusv(invalid PBO access)"); 493 return; 494 } 495 /* restore */ 496 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 497 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 498 GL_READ_ONLY_ARB, 499 ctx->Unpack.BufferObj); 500 if (!buf) { 501 /* buffer is already mapped - that's an error */ 502 _mesa_error(ctx, GL_INVALID_OPERATION, 503 "glPixelMapusv(PBO is mapped)"); 504 return; 505 } 506 values = (const GLushort *) ADD_POINTERS(buf, values); 507 } 508 else if (!values) { 509 return; 510 } 511 512 /* convert to floats */ 513 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 514 GLint i; 515 for (i = 0; i < mapsize; i++) { 516 fvalues[i] = (GLfloat) values[i]; 517 } 518 } 519 else { 520 GLint i; 521 for (i = 0; i < mapsize; i++) { 522 fvalues[i] = USHORT_TO_FLOAT( values[i] ); 523 } 524 } 525 526 if (ctx->Unpack.BufferObj->Name) { 527 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 528 ctx->Unpack.BufferObj); 529 } 530 531 store_pixelmap(ctx, map, mapsize, fvalues); 532} 533 534 535void GLAPIENTRY 536_mesa_GetPixelMapfv( GLenum map, GLfloat *values ) 537{ 538 GET_CURRENT_CONTEXT(ctx); 539 GLuint mapsize, i; 540 const struct gl_pixelmap *pm; 541 542 ASSERT_OUTSIDE_BEGIN_END(ctx); 543 544 pm = get_pixelmap(ctx, map); 545 if (!pm) { 546 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)"); 547 return; 548 } 549 550 mapsize = pm->Size; 551 552 if (ctx->Pack.BufferObj->Name) { 553 /* pack pixelmap into PBO */ 554 GLubyte *buf; 555 /* Note, need to use DefaultPacking and Pack's buffer object */ 556 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj; 557 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 558 GL_INTENSITY, GL_FLOAT, values)) { 559 _mesa_error(ctx, GL_INVALID_OPERATION, 560 "glGetPixelMapfv(invalid PBO access)"); 561 return; 562 } 563 /* restore */ 564 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 565 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 566 GL_WRITE_ONLY_ARB, 567 ctx->Pack.BufferObj); 568 if (!buf) { 569 /* buffer is already mapped - that's an error */ 570 _mesa_error(ctx, GL_INVALID_OPERATION, 571 "glGetPixelMapfv(PBO is mapped)"); 572 return; 573 } 574 values = (GLfloat *) ADD_POINTERS(buf, values); 575 } 576 else if (!values) { 577 return; 578 } 579 580 if (map == GL_PIXEL_MAP_S_TO_S) { 581 /* special case */ 582 for (i = 0; i < mapsize; i++) { 583 values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i]; 584 } 585 } 586 else { 587 MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat)); 588 } 589 590 if (ctx->Pack.BufferObj->Name) { 591 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 592 ctx->Pack.BufferObj); 593 } 594} 595 596 597void GLAPIENTRY 598_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) 599{ 600 GET_CURRENT_CONTEXT(ctx); 601 GLint mapsize, i; 602 const struct gl_pixelmap *pm; 603 604 ASSERT_OUTSIDE_BEGIN_END(ctx); 605 606 pm = get_pixelmap(ctx, map); 607 if (!pm) { 608 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)"); 609 return; 610 } 611 mapsize = pm->Size; 612 613 if (ctx->Pack.BufferObj->Name) { 614 /* pack pixelmap into PBO */ 615 GLubyte *buf; 616 /* Note, need to use DefaultPacking and Pack's buffer object */ 617 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj; 618 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 619 GL_INTENSITY, GL_UNSIGNED_INT, values)) { 620 _mesa_error(ctx, GL_INVALID_OPERATION, 621 "glGetPixelMapuiv(invalid PBO access)"); 622 return; 623 } 624 /* restore */ 625 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 626 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 627 GL_WRITE_ONLY_ARB, 628 ctx->Pack.BufferObj); 629 if (!buf) { 630 /* buffer is already mapped - that's an error */ 631 _mesa_error(ctx, GL_INVALID_OPERATION, 632 "glGetPixelMapuiv(PBO is mapped)"); 633 return; 634 } 635 values = (GLuint *) ADD_POINTERS(buf, values); 636 } 637 else if (!values) { 638 return; 639 } 640 641 if (map == GL_PIXEL_MAP_S_TO_S) { 642 /* special case */ 643 MEMCPY(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); 644 } 645 else { 646 for (i = 0; i < mapsize; i++) { 647 values[i] = FLOAT_TO_UINT( pm->Map[i] ); 648 } 649 } 650 651 if (ctx->Pack.BufferObj->Name) { 652 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 653 ctx->Pack.BufferObj); 654 } 655} 656 657 658void GLAPIENTRY 659_mesa_GetPixelMapusv( GLenum map, GLushort *values ) 660{ 661 GET_CURRENT_CONTEXT(ctx); 662 GLint mapsize, i; 663 const struct gl_pixelmap *pm; 664 665 ASSERT_OUTSIDE_BEGIN_END(ctx); 666 667 pm = get_pixelmap(ctx, map); 668 if (!pm) { 669 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)"); 670 return; 671 } 672 mapsize = pm ? pm->Size : 0; 673 674 if (ctx->Pack.BufferObj->Name) { 675 /* pack pixelmap into PBO */ 676 GLubyte *buf; 677 /* Note, need to use DefaultPacking and Pack's buffer object */ 678 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj; 679 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 680 GL_INTENSITY, GL_UNSIGNED_SHORT, 681 values)) { 682 _mesa_error(ctx, GL_INVALID_OPERATION, 683 "glGetPixelMapusv(invalid PBO access)"); 684 return; 685 } 686 /* restore */ 687 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 688 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 689 GL_WRITE_ONLY_ARB, 690 ctx->Pack.BufferObj); 691 if (!buf) { 692 /* buffer is already mapped - that's an error */ 693 _mesa_error(ctx, GL_INVALID_OPERATION, 694 "glGetPixelMapusv(PBO is mapped)"); 695 return; 696 } 697 values = (GLushort *) ADD_POINTERS(buf, values); 698 } 699 else if (!values) { 700 return; 701 } 702 703 switch (map) { 704 /* special cases */ 705 case GL_PIXEL_MAP_I_TO_I: 706 for (i = 0; i < mapsize; i++) { 707 values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.); 708 } 709 break; 710 case GL_PIXEL_MAP_S_TO_S: 711 for (i = 0; i < mapsize; i++) { 712 values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.); 713 } 714 break; 715 default: 716 for (i = 0; i < mapsize; i++) { 717 CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] ); 718 } 719 } 720 721 if (ctx->Pack.BufferObj->Name) { 722 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 723 ctx->Pack.BufferObj); 724 } 725} 726 727 728 729/**********************************************************************/ 730/***** glPixelTransfer *****/ 731/**********************************************************************/ 732 733 734/* 735 * Implements glPixelTransfer[fi] whether called immediately or from a 736 * display list. 737 */ 738void GLAPIENTRY 739_mesa_PixelTransferf( GLenum pname, GLfloat param ) 740{ 741 GET_CURRENT_CONTEXT(ctx); 742 ASSERT_OUTSIDE_BEGIN_END(ctx); 743 744 switch (pname) { 745 case GL_MAP_COLOR: 746 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE)) 747 return; 748 FLUSH_VERTICES(ctx, _NEW_PIXEL); 749 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; 750 break; 751 case GL_MAP_STENCIL: 752 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE)) 753 return; 754 FLUSH_VERTICES(ctx, _NEW_PIXEL); 755 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; 756 break; 757 case GL_INDEX_SHIFT: 758 if (ctx->Pixel.IndexShift == (GLint) param) 759 return; 760 FLUSH_VERTICES(ctx, _NEW_PIXEL); 761 ctx->Pixel.IndexShift = (GLint) param; 762 break; 763 case GL_INDEX_OFFSET: 764 if (ctx->Pixel.IndexOffset == (GLint) param) 765 return; 766 FLUSH_VERTICES(ctx, _NEW_PIXEL); 767 ctx->Pixel.IndexOffset = (GLint) param; 768 break; 769 case GL_RED_SCALE: 770 if (ctx->Pixel.RedScale == param) 771 return; 772 FLUSH_VERTICES(ctx, _NEW_PIXEL); 773 ctx->Pixel.RedScale = param; 774 break; 775 case GL_RED_BIAS: 776 if (ctx->Pixel.RedBias == param) 777 return; 778 FLUSH_VERTICES(ctx, _NEW_PIXEL); 779 ctx->Pixel.RedBias = param; 780 break; 781 case GL_GREEN_SCALE: 782 if (ctx->Pixel.GreenScale == param) 783 return; 784 FLUSH_VERTICES(ctx, _NEW_PIXEL); 785 ctx->Pixel.GreenScale = param; 786 break; 787 case GL_GREEN_BIAS: 788 if (ctx->Pixel.GreenBias == param) 789 return; 790 FLUSH_VERTICES(ctx, _NEW_PIXEL); 791 ctx->Pixel.GreenBias = param; 792 break; 793 case GL_BLUE_SCALE: 794 if (ctx->Pixel.BlueScale == param) 795 return; 796 FLUSH_VERTICES(ctx, _NEW_PIXEL); 797 ctx->Pixel.BlueScale = param; 798 break; 799 case GL_BLUE_BIAS: 800 if (ctx->Pixel.BlueBias == param) 801 return; 802 FLUSH_VERTICES(ctx, _NEW_PIXEL); 803 ctx->Pixel.BlueBias = param; 804 break; 805 case GL_ALPHA_SCALE: 806 if (ctx->Pixel.AlphaScale == param) 807 return; 808 FLUSH_VERTICES(ctx, _NEW_PIXEL); 809 ctx->Pixel.AlphaScale = param; 810 break; 811 case GL_ALPHA_BIAS: 812 if (ctx->Pixel.AlphaBias == param) 813 return; 814 FLUSH_VERTICES(ctx, _NEW_PIXEL); 815 ctx->Pixel.AlphaBias = param; 816 break; 817 case GL_DEPTH_SCALE: 818 if (ctx->Pixel.DepthScale == param) 819 return; 820 FLUSH_VERTICES(ctx, _NEW_PIXEL); 821 ctx->Pixel.DepthScale = param; 822 break; 823 case GL_DEPTH_BIAS: 824 if (ctx->Pixel.DepthBias == param) 825 return; 826 FLUSH_VERTICES(ctx, _NEW_PIXEL); 827 ctx->Pixel.DepthBias = param; 828 break; 829 case GL_POST_COLOR_MATRIX_RED_SCALE: 830 if (ctx->Pixel.PostColorMatrixScale[0] == param) 831 return; 832 FLUSH_VERTICES(ctx, _NEW_PIXEL); 833 ctx->Pixel.PostColorMatrixScale[0] = param; 834 break; 835 case GL_POST_COLOR_MATRIX_RED_BIAS: 836 if (ctx->Pixel.PostColorMatrixBias[0] == param) 837 return; 838 FLUSH_VERTICES(ctx, _NEW_PIXEL); 839 ctx->Pixel.PostColorMatrixBias[0] = param; 840 break; 841 case GL_POST_COLOR_MATRIX_GREEN_SCALE: 842 if (ctx->Pixel.PostColorMatrixScale[1] == param) 843 return; 844 FLUSH_VERTICES(ctx, _NEW_PIXEL); 845 ctx->Pixel.PostColorMatrixScale[1] = param; 846 break; 847 case GL_POST_COLOR_MATRIX_GREEN_BIAS: 848 if (ctx->Pixel.PostColorMatrixBias[1] == param) 849 return; 850 FLUSH_VERTICES(ctx, _NEW_PIXEL); 851 ctx->Pixel.PostColorMatrixBias[1] = param; 852 break; 853 case GL_POST_COLOR_MATRIX_BLUE_SCALE: 854 if (ctx->Pixel.PostColorMatrixScale[2] == param) 855 return; 856 FLUSH_VERTICES(ctx, _NEW_PIXEL); 857 ctx->Pixel.PostColorMatrixScale[2] = param; 858 break; 859 case GL_POST_COLOR_MATRIX_BLUE_BIAS: 860 if (ctx->Pixel.PostColorMatrixBias[2] == param) 861 return; 862 FLUSH_VERTICES(ctx, _NEW_PIXEL); 863 ctx->Pixel.PostColorMatrixBias[2] = param; 864 break; 865 case GL_POST_COLOR_MATRIX_ALPHA_SCALE: 866 if (ctx->Pixel.PostColorMatrixScale[3] == param) 867 return; 868 FLUSH_VERTICES(ctx, _NEW_PIXEL); 869 ctx->Pixel.PostColorMatrixScale[3] = param; 870 break; 871 case GL_POST_COLOR_MATRIX_ALPHA_BIAS: 872 if (ctx->Pixel.PostColorMatrixBias[3] == param) 873 return; 874 FLUSH_VERTICES(ctx, _NEW_PIXEL); 875 ctx->Pixel.PostColorMatrixBias[3] = param; 876 break; 877 case GL_POST_CONVOLUTION_RED_SCALE: 878 if (ctx->Pixel.PostConvolutionScale[0] == param) 879 return; 880 FLUSH_VERTICES(ctx, _NEW_PIXEL); 881 ctx->Pixel.PostConvolutionScale[0] = param; 882 break; 883 case GL_POST_CONVOLUTION_RED_BIAS: 884 if (ctx->Pixel.PostConvolutionBias[0] == param) 885 return; 886 FLUSH_VERTICES(ctx, _NEW_PIXEL); 887 ctx->Pixel.PostConvolutionBias[0] = param; 888 break; 889 case GL_POST_CONVOLUTION_GREEN_SCALE: 890 if (ctx->Pixel.PostConvolutionScale[1] == param) 891 return; 892 FLUSH_VERTICES(ctx, _NEW_PIXEL); 893 ctx->Pixel.PostConvolutionScale[1] = param; 894 break; 895 case GL_POST_CONVOLUTION_GREEN_BIAS: 896 if (ctx->Pixel.PostConvolutionBias[1] == param) 897 return; 898 FLUSH_VERTICES(ctx, _NEW_PIXEL); 899 ctx->Pixel.PostConvolutionBias[1] = param; 900 break; 901 case GL_POST_CONVOLUTION_BLUE_SCALE: 902 if (ctx->Pixel.PostConvolutionScale[2] == param) 903 return; 904 FLUSH_VERTICES(ctx, _NEW_PIXEL); 905 ctx->Pixel.PostConvolutionScale[2] = param; 906 break; 907 case GL_POST_CONVOLUTION_BLUE_BIAS: 908 if (ctx->Pixel.PostConvolutionBias[2] == param) 909 return; 910 FLUSH_VERTICES(ctx, _NEW_PIXEL); 911 ctx->Pixel.PostConvolutionBias[2] = param; 912 break; 913 case GL_POST_CONVOLUTION_ALPHA_SCALE: 914 if (ctx->Pixel.PostConvolutionScale[3] == param) 915 return; 916 FLUSH_VERTICES(ctx, _NEW_PIXEL); 917 ctx->Pixel.PostConvolutionScale[3] = param; 918 break; 919 case GL_POST_CONVOLUTION_ALPHA_BIAS: 920 if (ctx->Pixel.PostConvolutionBias[3] == param) 921 return; 922 FLUSH_VERTICES(ctx, _NEW_PIXEL); 923 ctx->Pixel.PostConvolutionBias[3] = param; 924 break; 925 default: 926 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); 927 return; 928 } 929} 930 931 932void GLAPIENTRY 933_mesa_PixelTransferi( GLenum pname, GLint param ) 934{ 935 _mesa_PixelTransferf( pname, (GLfloat) param ); 936} 937 938 939 940/**********************************************************************/ 941/***** Pixel processing functions ******/ 942/**********************************************************************/ 943 944/* 945 * Apply scale and bias factors to an array of RGBA pixels. 946 */ 947void 948_mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4], 949 GLfloat rScale, GLfloat gScale, 950 GLfloat bScale, GLfloat aScale, 951 GLfloat rBias, GLfloat gBias, 952 GLfloat bBias, GLfloat aBias) 953{ 954 if (rScale != 1.0 || rBias != 0.0) { 955 GLuint i; 956 for (i = 0; i < n; i++) { 957 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias; 958 } 959 } 960 if (gScale != 1.0 || gBias != 0.0) { 961 GLuint i; 962 for (i = 0; i < n; i++) { 963 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias; 964 } 965 } 966 if (bScale != 1.0 || bBias != 0.0) { 967 GLuint i; 968 for (i = 0; i < n; i++) { 969 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias; 970 } 971 } 972 if (aScale != 1.0 || aBias != 0.0) { 973 GLuint i; 974 for (i = 0; i < n; i++) { 975 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias; 976 } 977 } 978} 979 980 981/* 982 * Apply pixel mapping to an array of floating point RGBA pixels. 983 */ 984void 985_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] ) 986{ 987 const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1); 988 const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1); 989 const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1); 990 const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1); 991 const GLfloat *rMap = ctx->PixelMaps.RtoR.Map; 992 const GLfloat *gMap = ctx->PixelMaps.GtoG.Map; 993 const GLfloat *bMap = ctx->PixelMaps.BtoB.Map; 994 const GLfloat *aMap = ctx->PixelMaps.AtoA.Map; 995 GLuint i; 996 for (i=0;i<n;i++) { 997 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 998 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 999 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 1000 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 1001 rgba[i][RCOMP] = rMap[IROUND(r * rscale)]; 1002 rgba[i][GCOMP] = gMap[IROUND(g * gscale)]; 1003 rgba[i][BCOMP] = bMap[IROUND(b * bscale)]; 1004 rgba[i][ACOMP] = aMap[IROUND(a * ascale)]; 1005 } 1006} 1007 1008 1009/* 1010 * Apply the color matrix and post color matrix scaling and biasing. 1011 */ 1012void 1013_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4]) 1014{ 1015 const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0]; 1016 const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0]; 1017 const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1]; 1018 const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1]; 1019 const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2]; 1020 const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2]; 1021 const GLfloat as = ctx->Pixel.PostColorMatrixScale[3]; 1022 const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3]; 1023 const GLfloat *m = ctx->ColorMatrixStack.Top->m; 1024 GLuint i; 1025 for (i = 0; i < n; i++) { 1026 const GLfloat r = rgba[i][RCOMP]; 1027 const GLfloat g = rgba[i][GCOMP]; 1028 const GLfloat b = rgba[i][BCOMP]; 1029 const GLfloat a = rgba[i][ACOMP]; 1030 rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb; 1031 rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb; 1032 rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb; 1033 rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab; 1034 } 1035} 1036 1037 1038/** 1039 * Apply a color table lookup to an array of floating point RGBA colors. 1040 */ 1041void 1042_mesa_lookup_rgba_float(const struct gl_color_table *table, 1043 GLuint n, GLfloat rgba[][4]) 1044{ 1045 const GLint max = table->Size - 1; 1046 const GLfloat scale = (GLfloat) max; 1047 const GLfloat *lut = table->TableF; 1048 GLuint i; 1049 1050 if (!table->TableF || table->Size == 0) 1051 return; 1052 1053 switch (table->_BaseFormat) { 1054 case GL_INTENSITY: 1055 /* replace RGBA with I */ 1056 for (i = 0; i < n; i++) { 1057 GLint j = IROUND(rgba[i][RCOMP] * scale); 1058 GLfloat c = lut[CLAMP(j, 0, max)]; 1059 rgba[i][RCOMP] = 1060 rgba[i][GCOMP] = 1061 rgba[i][BCOMP] = 1062 rgba[i][ACOMP] = c; 1063 } 1064 break; 1065 case GL_LUMINANCE: 1066 /* replace RGB with L */ 1067 for (i = 0; i < n; i++) { 1068 GLint j = IROUND(rgba[i][RCOMP] * scale); 1069 GLfloat c = lut[CLAMP(j, 0, max)]; 1070 rgba[i][RCOMP] = 1071 rgba[i][GCOMP] = 1072 rgba[i][BCOMP] = c; 1073 } 1074 break; 1075 case GL_ALPHA: 1076 /* replace A with A */ 1077 for (i = 0; i < n; i++) { 1078 GLint j = IROUND(rgba[i][ACOMP] * scale); 1079 rgba[i][ACOMP] = lut[CLAMP(j, 0, max)]; 1080 } 1081 break; 1082 case GL_LUMINANCE_ALPHA: 1083 /* replace RGBA with LLLA */ 1084 for (i = 0; i < n; i++) { 1085 GLint jL = IROUND(rgba[i][RCOMP] * scale); 1086 GLint jA = IROUND(rgba[i][ACOMP] * scale); 1087 GLfloat luminance, alpha; 1088 jL = CLAMP(jL, 0, max); 1089 jA = CLAMP(jA, 0, max); 1090 luminance = lut[jL * 2 + 0]; 1091 alpha = lut[jA * 2 + 1]; 1092 rgba[i][RCOMP] = 1093 rgba[i][GCOMP] = 1094 rgba[i][BCOMP] = luminance; 1095 rgba[i][ACOMP] = alpha;; 1096 } 1097 break; 1098 case GL_RGB: 1099 /* replace RGB with RGB */ 1100 for (i = 0; i < n; i++) { 1101 GLint jR = IROUND(rgba[i][RCOMP] * scale); 1102 GLint jG = IROUND(rgba[i][GCOMP] * scale); 1103 GLint jB = IROUND(rgba[i][BCOMP] * scale); 1104 jR = CLAMP(jR, 0, max); 1105 jG = CLAMP(jG, 0, max); 1106 jB = CLAMP(jB, 0, max); 1107 rgba[i][RCOMP] = lut[jR * 3 + 0]; 1108 rgba[i][GCOMP] = lut[jG * 3 + 1]; 1109 rgba[i][BCOMP] = lut[jB * 3 + 2]; 1110 } 1111 break; 1112 case GL_RGBA: 1113 /* replace RGBA with RGBA */ 1114 for (i = 0; i < n; i++) { 1115 GLint jR = IROUND(rgba[i][RCOMP] * scale); 1116 GLint jG = IROUND(rgba[i][GCOMP] * scale); 1117 GLint jB = IROUND(rgba[i][BCOMP] * scale); 1118 GLint jA = IROUND(rgba[i][ACOMP] * scale); 1119 jR = CLAMP(jR, 0, max); 1120 jG = CLAMP(jG, 0, max); 1121 jB = CLAMP(jB, 0, max); 1122 jA = CLAMP(jA, 0, max); 1123 rgba[i][RCOMP] = lut[jR * 4 + 0]; 1124 rgba[i][GCOMP] = lut[jG * 4 + 1]; 1125 rgba[i][BCOMP] = lut[jB * 4 + 2]; 1126 rgba[i][ACOMP] = lut[jA * 4 + 3]; 1127 } 1128 break; 1129 default: 1130 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float"); 1131 return; 1132 } 1133} 1134 1135 1136 1137/** 1138 * Apply a color table lookup to an array of ubyte/RGBA colors. 1139 */ 1140void 1141_mesa_lookup_rgba_ubyte(const struct gl_color_table *table, 1142 GLuint n, GLubyte rgba[][4]) 1143{ 1144 const GLubyte *lut = table->TableUB; 1145 const GLfloat scale = (GLfloat) (table->Size - 1) / 255.0; 1146 GLuint i; 1147 1148 if (!table->TableUB || table->Size == 0) 1149 return; 1150 1151 switch (table->_BaseFormat) { 1152 case GL_INTENSITY: 1153 /* replace RGBA with I */ 1154 if (table->Size == 256) { 1155 for (i = 0; i < n; i++) { 1156 const GLubyte c = lut[rgba[i][RCOMP]]; 1157 rgba[i][RCOMP] = 1158 rgba[i][GCOMP] = 1159 rgba[i][BCOMP] = 1160 rgba[i][ACOMP] = c; 1161 } 1162 } 1163 else { 1164 for (i = 0; i < n; i++) { 1165 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1166 rgba[i][RCOMP] = 1167 rgba[i][GCOMP] = 1168 rgba[i][BCOMP] = 1169 rgba[i][ACOMP] = lut[j]; 1170 } 1171 } 1172 break; 1173 case GL_LUMINANCE: 1174 /* replace RGB with L */ 1175 if (table->Size == 256) { 1176 for (i = 0; i < n; i++) { 1177 const GLubyte c = lut[rgba[i][RCOMP]]; 1178 rgba[i][RCOMP] = 1179 rgba[i][GCOMP] = 1180 rgba[i][BCOMP] = c; 1181 } 1182 } 1183 else { 1184 for (i = 0; i < n; i++) { 1185 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1186 rgba[i][RCOMP] = 1187 rgba[i][GCOMP] = 1188 rgba[i][BCOMP] = lut[j]; 1189 } 1190 } 1191 break; 1192 case GL_ALPHA: 1193 /* replace A with A */ 1194 if (table->Size == 256) { 1195 for (i = 0; i < n; i++) { 1196 rgba[i][ACOMP] = lut[rgba[i][ACOMP]]; 1197 } 1198 } 1199 else { 1200 for (i = 0; i < n; i++) { 1201 GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1202 rgba[i][ACOMP] = lut[j]; 1203 } 1204 } 1205 break; 1206 case GL_LUMINANCE_ALPHA: 1207 /* replace RGBA with LLLA */ 1208 if (table->Size == 256) { 1209 for (i = 0; i < n; i++) { 1210 GLubyte l = lut[rgba[i][RCOMP] * 2 + 0]; 1211 GLubyte a = lut[rgba[i][ACOMP] * 2 + 1];; 1212 rgba[i][RCOMP] = 1213 rgba[i][GCOMP] = 1214 rgba[i][BCOMP] = l; 1215 rgba[i][ACOMP] = a; 1216 } 1217 } 1218 else { 1219 for (i = 0; i < n; i++) { 1220 GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1221 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1222 GLubyte luminance = lut[jL * 2 + 0]; 1223 GLubyte alpha = lut[jA * 2 + 1]; 1224 rgba[i][RCOMP] = 1225 rgba[i][GCOMP] = 1226 rgba[i][BCOMP] = luminance; 1227 rgba[i][ACOMP] = alpha; 1228 } 1229 } 1230 break; 1231 case GL_RGB: 1232 if (table->Size == 256) { 1233 for (i = 0; i < n; i++) { 1234 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0]; 1235 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1]; 1236 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2]; 1237 } 1238 } 1239 else { 1240 for (i = 0; i < n; i++) { 1241 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1242 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale); 1243 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale); 1244 rgba[i][RCOMP] = lut[jR * 3 + 0]; 1245 rgba[i][GCOMP] = lut[jG * 3 + 1]; 1246 rgba[i][BCOMP] = lut[jB * 3 + 2]; 1247 } 1248 } 1249 break; 1250 case GL_RGBA: 1251 if (table->Size == 256) { 1252 for (i = 0; i < n; i++) { 1253 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0]; 1254 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1]; 1255 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2]; 1256 rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3]; 1257 } 1258 } 1259 else { 1260 for (i = 0; i < n; i++) { 1261 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1262 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale); 1263 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale); 1264 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1265 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]); 1266 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]); 1267 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]); 1268 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]); 1269 } 1270 } 1271 break; 1272 default: 1273 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan"); 1274 return; 1275 } 1276} 1277 1278 1279 1280/* 1281 * Map color indexes to float rgba values. 1282 */ 1283void 1284_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n, 1285 const GLuint index[], GLfloat rgba[][4] ) 1286{ 1287 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1; 1288 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1; 1289 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1; 1290 GLuint amask = ctx->PixelMaps.ItoA.Size - 1; 1291 const GLfloat *rMap = ctx->PixelMaps.ItoR.Map; 1292 const GLfloat *gMap = ctx->PixelMaps.ItoG.Map; 1293 const GLfloat *bMap = ctx->PixelMaps.ItoB.Map; 1294 const GLfloat *aMap = ctx->PixelMaps.ItoA.Map; 1295 GLuint i; 1296 for (i=0;i<n;i++) { 1297 rgba[i][RCOMP] = rMap[index[i] & rmask]; 1298 rgba[i][GCOMP] = gMap[index[i] & gmask]; 1299 rgba[i][BCOMP] = bMap[index[i] & bmask]; 1300 rgba[i][ACOMP] = aMap[index[i] & amask]; 1301 } 1302} 1303 1304 1305/** 1306 * Map ubyte color indexes to ubyte/RGBA values. 1307 */ 1308void 1309_mesa_map_ci8_to_rgba8(const GLcontext *ctx, GLuint n, const GLubyte index[], 1310 GLubyte rgba[][4]) 1311{ 1312 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1; 1313 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1; 1314 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1; 1315 GLuint amask = ctx->PixelMaps.ItoA.Size - 1; 1316 const GLubyte *rMap = ctx->PixelMaps.ItoR.Map8; 1317 const GLubyte *gMap = ctx->PixelMaps.ItoG.Map8; 1318 const GLubyte *bMap = ctx->PixelMaps.ItoB.Map8; 1319 const GLubyte *aMap = ctx->PixelMaps.ItoA.Map8; 1320 GLuint i; 1321 for (i=0;i<n;i++) { 1322 rgba[i][RCOMP] = rMap[index[i] & rmask]; 1323 rgba[i][GCOMP] = gMap[index[i] & gmask]; 1324 rgba[i][BCOMP] = bMap[index[i] & bmask]; 1325 rgba[i][ACOMP] = aMap[index[i] & amask]; 1326 } 1327} 1328 1329 1330void 1331_mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n, 1332 GLfloat depthValues[]) 1333{ 1334 const GLfloat scale = ctx->Pixel.DepthScale; 1335 const GLfloat bias = ctx->Pixel.DepthBias; 1336 GLuint i; 1337 for (i = 0; i < n; i++) { 1338 GLfloat d = depthValues[i] * scale + bias; 1339 depthValues[i] = CLAMP(d, 0.0F, 1.0F); 1340 } 1341} 1342 1343 1344 1345/**********************************************************************/ 1346/***** State Management *****/ 1347/**********************************************************************/ 1348 1349/* 1350 * Return a bitmask of IMAGE_*_BIT flags which to indicate which 1351 * pixel transfer operations are enabled. 1352 */ 1353static void 1354update_image_transfer_state(GLcontext *ctx) 1355{ 1356 GLuint mask = 0; 1357 1358 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || 1359 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || 1360 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || 1361 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) 1362 mask |= IMAGE_SCALE_BIAS_BIT; 1363 1364 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) 1365 mask |= IMAGE_SHIFT_OFFSET_BIT; 1366 1367 if (ctx->Pixel.MapColorFlag) 1368 mask |= IMAGE_MAP_COLOR_BIT; 1369 1370 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION]) 1371 mask |= IMAGE_COLOR_TABLE_BIT; 1372 1373 if (ctx->Pixel.Convolution1DEnabled || 1374 ctx->Pixel.Convolution2DEnabled || 1375 ctx->Pixel.Separable2DEnabled) { 1376 mask |= IMAGE_CONVOLUTION_BIT; 1377 if (ctx->Pixel.PostConvolutionScale[0] != 1.0F || 1378 ctx->Pixel.PostConvolutionScale[1] != 1.0F || 1379 ctx->Pixel.PostConvolutionScale[2] != 1.0F || 1380 ctx->Pixel.PostConvolutionScale[3] != 1.0F || 1381 ctx->Pixel.PostConvolutionBias[0] != 0.0F || 1382 ctx->Pixel.PostConvolutionBias[1] != 0.0F || 1383 ctx->Pixel.PostConvolutionBias[2] != 0.0F || 1384 ctx->Pixel.PostConvolutionBias[3] != 0.0F) { 1385 mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS; 1386 } 1387 } 1388 1389 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION]) 1390 mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT; 1391 1392 if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY || 1393 ctx->Pixel.PostColorMatrixScale[0] != 1.0F || 1394 ctx->Pixel.PostColorMatrixBias[0] != 0.0F || 1395 ctx->Pixel.PostColorMatrixScale[1] != 1.0F || 1396 ctx->Pixel.PostColorMatrixBias[1] != 0.0F || 1397 ctx->Pixel.PostColorMatrixScale[2] != 1.0F || 1398 ctx->Pixel.PostColorMatrixBias[2] != 0.0F || 1399 ctx->Pixel.PostColorMatrixScale[3] != 1.0F || 1400 ctx->Pixel.PostColorMatrixBias[3] != 0.0F) 1401 mask |= IMAGE_COLOR_MATRIX_BIT; 1402 1403 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX]) 1404 mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT; 1405 1406 if (ctx->Pixel.HistogramEnabled) 1407 mask |= IMAGE_HISTOGRAM_BIT; 1408 1409 if (ctx->Pixel.MinMaxEnabled) 1410 mask |= IMAGE_MIN_MAX_BIT; 1411 1412 ctx->_ImageTransferState = mask; 1413} 1414 1415 1416void _mesa_update_pixel( GLcontext *ctx, GLuint new_state ) 1417{ 1418 if (new_state & _NEW_COLOR_MATRIX) 1419 _math_matrix_analyse( ctx->ColorMatrixStack.Top ); 1420 1421 /* References ColorMatrix.type (derived above). 1422 */ 1423 if (new_state & _IMAGE_NEW_TRANSFER_STATE) 1424 update_image_transfer_state(ctx); 1425} 1426 1427 1428/**********************************************************************/ 1429/***** Initialization *****/ 1430/**********************************************************************/ 1431 1432static void 1433init_pixelmap(struct gl_pixelmap *map) 1434{ 1435 map->Size = 1; 1436 map->Map[0] = 0.0; 1437 map->Map8[0] = 0; 1438} 1439 1440 1441/** 1442 * Initialize the context's PIXEL attribute group. 1443 */ 1444void 1445_mesa_init_pixel( GLcontext *ctx ) 1446{ 1447 int i; 1448 1449 /* Pixel group */ 1450 ctx->Pixel.RedBias = 0.0; 1451 ctx->Pixel.RedScale = 1.0; 1452 ctx->Pixel.GreenBias = 0.0; 1453 ctx->Pixel.GreenScale = 1.0; 1454 ctx->Pixel.BlueBias = 0.0; 1455 ctx->Pixel.BlueScale = 1.0; 1456 ctx->Pixel.AlphaBias = 0.0; 1457 ctx->Pixel.AlphaScale = 1.0; 1458 ctx->Pixel.DepthBias = 0.0; 1459 ctx->Pixel.DepthScale = 1.0; 1460 ctx->Pixel.IndexOffset = 0; 1461 ctx->Pixel.IndexShift = 0; 1462 ctx->Pixel.ZoomX = 1.0; 1463 ctx->Pixel.ZoomY = 1.0; 1464 ctx->Pixel.MapColorFlag = GL_FALSE; 1465 ctx->Pixel.MapStencilFlag = GL_FALSE; 1466 init_pixelmap(&ctx->PixelMaps.StoS); 1467 init_pixelmap(&ctx->PixelMaps.ItoI); 1468 init_pixelmap(&ctx->PixelMaps.ItoR); 1469 init_pixelmap(&ctx->PixelMaps.ItoG); 1470 init_pixelmap(&ctx->PixelMaps.ItoB); 1471 init_pixelmap(&ctx->PixelMaps.ItoA); 1472 init_pixelmap(&ctx->PixelMaps.RtoR); 1473 init_pixelmap(&ctx->PixelMaps.GtoG); 1474 init_pixelmap(&ctx->PixelMaps.BtoB); 1475 init_pixelmap(&ctx->PixelMaps.AtoA); 1476 ctx->Pixel.HistogramEnabled = GL_FALSE; 1477 ctx->Pixel.MinMaxEnabled = GL_FALSE; 1478 ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0); 1479 ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0); 1480 for (i = 0; i < COLORTABLE_MAX; i++) { 1481 ASSIGN_4V(ctx->Pixel.ColorTableScale[i], 1.0, 1.0, 1.0, 1.0); 1482 ASSIGN_4V(ctx->Pixel.ColorTableBias[i], 0.0, 0.0, 0.0, 0.0); 1483 ctx->Pixel.ColorTableEnabled[i] = GL_FALSE; 1484 } 1485 ctx->Pixel.Convolution1DEnabled = GL_FALSE; 1486 ctx->Pixel.Convolution2DEnabled = GL_FALSE; 1487 ctx->Pixel.Separable2DEnabled = GL_FALSE; 1488 for (i = 0; i < 3; i++) { 1489 ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0); 1490 ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE; 1491 ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0); 1492 ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0); 1493 } 1494 for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) { 1495 ctx->Convolution1D.Filter[i] = 0.0; 1496 ctx->Convolution2D.Filter[i] = 0.0; 1497 ctx->Separable2D.Filter[i] = 0.0; 1498 } 1499 ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0); 1500 ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0); 1501 /* GL_SGI_texture_color_table */ 1502 ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0); 1503 ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0); 1504 1505 /* Pixel transfer */ 1506 ctx->Pack.Alignment = 4; 1507 ctx->Pack.RowLength = 0; 1508 ctx->Pack.ImageHeight = 0; 1509 ctx->Pack.SkipPixels = 0; 1510 ctx->Pack.SkipRows = 0; 1511 ctx->Pack.SkipImages = 0; 1512 ctx->Pack.SwapBytes = GL_FALSE; 1513 ctx->Pack.LsbFirst = GL_FALSE; 1514 ctx->Pack.ClientStorage = GL_FALSE; 1515 ctx->Pack.Invert = GL_FALSE; 1516#if FEATURE_EXT_pixel_buffer_object 1517 ctx->Pack.BufferObj = ctx->Array.NullBufferObj; 1518#endif 1519 ctx->Unpack.Alignment = 4; 1520 ctx->Unpack.RowLength = 0; 1521 ctx->Unpack.ImageHeight = 0; 1522 ctx->Unpack.SkipPixels = 0; 1523 ctx->Unpack.SkipRows = 0; 1524 ctx->Unpack.SkipImages = 0; 1525 ctx->Unpack.SwapBytes = GL_FALSE; 1526 ctx->Unpack.LsbFirst = GL_FALSE; 1527 ctx->Unpack.ClientStorage = GL_FALSE; 1528 ctx->Unpack.Invert = GL_FALSE; 1529#if FEATURE_EXT_pixel_buffer_object 1530 ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; 1531#endif 1532 1533 /* 1534 * _mesa_unpack_image() returns image data in this format. When we 1535 * execute image commands (glDrawPixels(), glTexImage(), etc) from 1536 * within display lists we have to be sure to set the current 1537 * unpacking parameters to these values! 1538 */ 1539 ctx->DefaultPacking.Alignment = 1; 1540 ctx->DefaultPacking.RowLength = 0; 1541 ctx->DefaultPacking.SkipPixels = 0; 1542 ctx->DefaultPacking.SkipRows = 0; 1543 ctx->DefaultPacking.ImageHeight = 0; 1544 ctx->DefaultPacking.SkipImages = 0; 1545 ctx->DefaultPacking.SwapBytes = GL_FALSE; 1546 ctx->DefaultPacking.LsbFirst = GL_FALSE; 1547 ctx->DefaultPacking.ClientStorage = GL_FALSE; 1548 ctx->DefaultPacking.Invert = GL_FALSE; 1549#if FEATURE_EXT_pixel_buffer_object 1550 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 1551#endif 1552 1553 if (ctx->Visual.doubleBufferMode) { 1554 ctx->Pixel.ReadBuffer = GL_BACK; 1555 } 1556 else { 1557 ctx->Pixel.ReadBuffer = GL_FRONT; 1558 } 1559 1560 /* Miscellaneous */ 1561 ctx->_ImageTransferState = 0; 1562} 1563