pixel.c revision 331cc1dcba8705116288e487f43f460852c2159f
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.3 4 * 5 * Copyright (C) 1999-2004 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/** 257 * Helper routine used by the other _mesa_PixelMap() functions. 258 */ 259static void 260pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize, const GLfloat *values) 261{ 262 GLint i; 263 switch (map) { 264 case GL_PIXEL_MAP_S_TO_S: 265 ctx->Pixel.MapStoSsize = mapsize; 266 for (i = 0; i < mapsize; i++) { 267 ctx->Pixel.MapStoS[i] = (GLint) values[i]; 268 } 269 break; 270 case GL_PIXEL_MAP_I_TO_I: 271 ctx->Pixel.MapItoIsize = mapsize; 272 for (i = 0; i < mapsize; i++) { 273 ctx->Pixel.MapItoI[i] = (GLint) values[i]; 274 } 275 break; 276 case GL_PIXEL_MAP_I_TO_R: 277 ctx->Pixel.MapItoRsize = mapsize; 278 for (i = 0; i < mapsize; i++) { 279 GLfloat val = CLAMP( values[i], 0.0F, 1.0F ); 280 ctx->Pixel.MapItoR[i] = val; 281 ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F); 282 } 283 break; 284 case GL_PIXEL_MAP_I_TO_G: 285 ctx->Pixel.MapItoGsize = mapsize; 286 for (i = 0; i < mapsize; i++) { 287 GLfloat val = CLAMP( values[i], 0.0F, 1.0F ); 288 ctx->Pixel.MapItoG[i] = val; 289 ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F); 290 } 291 break; 292 case GL_PIXEL_MAP_I_TO_B: 293 ctx->Pixel.MapItoBsize = mapsize; 294 for (i = 0; i < mapsize; i++) { 295 GLfloat val = CLAMP( values[i], 0.0F, 1.0F ); 296 ctx->Pixel.MapItoB[i] = val; 297 ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F); 298 } 299 break; 300 case GL_PIXEL_MAP_I_TO_A: 301 ctx->Pixel.MapItoAsize = mapsize; 302 for (i = 0; i < mapsize; i++) { 303 GLfloat val = CLAMP( values[i], 0.0F, 1.0F ); 304 ctx->Pixel.MapItoA[i] = val; 305 ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F); 306 } 307 break; 308 case GL_PIXEL_MAP_R_TO_R: 309 ctx->Pixel.MapRtoRsize = mapsize; 310 for (i = 0; i < mapsize; i++) { 311 ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0F, 1.0F ); 312 } 313 break; 314 case GL_PIXEL_MAP_G_TO_G: 315 ctx->Pixel.MapGtoGsize = mapsize; 316 for (i = 0; i < mapsize; i++) { 317 ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0F, 1.0F ); 318 } 319 break; 320 case GL_PIXEL_MAP_B_TO_B: 321 ctx->Pixel.MapBtoBsize = mapsize; 322 for (i = 0; i < mapsize; i++) { 323 ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0F, 1.0F ); 324 } 325 break; 326 case GL_PIXEL_MAP_A_TO_A: 327 ctx->Pixel.MapAtoAsize = mapsize; 328 for (i = 0; i < mapsize; i++) { 329 ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0F, 1.0F ); 330 } 331 break; 332 default: 333 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMap(map)" ); 334 } 335} 336 337 338void GLAPIENTRY 339_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) 340{ 341 GET_CURRENT_CONTEXT(ctx); 342 ASSERT_OUTSIDE_BEGIN_END(ctx); 343 344 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */ 345 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 346 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 347 return; 348 } 349 350 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 351 /* test that mapsize is a power of two */ 352 if (_mesa_bitcount((GLuint) mapsize) != 1) { 353 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 354 return; 355 } 356 } 357 358 FLUSH_VERTICES(ctx, _NEW_PIXEL); 359 360 if (ctx->Unpack.BufferObj->Name) { 361 /* unpack pixelmap from PBO */ 362 GLubyte *buf; 363 /* Note, need to use DefaultPacking and Unpack's buffer object */ 364 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj; 365 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1, 366 GL_INTENSITY, GL_FLOAT, values)) { 367 _mesa_error(ctx, GL_INVALID_OPERATION, 368 "glPixelMapfv(invalid PBO access)"); 369 return; 370 } 371 /* restore */ 372 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 373 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 374 GL_READ_ONLY_ARB, 375 ctx->Unpack.BufferObj); 376 if (!buf) { 377 /* buffer is already mapped - that's an error */ 378 _mesa_error(ctx, GL_INVALID_OPERATION, 379 "glPixelMapfv(PBO is mapped)"); 380 return; 381 } 382 values = (const GLfloat *) ADD_POINTERS(buf, values); 383 } 384 else if (!values) { 385 return; 386 } 387 388 pixelmap(ctx, map, mapsize, values); 389 390 if (ctx->Unpack.BufferObj->Name) { 391 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 392 ctx->Unpack.BufferObj); 393 } 394} 395 396 397 398void GLAPIENTRY 399_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) 400{ 401 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 402 GET_CURRENT_CONTEXT(ctx); 403 ASSERT_OUTSIDE_BEGIN_END(ctx); 404 405 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 406 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 407 return; 408 } 409 410 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 411 /* test that mapsize is a power of two */ 412 if (_mesa_bitcount((GLuint) mapsize) != 1) { 413 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 414 return; 415 } 416 } 417 418 FLUSH_VERTICES(ctx, _NEW_PIXEL); 419 420 if (ctx->Unpack.BufferObj->Name) { 421 /* unpack pixelmap from PBO */ 422 GLubyte *buf; 423 /* Note, need to use DefaultPacking and Unpack's buffer object */ 424 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj; 425 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1, 426 GL_INTENSITY, GL_UNSIGNED_INT, values)) { 427 _mesa_error(ctx, GL_INVALID_OPERATION, 428 "glPixelMapuiv(invalid PBO access)"); 429 return; 430 } 431 /* restore */ 432 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 433 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 434 GL_READ_ONLY_ARB, 435 ctx->Unpack.BufferObj); 436 if (!buf) { 437 /* buffer is already mapped - that's an error */ 438 _mesa_error(ctx, GL_INVALID_OPERATION, 439 "glPixelMapuiv(PBO is mapped)"); 440 return; 441 } 442 values = (const GLuint *) ADD_POINTERS(buf, values); 443 } 444 else if (!values) { 445 return; 446 } 447 448 /* convert to floats */ 449 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 450 GLint i; 451 for (i = 0; i < mapsize; i++) { 452 fvalues[i] = (GLfloat) values[i]; 453 } 454 } 455 else { 456 GLint i; 457 for (i = 0; i < mapsize; i++) { 458 fvalues[i] = UINT_TO_FLOAT( values[i] ); 459 } 460 } 461 462 if (ctx->Unpack.BufferObj->Name) { 463 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 464 ctx->Unpack.BufferObj); 465 } 466 467 pixelmap(ctx, map, mapsize, fvalues); 468} 469 470 471 472void GLAPIENTRY 473_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) 474{ 475 GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 476 GET_CURRENT_CONTEXT(ctx); 477 ASSERT_OUTSIDE_BEGIN_END(ctx); 478 479 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 480 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 481 return; 482 } 483 484 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 485 /* test that mapsize is a power of two */ 486 if (_mesa_bitcount((GLuint) mapsize) != 1) { 487 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 488 return; 489 } 490 } 491 492 FLUSH_VERTICES(ctx, _NEW_PIXEL); 493 494 if (ctx->Unpack.BufferObj->Name) { 495 /* unpack pixelmap from PBO */ 496 GLubyte *buf; 497 /* Note, need to use DefaultPacking and Unpack's buffer object */ 498 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj; 499 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1, 500 GL_INTENSITY, GL_UNSIGNED_SHORT, 501 values)) { 502 _mesa_error(ctx, GL_INVALID_OPERATION, 503 "glPixelMapusv(invalid PBO access)"); 504 return; 505 } 506 /* restore */ 507 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 508 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 509 GL_READ_ONLY_ARB, 510 ctx->Unpack.BufferObj); 511 if (!buf) { 512 /* buffer is already mapped - that's an error */ 513 _mesa_error(ctx, GL_INVALID_OPERATION, 514 "glPixelMapusv(PBO is mapped)"); 515 return; 516 } 517 values = (const GLushort *) ADD_POINTERS(buf, values); 518 } 519 else if (!values) { 520 return; 521 } 522 523 /* convert to floats */ 524 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 525 GLint i; 526 for (i = 0; i < mapsize; i++) { 527 fvalues[i] = (GLfloat) values[i]; 528 } 529 } 530 else { 531 GLint i; 532 for (i = 0; i < mapsize; i++) { 533 fvalues[i] = USHORT_TO_FLOAT( values[i] ); 534 } 535 } 536 537 if (ctx->Unpack.BufferObj->Name) { 538 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 539 ctx->Unpack.BufferObj); 540 } 541 542 pixelmap(ctx, map, mapsize, fvalues); 543} 544 545 546/** 547 * Return size of the named map. 548 */ 549static GLuint 550get_map_size(GLcontext *ctx, GLenum map) 551{ 552 switch (map) { 553 case GL_PIXEL_MAP_I_TO_I: 554 return ctx->Pixel.MapItoIsize; 555 case GL_PIXEL_MAP_S_TO_S: 556 return ctx->Pixel.MapStoSsize; 557 case GL_PIXEL_MAP_I_TO_R: 558 return ctx->Pixel.MapItoRsize; 559 case GL_PIXEL_MAP_I_TO_G: 560 return ctx->Pixel.MapItoGsize; 561 case GL_PIXEL_MAP_I_TO_B: 562 return ctx->Pixel.MapItoBsize; 563 case GL_PIXEL_MAP_I_TO_A: 564 return ctx->Pixel.MapItoAsize; 565 case GL_PIXEL_MAP_R_TO_R: 566 return ctx->Pixel.MapRtoRsize; 567 case GL_PIXEL_MAP_G_TO_G: 568 return ctx->Pixel.MapGtoGsize; 569 case GL_PIXEL_MAP_B_TO_B: 570 return ctx->Pixel.MapBtoBsize; 571 case GL_PIXEL_MAP_A_TO_A: 572 return ctx->Pixel.MapAtoAsize; 573 default: 574 return 0; 575 } 576} 577 578 579void GLAPIENTRY 580_mesa_GetPixelMapfv( GLenum map, GLfloat *values ) 581{ 582 GET_CURRENT_CONTEXT(ctx); 583 GLuint mapsize, i; 584 ASSERT_OUTSIDE_BEGIN_END(ctx); 585 586 mapsize = get_map_size(ctx, map); 587 588 if (ctx->Pack.BufferObj->Name) { 589 /* pack pixelmap into PBO */ 590 GLubyte *buf; 591 /* Note, need to use DefaultPacking and Pack's buffer object */ 592 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj; 593 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1, 594 GL_INTENSITY, GL_FLOAT, values)) { 595 _mesa_error(ctx, GL_INVALID_OPERATION, 596 "glGetPixelMapfv(invalid PBO access)"); 597 return; 598 } 599 /* restore */ 600 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 601 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 602 GL_WRITE_ONLY_ARB, 603 ctx->Pack.BufferObj); 604 if (!buf) { 605 /* buffer is already mapped - that's an error */ 606 _mesa_error(ctx, GL_INVALID_OPERATION, 607 "glGetPixelMapfv(PBO is mapped)"); 608 return; 609 } 610 values = (GLfloat *) ADD_POINTERS(buf, values); 611 } 612 else if (!values) { 613 return; 614 } 615 616 switch (map) { 617 case GL_PIXEL_MAP_I_TO_I: 618 for (i = 0; i < mapsize; i++) { 619 values[i] = (GLfloat) ctx->Pixel.MapItoI[i]; 620 } 621 break; 622 case GL_PIXEL_MAP_S_TO_S: 623 for (i = 0; i < mapsize; i++) { 624 values[i] = (GLfloat) ctx->Pixel.MapStoS[i]; 625 } 626 break; 627 case GL_PIXEL_MAP_I_TO_R: 628 MEMCPY(values, ctx->Pixel.MapItoR, mapsize * sizeof(GLfloat)); 629 break; 630 case GL_PIXEL_MAP_I_TO_G: 631 MEMCPY(values, ctx->Pixel.MapItoG, mapsize * sizeof(GLfloat)); 632 break; 633 case GL_PIXEL_MAP_I_TO_B: 634 MEMCPY(values, ctx->Pixel.MapItoB, mapsize * sizeof(GLfloat)); 635 break; 636 case GL_PIXEL_MAP_I_TO_A: 637 MEMCPY(values, ctx->Pixel.MapItoA, mapsize * sizeof(GLfloat)); 638 break; 639 case GL_PIXEL_MAP_R_TO_R: 640 MEMCPY(values, ctx->Pixel.MapRtoR, mapsize * sizeof(GLfloat)); 641 break; 642 case GL_PIXEL_MAP_G_TO_G: 643 MEMCPY(values, ctx->Pixel.MapGtoG, mapsize * sizeof(GLfloat)); 644 break; 645 case GL_PIXEL_MAP_B_TO_B: 646 MEMCPY(values, ctx->Pixel.MapBtoB, mapsize * sizeof(GLfloat)); 647 break; 648 case GL_PIXEL_MAP_A_TO_A: 649 MEMCPY(values, ctx->Pixel.MapAtoA, mapsize * sizeof(GLfloat)); 650 break; 651 default: 652 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" ); 653 } 654 655 if (ctx->Pack.BufferObj->Name) { 656 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 657 ctx->Pack.BufferObj); 658 } 659} 660 661 662void GLAPIENTRY 663_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) 664{ 665 GET_CURRENT_CONTEXT(ctx); 666 GLint mapsize, i; 667 ASSERT_OUTSIDE_BEGIN_END(ctx); 668 669 mapsize = get_map_size(ctx, map); 670 671 if (ctx->Pack.BufferObj->Name) { 672 /* pack pixelmap into PBO */ 673 GLubyte *buf; 674 /* Note, need to use DefaultPacking and Pack's buffer object */ 675 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj; 676 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1, 677 GL_INTENSITY, GL_UNSIGNED_INT, values)) { 678 _mesa_error(ctx, GL_INVALID_OPERATION, 679 "glGetPixelMapuiv(invalid PBO access)"); 680 return; 681 } 682 /* restore */ 683 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 684 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 685 GL_WRITE_ONLY_ARB, 686 ctx->Pack.BufferObj); 687 if (!buf) { 688 /* buffer is already mapped - that's an error */ 689 _mesa_error(ctx, GL_INVALID_OPERATION, 690 "glGetPixelMapuiv(PBO is mapped)"); 691 return; 692 } 693 values = (GLuint *) ADD_POINTERS(buf, values); 694 } 695 else if (!values) { 696 return; 697 } 698 699 switch (map) { 700 case GL_PIXEL_MAP_I_TO_I: 701 MEMCPY(values, ctx->Pixel.MapItoI, mapsize * sizeof(GLint)); 702 break; 703 case GL_PIXEL_MAP_S_TO_S: 704 MEMCPY(values, ctx->Pixel.MapStoS, mapsize * sizeof(GLint)); 705 break; 706 case GL_PIXEL_MAP_I_TO_R: 707 for (i = 0; i < mapsize; i++) { 708 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] ); 709 } 710 break; 711 case GL_PIXEL_MAP_I_TO_G: 712 for (i = 0; i < mapsize; i++) { 713 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] ); 714 } 715 break; 716 case GL_PIXEL_MAP_I_TO_B: 717 for (i = 0; i < mapsize; i++) { 718 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] ); 719 } 720 break; 721 case GL_PIXEL_MAP_I_TO_A: 722 for (i = 0; i < mapsize; i++) { 723 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] ); 724 } 725 break; 726 case GL_PIXEL_MAP_R_TO_R: 727 for (i = 0; i < mapsize; i++) { 728 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] ); 729 } 730 break; 731 case GL_PIXEL_MAP_G_TO_G: 732 for (i = 0; i < mapsize; i++) { 733 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] ); 734 } 735 break; 736 case GL_PIXEL_MAP_B_TO_B: 737 for (i = 0; i < mapsize; i++) { 738 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] ); 739 } 740 break; 741 case GL_PIXEL_MAP_A_TO_A: 742 for (i = 0; i < mapsize; i++) { 743 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] ); 744 } 745 break; 746 default: 747 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" ); 748 } 749 750 if (ctx->Pack.BufferObj->Name) { 751 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 752 ctx->Pack.BufferObj); 753 } 754} 755 756 757void GLAPIENTRY 758_mesa_GetPixelMapusv( GLenum map, GLushort *values ) 759{ 760 GET_CURRENT_CONTEXT(ctx); 761 GLint mapsize, i; 762 ASSERT_OUTSIDE_BEGIN_END(ctx); 763 764 mapsize = get_map_size(ctx, map); 765 766 if (ctx->Pack.BufferObj->Name) { 767 /* pack pixelmap into PBO */ 768 GLubyte *buf; 769 /* Note, need to use DefaultPacking and Pack's buffer object */ 770 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj; 771 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1, 772 GL_INTENSITY, GL_UNSIGNED_SHORT, 773 values)) { 774 _mesa_error(ctx, GL_INVALID_OPERATION, 775 "glGetPixelMapusv(invalid PBO access)"); 776 return; 777 } 778 /* restore */ 779 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 780 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 781 GL_WRITE_ONLY_ARB, 782 ctx->Pack.BufferObj); 783 if (!buf) { 784 /* buffer is already mapped - that's an error */ 785 _mesa_error(ctx, GL_INVALID_OPERATION, 786 "glGetPixelMapusv(PBO is mapped)"); 787 return; 788 } 789 values = (GLushort *) ADD_POINTERS(buf, values); 790 } 791 else if (!values) { 792 return; 793 } 794 795 switch (map) { 796 case GL_PIXEL_MAP_I_TO_I: 797 for (i = 0; i < mapsize; i++) { 798 values[i] = (GLushort) ctx->Pixel.MapItoI[i]; 799 } 800 break; 801 case GL_PIXEL_MAP_S_TO_S: 802 for (i = 0; i < mapsize; i++) { 803 values[i] = (GLushort) ctx->Pixel.MapStoS[i]; 804 } 805 break; 806 case GL_PIXEL_MAP_I_TO_R: 807 for (i = 0; i < mapsize; i++) { 808 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] ); 809 } 810 break; 811 case GL_PIXEL_MAP_I_TO_G: 812 for (i = 0; i < mapsize; i++) { 813 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] ); 814 } 815 break; 816 case GL_PIXEL_MAP_I_TO_B: 817 for (i = 0; i < mapsize; i++) { 818 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] ); 819 } 820 break; 821 case GL_PIXEL_MAP_I_TO_A: 822 for (i = 0; i < mapsize; i++) { 823 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] ); 824 } 825 break; 826 case GL_PIXEL_MAP_R_TO_R: 827 for (i = 0; i < mapsize; i++) { 828 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] ); 829 } 830 break; 831 case GL_PIXEL_MAP_G_TO_G: 832 for (i = 0; i < mapsize; i++) { 833 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] ); 834 } 835 break; 836 case GL_PIXEL_MAP_B_TO_B: 837 for (i = 0; i < mapsize; i++) { 838 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] ); 839 } 840 break; 841 case GL_PIXEL_MAP_A_TO_A: 842 for (i = 0; i < mapsize; i++) { 843 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] ); 844 } 845 break; 846 default: 847 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" ); 848 } 849 850 if (ctx->Pack.BufferObj->Name) { 851 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 852 ctx->Pack.BufferObj); 853 } 854} 855 856 857 858/**********************************************************************/ 859/***** glPixelTransfer *****/ 860/**********************************************************************/ 861 862 863/* 864 * Implements glPixelTransfer[fi] whether called immediately or from a 865 * display list. 866 */ 867void GLAPIENTRY 868_mesa_PixelTransferf( GLenum pname, GLfloat param ) 869{ 870 GET_CURRENT_CONTEXT(ctx); 871 ASSERT_OUTSIDE_BEGIN_END(ctx); 872 873 switch (pname) { 874 case GL_MAP_COLOR: 875 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE)) 876 return; 877 FLUSH_VERTICES(ctx, _NEW_PIXEL); 878 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; 879 break; 880 case GL_MAP_STENCIL: 881 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE)) 882 return; 883 FLUSH_VERTICES(ctx, _NEW_PIXEL); 884 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; 885 break; 886 case GL_INDEX_SHIFT: 887 if (ctx->Pixel.IndexShift == (GLint) param) 888 return; 889 FLUSH_VERTICES(ctx, _NEW_PIXEL); 890 ctx->Pixel.IndexShift = (GLint) param; 891 break; 892 case GL_INDEX_OFFSET: 893 if (ctx->Pixel.IndexOffset == (GLint) param) 894 return; 895 FLUSH_VERTICES(ctx, _NEW_PIXEL); 896 ctx->Pixel.IndexOffset = (GLint) param; 897 break; 898 case GL_RED_SCALE: 899 if (ctx->Pixel.RedScale == param) 900 return; 901 FLUSH_VERTICES(ctx, _NEW_PIXEL); 902 ctx->Pixel.RedScale = param; 903 break; 904 case GL_RED_BIAS: 905 if (ctx->Pixel.RedBias == param) 906 return; 907 FLUSH_VERTICES(ctx, _NEW_PIXEL); 908 ctx->Pixel.RedBias = param; 909 break; 910 case GL_GREEN_SCALE: 911 if (ctx->Pixel.GreenScale == param) 912 return; 913 FLUSH_VERTICES(ctx, _NEW_PIXEL); 914 ctx->Pixel.GreenScale = param; 915 break; 916 case GL_GREEN_BIAS: 917 if (ctx->Pixel.GreenBias == param) 918 return; 919 FLUSH_VERTICES(ctx, _NEW_PIXEL); 920 ctx->Pixel.GreenBias = param; 921 break; 922 case GL_BLUE_SCALE: 923 if (ctx->Pixel.BlueScale == param) 924 return; 925 FLUSH_VERTICES(ctx, _NEW_PIXEL); 926 ctx->Pixel.BlueScale = param; 927 break; 928 case GL_BLUE_BIAS: 929 if (ctx->Pixel.BlueBias == param) 930 return; 931 FLUSH_VERTICES(ctx, _NEW_PIXEL); 932 ctx->Pixel.BlueBias = param; 933 break; 934 case GL_ALPHA_SCALE: 935 if (ctx->Pixel.AlphaScale == param) 936 return; 937 FLUSH_VERTICES(ctx, _NEW_PIXEL); 938 ctx->Pixel.AlphaScale = param; 939 break; 940 case GL_ALPHA_BIAS: 941 if (ctx->Pixel.AlphaBias == param) 942 return; 943 FLUSH_VERTICES(ctx, _NEW_PIXEL); 944 ctx->Pixel.AlphaBias = param; 945 break; 946 case GL_DEPTH_SCALE: 947 if (ctx->Pixel.DepthScale == param) 948 return; 949 FLUSH_VERTICES(ctx, _NEW_PIXEL); 950 ctx->Pixel.DepthScale = param; 951 break; 952 case GL_DEPTH_BIAS: 953 if (ctx->Pixel.DepthBias == param) 954 return; 955 FLUSH_VERTICES(ctx, _NEW_PIXEL); 956 ctx->Pixel.DepthBias = param; 957 break; 958 case GL_POST_COLOR_MATRIX_RED_SCALE: 959 if (ctx->Pixel.PostColorMatrixScale[0] == param) 960 return; 961 FLUSH_VERTICES(ctx, _NEW_PIXEL); 962 ctx->Pixel.PostColorMatrixScale[0] = param; 963 break; 964 case GL_POST_COLOR_MATRIX_RED_BIAS: 965 if (ctx->Pixel.PostColorMatrixBias[0] == param) 966 return; 967 FLUSH_VERTICES(ctx, _NEW_PIXEL); 968 ctx->Pixel.PostColorMatrixBias[0] = param; 969 break; 970 case GL_POST_COLOR_MATRIX_GREEN_SCALE: 971 if (ctx->Pixel.PostColorMatrixScale[1] == param) 972 return; 973 FLUSH_VERTICES(ctx, _NEW_PIXEL); 974 ctx->Pixel.PostColorMatrixScale[1] = param; 975 break; 976 case GL_POST_COLOR_MATRIX_GREEN_BIAS: 977 if (ctx->Pixel.PostColorMatrixBias[1] == param) 978 return; 979 FLUSH_VERTICES(ctx, _NEW_PIXEL); 980 ctx->Pixel.PostColorMatrixBias[1] = param; 981 break; 982 case GL_POST_COLOR_MATRIX_BLUE_SCALE: 983 if (ctx->Pixel.PostColorMatrixScale[2] == param) 984 return; 985 FLUSH_VERTICES(ctx, _NEW_PIXEL); 986 ctx->Pixel.PostColorMatrixScale[2] = param; 987 break; 988 case GL_POST_COLOR_MATRIX_BLUE_BIAS: 989 if (ctx->Pixel.PostColorMatrixBias[2] == param) 990 return; 991 FLUSH_VERTICES(ctx, _NEW_PIXEL); 992 ctx->Pixel.PostColorMatrixBias[2] = param; 993 break; 994 case GL_POST_COLOR_MATRIX_ALPHA_SCALE: 995 if (ctx->Pixel.PostColorMatrixScale[3] == param) 996 return; 997 FLUSH_VERTICES(ctx, _NEW_PIXEL); 998 ctx->Pixel.PostColorMatrixScale[3] = param; 999 break; 1000 case GL_POST_COLOR_MATRIX_ALPHA_BIAS: 1001 if (ctx->Pixel.PostColorMatrixBias[3] == param) 1002 return; 1003 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1004 ctx->Pixel.PostColorMatrixBias[3] = param; 1005 break; 1006 case GL_POST_CONVOLUTION_RED_SCALE: 1007 if (ctx->Pixel.PostConvolutionScale[0] == param) 1008 return; 1009 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1010 ctx->Pixel.PostConvolutionScale[0] = param; 1011 break; 1012 case GL_POST_CONVOLUTION_RED_BIAS: 1013 if (ctx->Pixel.PostConvolutionBias[0] == param) 1014 return; 1015 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1016 ctx->Pixel.PostConvolutionBias[0] = param; 1017 break; 1018 case GL_POST_CONVOLUTION_GREEN_SCALE: 1019 if (ctx->Pixel.PostConvolutionScale[1] == param) 1020 return; 1021 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1022 ctx->Pixel.PostConvolutionScale[1] = param; 1023 break; 1024 case GL_POST_CONVOLUTION_GREEN_BIAS: 1025 if (ctx->Pixel.PostConvolutionBias[1] == param) 1026 return; 1027 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1028 ctx->Pixel.PostConvolutionBias[1] = param; 1029 break; 1030 case GL_POST_CONVOLUTION_BLUE_SCALE: 1031 if (ctx->Pixel.PostConvolutionScale[2] == param) 1032 return; 1033 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1034 ctx->Pixel.PostConvolutionScale[2] = param; 1035 break; 1036 case GL_POST_CONVOLUTION_BLUE_BIAS: 1037 if (ctx->Pixel.PostConvolutionBias[2] == param) 1038 return; 1039 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1040 ctx->Pixel.PostConvolutionBias[2] = param; 1041 break; 1042 case GL_POST_CONVOLUTION_ALPHA_SCALE: 1043 if (ctx->Pixel.PostConvolutionScale[2] == param) 1044 return; 1045 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1046 ctx->Pixel.PostConvolutionScale[2] = param; 1047 break; 1048 case GL_POST_CONVOLUTION_ALPHA_BIAS: 1049 if (ctx->Pixel.PostConvolutionBias[2] == param) 1050 return; 1051 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1052 ctx->Pixel.PostConvolutionBias[2] = param; 1053 break; 1054 default: 1055 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); 1056 return; 1057 } 1058} 1059 1060 1061void GLAPIENTRY 1062_mesa_PixelTransferi( GLenum pname, GLint param ) 1063{ 1064 _mesa_PixelTransferf( pname, (GLfloat) param ); 1065} 1066 1067 1068 1069/**********************************************************************/ 1070/***** Pixel processing functions ******/ 1071/**********************************************************************/ 1072 1073/* 1074 * Apply scale and bias factors to an array of RGBA pixels. 1075 */ 1076void 1077_mesa_scale_and_bias_rgba(GLcontext *ctx, GLuint n, GLfloat rgba[][4], 1078 GLfloat rScale, GLfloat gScale, 1079 GLfloat bScale, GLfloat aScale, 1080 GLfloat rBias, GLfloat gBias, 1081 GLfloat bBias, GLfloat aBias) 1082{ 1083 (void) ctx; 1084 1085 if (rScale != 1.0 || rBias != 0.0) { 1086 GLuint i; 1087 for (i = 0; i < n; i++) { 1088 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias; 1089 } 1090 } 1091 if (gScale != 1.0 || gBias != 0.0) { 1092 GLuint i; 1093 for (i = 0; i < n; i++) { 1094 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias; 1095 } 1096 } 1097 if (bScale != 1.0 || bBias != 0.0) { 1098 GLuint i; 1099 for (i = 0; i < n; i++) { 1100 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias; 1101 } 1102 } 1103 if (aScale != 1.0 || aBias != 0.0) { 1104 GLuint i; 1105 for (i = 0; i < n; i++) { 1106 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias; 1107 } 1108 } 1109} 1110 1111 1112/* 1113 * Apply pixel mapping to an array of floating point RGBA pixels. 1114 */ 1115void 1116_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] ) 1117{ 1118 const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1); 1119 const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1); 1120 const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1); 1121 const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1); 1122 const GLfloat *rMap = ctx->Pixel.MapRtoR; 1123 const GLfloat *gMap = ctx->Pixel.MapGtoG; 1124 const GLfloat *bMap = ctx->Pixel.MapBtoB; 1125 const GLfloat *aMap = ctx->Pixel.MapAtoA; 1126 GLuint i; 1127 for (i=0;i<n;i++) { 1128 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); 1129 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); 1130 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); 1131 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); 1132 rgba[i][RCOMP] = rMap[IROUND(r * rscale)]; 1133 rgba[i][GCOMP] = gMap[IROUND(g * gscale)]; 1134 rgba[i][BCOMP] = bMap[IROUND(b * bscale)]; 1135 rgba[i][ACOMP] = aMap[IROUND(a * ascale)]; 1136 } 1137} 1138 1139 1140/* 1141 * Apply the color matrix and post color matrix scaling and biasing. 1142 */ 1143void 1144_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4]) 1145{ 1146 const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0]; 1147 const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0]; 1148 const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1]; 1149 const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1]; 1150 const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2]; 1151 const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2]; 1152 const GLfloat as = ctx->Pixel.PostColorMatrixScale[3]; 1153 const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3]; 1154 const GLfloat *m = ctx->ColorMatrixStack.Top->m; 1155 GLuint i; 1156 for (i = 0; i < n; i++) { 1157 const GLfloat r = rgba[i][RCOMP]; 1158 const GLfloat g = rgba[i][GCOMP]; 1159 const GLfloat b = rgba[i][BCOMP]; 1160 const GLfloat a = rgba[i][ACOMP]; 1161 rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb; 1162 rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb; 1163 rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb; 1164 rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab; 1165 } 1166} 1167 1168 1169/** 1170 * Apply a color table lookup to an array of floating point RGBA colors. 1171 */ 1172void 1173_mesa_lookup_rgba_float(const struct gl_color_table *table, 1174 GLuint n, GLfloat rgba[][4]) 1175{ 1176 if (!table->Table || table->Size == 0) 1177 return; 1178 1179 switch (table->Format) { 1180 case GL_INTENSITY: 1181 /* replace RGBA with I */ 1182 if (table->Type == GL_FLOAT) { 1183 const GLint max = table->Size - 1; 1184 const GLfloat scale = (GLfloat) max; 1185 const GLfloat *lut = (const GLfloat *) table->Table; 1186 GLuint i; 1187 for (i = 0; i < n; i++) { 1188 GLint j = IROUND(rgba[i][RCOMP] * scale); 1189 GLfloat c = lut[CLAMP(j, 0, max)]; 1190 rgba[i][RCOMP] = rgba[i][GCOMP] = 1191 rgba[i][BCOMP] = rgba[i][ACOMP] = c; 1192 } 1193 } 1194 else { 1195 const GLint max = table->Size - 1; 1196 const GLfloat scale = (GLfloat) max; 1197 const GLchan *lut = (const GLchan *) table->Table; 1198 GLuint i; 1199 for (i = 0; i < n; i++) { 1200 GLint j = IROUND(rgba[i][RCOMP] * scale); 1201 GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]); 1202 rgba[i][RCOMP] = rgba[i][GCOMP] = 1203 rgba[i][BCOMP] = rgba[i][ACOMP] = c; 1204 } 1205 } 1206 break; 1207 case GL_LUMINANCE: 1208 /* replace RGB with L */ 1209 if (table->Type == GL_FLOAT) { 1210 const GLint max = table->Size - 1; 1211 const GLfloat scale = (GLfloat) max; 1212 const GLfloat *lut = (const GLfloat *) table->Table; 1213 GLuint i; 1214 for (i = 0; i < n; i++) { 1215 GLint j = IROUND(rgba[i][RCOMP] * scale); 1216 GLfloat c = lut[CLAMP(j, 0, max)]; 1217 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c; 1218 } 1219 } 1220 else { 1221 const GLint max = table->Size - 1; 1222 const GLfloat scale = (GLfloat) max; 1223 const GLchan *lut = (const GLchan *) table->Table; 1224 GLuint i; 1225 for (i = 0; i < n; i++) { 1226 GLint j = IROUND(rgba[i][RCOMP] * scale); 1227 GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]); 1228 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c; 1229 } 1230 } 1231 break; 1232 case GL_ALPHA: 1233 /* replace A with A */ 1234 if (table->Type == GL_FLOAT) { 1235 const GLint max = table->Size - 1; 1236 const GLfloat scale = (GLfloat) max; 1237 const GLfloat *lut = (const GLfloat *) table->Table; 1238 GLuint i; 1239 for (i = 0; i < n; i++) { 1240 GLint j = IROUND(rgba[i][ACOMP] * scale); 1241 rgba[i][ACOMP] = lut[CLAMP(j, 0, max)]; 1242 } 1243 } 1244 else { 1245 const GLint max = table->Size - 1; 1246 const GLfloat scale = (GLfloat) max; 1247 const GLchan *lut = (const GLchan *) table->Table; 1248 GLuint i; 1249 for (i = 0; i < n; i++) { 1250 GLint j = IROUND(rgba[i][ACOMP] * scale); 1251 rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]); 1252 } 1253 } 1254 break; 1255 case GL_LUMINANCE_ALPHA: 1256 /* replace RGBA with LLLA */ 1257 if (table->Type == GL_FLOAT) { 1258 const GLint max = table->Size - 1; 1259 const GLfloat scale = (GLfloat) max; 1260 const GLfloat *lut = (const GLfloat *) table->Table; 1261 GLuint i; 1262 for (i = 0; i < n; i++) { 1263 GLint jL = IROUND(rgba[i][RCOMP] * scale); 1264 GLint jA = IROUND(rgba[i][ACOMP] * scale); 1265 GLfloat luminance, alpha; 1266 jL = CLAMP(jL, 0, max); 1267 jA = CLAMP(jA, 0, max); 1268 luminance = lut[jL * 2 + 0]; 1269 alpha = lut[jA * 2 + 1]; 1270 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance; 1271 rgba[i][ACOMP] = alpha;; 1272 } 1273 } 1274 else { 1275 const GLint max = table->Size - 1; 1276 const GLfloat scale = (GLfloat) max; 1277 const GLchan *lut = (const GLchan *) table->Table; 1278 GLuint i; 1279 for (i = 0; i < n; i++) { 1280 GLint jL = IROUND(rgba[i][RCOMP] * scale); 1281 GLint jA = IROUND(rgba[i][ACOMP] * scale); 1282 GLfloat luminance, alpha; 1283 jL = CLAMP(jL, 0, max); 1284 jA = CLAMP(jA, 0, max); 1285 luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]); 1286 alpha = CHAN_TO_FLOAT(lut[jA * 2 + 1]); 1287 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance; 1288 rgba[i][ACOMP] = alpha;; 1289 } 1290 } 1291 break; 1292 case GL_RGB: 1293 /* replace RGB with RGB */ 1294 if (table->Type == GL_FLOAT) { 1295 const GLint max = table->Size - 1; 1296 const GLfloat scale = (GLfloat) max; 1297 const GLfloat *lut = (const GLfloat *) table->Table; 1298 GLuint i; 1299 for (i = 0; i < n; i++) { 1300 GLint jR = IROUND(rgba[i][RCOMP] * scale); 1301 GLint jG = IROUND(rgba[i][GCOMP] * scale); 1302 GLint jB = IROUND(rgba[i][BCOMP] * scale); 1303 jR = CLAMP(jR, 0, max); 1304 jG = CLAMP(jG, 0, max); 1305 jB = CLAMP(jB, 0, max); 1306 rgba[i][RCOMP] = lut[jR * 3 + 0]; 1307 rgba[i][GCOMP] = lut[jG * 3 + 1]; 1308 rgba[i][BCOMP] = lut[jB * 3 + 2]; 1309 } 1310 } 1311 else { 1312 const GLint max = table->Size - 1; 1313 const GLfloat scale = (GLfloat) max; 1314 const GLchan *lut = (const GLchan *) table->Table; 1315 GLuint i; 1316 for (i = 0; i < n; i++) { 1317 GLint jR = IROUND(rgba[i][RCOMP] * scale); 1318 GLint jG = IROUND(rgba[i][GCOMP] * scale); 1319 GLint jB = IROUND(rgba[i][BCOMP] * scale); 1320 jR = CLAMP(jR, 0, max); 1321 jG = CLAMP(jG, 0, max); 1322 jB = CLAMP(jB, 0, max); 1323 rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]); 1324 rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]); 1325 rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]); 1326 } 1327 } 1328 break; 1329 case GL_RGBA: 1330 /* replace RGBA with RGBA */ 1331 if (table->Type == GL_FLOAT) { 1332 const GLint max = table->Size - 1; 1333 const GLfloat scale = (GLfloat) max; 1334 const GLfloat *lut = (const GLfloat *) table->Table; 1335 GLuint i; 1336 for (i = 0; i < n; i++) { 1337 GLint jR = IROUND(rgba[i][RCOMP] * scale); 1338 GLint jG = IROUND(rgba[i][GCOMP] * scale); 1339 GLint jB = IROUND(rgba[i][BCOMP] * scale); 1340 GLint jA = IROUND(rgba[i][ACOMP] * scale); 1341 jR = CLAMP(jR, 0, max); 1342 jG = CLAMP(jG, 0, max); 1343 jB = CLAMP(jB, 0, max); 1344 jA = CLAMP(jA, 0, max); 1345 rgba[i][RCOMP] = lut[jR * 4 + 0]; 1346 rgba[i][GCOMP] = lut[jG * 4 + 1]; 1347 rgba[i][BCOMP] = lut[jB * 4 + 2]; 1348 rgba[i][ACOMP] = lut[jA * 4 + 3]; 1349 } 1350 } 1351 else { 1352 const GLint max = table->Size - 1; 1353 const GLfloat scale = (GLfloat) max; 1354 const GLchan *lut = (const GLchan *) table->Table; 1355 GLuint i; 1356 for (i = 0; i < n; i++) { 1357 GLint jR = IROUND(rgba[i][RCOMP] * scale); 1358 GLint jG = IROUND(rgba[i][GCOMP] * scale); 1359 GLint jB = IROUND(rgba[i][BCOMP] * scale); 1360 GLint jA = IROUND(rgba[i][ACOMP] * scale); 1361 jR = CLAMP(jR, 0, max); 1362 jG = CLAMP(jG, 0, max); 1363 jB = CLAMP(jB, 0, max); 1364 jA = CLAMP(jA, 0, max); 1365 rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]); 1366 rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]); 1367 rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]); 1368 rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]); 1369 } 1370 } 1371 break; 1372 default: 1373 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float"); 1374 return; 1375 } 1376} 1377 1378 1379 1380/** 1381 * Apply a color table lookup to an array of GLchan RGBA colors. 1382 */ 1383void 1384_mesa_lookup_rgba_chan(const struct gl_color_table *table, 1385 GLuint n, GLchan rgba[][4]) 1386{ 1387 if (!table->Table || table->Size == 0) 1388 return; 1389 1390 switch (table->Format) { 1391 case GL_INTENSITY: 1392 /* replace RGBA with I */ 1393 if (table->Type == GL_FLOAT) { 1394 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1395 const GLfloat *lut = (const GLfloat *) table->Table; 1396 GLuint i; 1397 for (i = 0; i < n; i++) { 1398 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1399 GLchan c; 1400 CLAMPED_FLOAT_TO_CHAN(c, lut[j]); 1401 rgba[i][RCOMP] = rgba[i][GCOMP] = 1402 rgba[i][BCOMP] = rgba[i][ACOMP] = c; 1403 } 1404 } 1405 else { 1406#if CHAN_TYPE == GL_UNSIGNED_BYTE 1407 if (table->Size == 256) { 1408 /* common case */ 1409 const GLchan *lut = (const GLchan *) table->Table; 1410 GLuint i; 1411 for (i = 0; i < n; i++) { 1412 const GLchan c = lut[rgba[i][RCOMP]]; 1413 rgba[i][RCOMP] = rgba[i][GCOMP] = 1414 rgba[i][BCOMP] = rgba[i][ACOMP] = c; 1415 } 1416 } 1417 else 1418#endif 1419 { 1420 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1421 const GLchan *lut = (const GLchan *) table->Table; 1422 GLuint i; 1423 for (i = 0; i < n; i++) { 1424 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1425 rgba[i][RCOMP] = rgba[i][GCOMP] = 1426 rgba[i][BCOMP] = rgba[i][ACOMP] = lut[j]; 1427 } 1428 } 1429 } 1430 break; 1431 case GL_LUMINANCE: 1432 /* replace RGB with L */ 1433 if (table->Type == GL_FLOAT) { 1434 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1435 const GLfloat *lut = (const GLfloat *) table->Table; 1436 GLuint i; 1437 for (i = 0; i < n; i++) { 1438 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1439 GLchan c; 1440 CLAMPED_FLOAT_TO_CHAN(c, lut[j]); 1441 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c; 1442 } 1443 } 1444 else { 1445#if CHAN_TYPE == GL_UNSIGNED_BYTE 1446 if (table->Size == 256) { 1447 /* common case */ 1448 const GLchan *lut = (const GLchan *) table->Table; 1449 GLuint i; 1450 for (i = 0; i < n; i++) { 1451 const GLchan c = lut[rgba[i][RCOMP]]; 1452 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c; 1453 } 1454 } 1455 else 1456#endif 1457 { 1458 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1459 const GLchan *lut = (const GLchan *) table->Table; 1460 GLuint i; 1461 for (i = 0; i < n; i++) { 1462 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1463 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = lut[j]; 1464 } 1465 } 1466 } 1467 break; 1468 case GL_ALPHA: 1469 /* replace A with A */ 1470 if (table->Type == GL_FLOAT) { 1471 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1472 const GLfloat *lut = (const GLfloat *) table->Table; 1473 GLuint i; 1474 for (i = 0; i < n; i++) { 1475 GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1476 GLchan c; 1477 CLAMPED_FLOAT_TO_CHAN(c, lut[j]); 1478 rgba[i][ACOMP] = c; 1479 } 1480 } 1481 else { 1482#if CHAN_TYPE == GL_UNSIGNED_BYTE 1483 if (table->Size == 256) { 1484 /* common case */ 1485 const GLchan *lut = (const GLchan *) table->Table; 1486 GLuint i; 1487 for (i = 0; i < n; i++) { 1488 rgba[i][ACOMP] = lut[rgba[i][ACOMP]]; 1489 } 1490 } 1491 else 1492#endif 1493 { 1494 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1495 const GLchan *lut = (const GLchan *) table->Table; 1496 GLuint i; 1497 for (i = 0; i < n; i++) { 1498 GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1499 rgba[i][ACOMP] = lut[j]; 1500 } 1501 } 1502 } 1503 break; 1504 case GL_LUMINANCE_ALPHA: 1505 /* replace RGBA with LLLA */ 1506 if (table->Type == GL_FLOAT) { 1507 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1508 const GLfloat *lut = (const GLfloat *) table->Table; 1509 GLuint i; 1510 for (i = 0; i < n; i++) { 1511 GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1512 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1513 GLchan luminance, alpha; 1514 CLAMPED_FLOAT_TO_CHAN(luminance, lut[jL * 2 + 0]); 1515 CLAMPED_FLOAT_TO_CHAN(alpha, lut[jA * 2 + 1]); 1516 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance; 1517 rgba[i][ACOMP] = alpha;; 1518 } 1519 } 1520 else { 1521#if CHAN_TYPE == GL_UNSIGNED_BYTE 1522 if (table->Size == 256) { 1523 /* common case */ 1524 const GLchan *lut = (const GLchan *) table->Table; 1525 GLuint i; 1526 for (i = 0; i < n; i++) { 1527 GLchan l = lut[rgba[i][RCOMP] * 2 + 0]; 1528 GLchan a = lut[rgba[i][ACOMP] * 2 + 1];; 1529 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = l; 1530 rgba[i][ACOMP] = a; 1531 } 1532 } 1533 else 1534#endif 1535 { 1536 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1537 const GLchan *lut = (const GLchan *) table->Table; 1538 GLuint i; 1539 for (i = 0; i < n; i++) { 1540 GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1541 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1542 GLchan luminance = lut[jL * 2 + 0]; 1543 GLchan alpha = lut[jA * 2 + 1]; 1544 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance; 1545 rgba[i][ACOMP] = alpha; 1546 } 1547 } 1548 } 1549 break; 1550 case GL_RGB: 1551 /* replace RGB with RGB */ 1552 if (table->Type == GL_FLOAT) { 1553 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1554 const GLfloat *lut = (const GLfloat *) table->Table; 1555 GLuint i; 1556 for (i = 0; i < n; i++) { 1557 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1558 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale); 1559 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale); 1560 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 3 + 0]); 1561 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 3 + 1]); 1562 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 3 + 2]); 1563 } 1564 } 1565 else { 1566#if CHAN_TYPE == GL_UNSIGNED_BYTE 1567 if (table->Size == 256) { 1568 /* common case */ 1569 const GLchan *lut = (const GLchan *) table->Table; 1570 GLuint i; 1571 for (i = 0; i < n; i++) { 1572 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0]; 1573 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1]; 1574 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2]; 1575 } 1576 } 1577 else 1578#endif 1579 { 1580 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1581 const GLchan *lut = (const GLchan *) table->Table; 1582 GLuint i; 1583 for (i = 0; i < n; i++) { 1584 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1585 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale); 1586 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale); 1587 rgba[i][RCOMP] = lut[jR * 3 + 0]; 1588 rgba[i][GCOMP] = lut[jG * 3 + 1]; 1589 rgba[i][BCOMP] = lut[jB * 3 + 2]; 1590 } 1591 } 1592 } 1593 break; 1594 case GL_RGBA: 1595 /* replace RGBA with RGBA */ 1596 if (table->Type == GL_FLOAT) { 1597 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1598 const GLfloat *lut = (const GLfloat *) table->Table; 1599 GLuint i; 1600 for (i = 0; i < n; i++) { 1601 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1602 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale); 1603 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale); 1604 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1605 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]); 1606 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]); 1607 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]); 1608 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]); 1609 } 1610 } 1611 else { 1612#if CHAN_TYPE == GL_UNSIGNED_BYTE 1613 if (table->Size == 256) { 1614 /* common case */ 1615 const GLchan *lut = (const GLchan *) table->Table; 1616 GLuint i; 1617 for (i = 0; i < n; i++) { 1618 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0]; 1619 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1]; 1620 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2]; 1621 rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3]; 1622 } 1623 } 1624 else 1625#endif 1626 { 1627 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF; 1628 const GLfloat *lut = (const GLfloat *) table->Table; 1629 GLuint i; 1630 for (i = 0; i < n; i++) { 1631 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale); 1632 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale); 1633 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale); 1634 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale); 1635 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]); 1636 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]); 1637 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]); 1638 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]); 1639 } 1640 } 1641 } 1642 break; 1643 default: 1644 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan"); 1645 return; 1646 } 1647} 1648 1649 1650 1651/* 1652 * Apply color index shift and offset to an array of pixels. 1653 */ 1654void 1655_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] ) 1656{ 1657 GLint shift = ctx->Pixel.IndexShift; 1658 GLint offset = ctx->Pixel.IndexOffset; 1659 GLuint i; 1660 if (shift > 0) { 1661 for (i=0;i<n;i++) { 1662 indexes[i] = (indexes[i] << shift) + offset; 1663 } 1664 } 1665 else if (shift < 0) { 1666 shift = -shift; 1667 for (i=0;i<n;i++) { 1668 indexes[i] = (indexes[i] >> shift) + offset; 1669 } 1670 } 1671 else { 1672 for (i=0;i<n;i++) { 1673 indexes[i] = indexes[i] + offset; 1674 } 1675 } 1676} 1677 1678 1679/* 1680 * Apply color index mapping to color indexes. 1681 */ 1682void 1683_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] ) 1684{ 1685 GLuint mask = ctx->Pixel.MapItoIsize - 1; 1686 GLuint i; 1687 for (i=0;i<n;i++) { 1688 index[i] = ctx->Pixel.MapItoI[ index[i] & mask ]; 1689 } 1690} 1691 1692 1693/* 1694 * Map color indexes to rgba values. 1695 */ 1696void 1697_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n, 1698 const GLuint index[], GLchan rgba[][4] ) 1699{ 1700#if CHAN_BITS == 8 1701 GLuint rmask = ctx->Pixel.MapItoRsize - 1; 1702 GLuint gmask = ctx->Pixel.MapItoGsize - 1; 1703 GLuint bmask = ctx->Pixel.MapItoBsize - 1; 1704 GLuint amask = ctx->Pixel.MapItoAsize - 1; 1705 const GLubyte *rMap = ctx->Pixel.MapItoR8; 1706 const GLubyte *gMap = ctx->Pixel.MapItoG8; 1707 const GLubyte *bMap = ctx->Pixel.MapItoB8; 1708 const GLubyte *aMap = ctx->Pixel.MapItoA8; 1709 GLuint i; 1710 for (i=0;i<n;i++) { 1711 rgba[i][RCOMP] = rMap[index[i] & rmask]; 1712 rgba[i][GCOMP] = gMap[index[i] & gmask]; 1713 rgba[i][BCOMP] = bMap[index[i] & bmask]; 1714 rgba[i][ACOMP] = aMap[index[i] & amask]; 1715 } 1716#else 1717 GLuint rmask = ctx->Pixel.MapItoRsize - 1; 1718 GLuint gmask = ctx->Pixel.MapItoGsize - 1; 1719 GLuint bmask = ctx->Pixel.MapItoBsize - 1; 1720 GLuint amask = ctx->Pixel.MapItoAsize - 1; 1721 const GLfloat *rMap = ctx->Pixel.MapItoR; 1722 const GLfloat *gMap = ctx->Pixel.MapItoG; 1723 const GLfloat *bMap = ctx->Pixel.MapItoB; 1724 const GLfloat *aMap = ctx->Pixel.MapItoA; 1725 GLuint i; 1726 for (i=0;i<n;i++) { 1727 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]); 1728 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]); 1729 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]); 1730 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]); 1731 } 1732#endif 1733} 1734 1735 1736/* 1737 * Map color indexes to float rgba values. 1738 */ 1739void 1740_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n, 1741 const GLuint index[], GLfloat rgba[][4] ) 1742{ 1743 GLuint rmask = ctx->Pixel.MapItoRsize - 1; 1744 GLuint gmask = ctx->Pixel.MapItoGsize - 1; 1745 GLuint bmask = ctx->Pixel.MapItoBsize - 1; 1746 GLuint amask = ctx->Pixel.MapItoAsize - 1; 1747 const GLfloat *rMap = ctx->Pixel.MapItoR; 1748 const GLfloat *gMap = ctx->Pixel.MapItoG; 1749 const GLfloat *bMap = ctx->Pixel.MapItoB; 1750 const GLfloat *aMap = ctx->Pixel.MapItoA; 1751 GLuint i; 1752 for (i=0;i<n;i++) { 1753 rgba[i][RCOMP] = rMap[index[i] & rmask]; 1754 rgba[i][GCOMP] = gMap[index[i] & gmask]; 1755 rgba[i][BCOMP] = bMap[index[i] & bmask]; 1756 rgba[i][ACOMP] = aMap[index[i] & amask]; 1757 } 1758} 1759 1760 1761/* 1762 * Map 8-bit color indexes to rgb values. 1763 */ 1764void 1765_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[], 1766 GLchan rgba[][4] ) 1767{ 1768#if CHAN_BITS == 8 1769 GLuint rmask = ctx->Pixel.MapItoRsize - 1; 1770 GLuint gmask = ctx->Pixel.MapItoGsize - 1; 1771 GLuint bmask = ctx->Pixel.MapItoBsize - 1; 1772 GLuint amask = ctx->Pixel.MapItoAsize - 1; 1773 const GLubyte *rMap = ctx->Pixel.MapItoR8; 1774 const GLubyte *gMap = ctx->Pixel.MapItoG8; 1775 const GLubyte *bMap = ctx->Pixel.MapItoB8; 1776 const GLubyte *aMap = ctx->Pixel.MapItoA8; 1777 GLuint i; 1778 for (i=0;i<n;i++) { 1779 rgba[i][RCOMP] = rMap[index[i] & rmask]; 1780 rgba[i][GCOMP] = gMap[index[i] & gmask]; 1781 rgba[i][BCOMP] = bMap[index[i] & bmask]; 1782 rgba[i][ACOMP] = aMap[index[i] & amask]; 1783 } 1784#else 1785 GLuint rmask = ctx->Pixel.MapItoRsize - 1; 1786 GLuint gmask = ctx->Pixel.MapItoGsize - 1; 1787 GLuint bmask = ctx->Pixel.MapItoBsize - 1; 1788 GLuint amask = ctx->Pixel.MapItoAsize - 1; 1789 const GLfloat *rMap = ctx->Pixel.MapItoR; 1790 const GLfloat *gMap = ctx->Pixel.MapItoG; 1791 const GLfloat *bMap = ctx->Pixel.MapItoB; 1792 const GLfloat *aMap = ctx->Pixel.MapItoA; 1793 GLuint i; 1794 for (i=0;i<n;i++) { 1795 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]); 1796 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]); 1797 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]); 1798 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]); 1799 } 1800#endif 1801} 1802 1803 1804void 1805_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n, 1806 GLstencil stencil[] ) 1807{ 1808 GLuint i; 1809 GLint shift = ctx->Pixel.IndexShift; 1810 GLint offset = ctx->Pixel.IndexOffset; 1811 if (shift > 0) { 1812 for (i=0;i<n;i++) { 1813 stencil[i] = (stencil[i] << shift) + offset; 1814 } 1815 } 1816 else if (shift < 0) { 1817 shift = -shift; 1818 for (i=0;i<n;i++) { 1819 stencil[i] = (stencil[i] >> shift) + offset; 1820 } 1821 } 1822 else { 1823 for (i=0;i<n;i++) { 1824 stencil[i] = stencil[i] + offset; 1825 } 1826 } 1827 1828} 1829 1830 1831void 1832_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] ) 1833{ 1834 GLuint mask = ctx->Pixel.MapStoSsize - 1; 1835 GLuint i; 1836 for (i=0;i<n;i++) { 1837 stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ]; 1838 } 1839} 1840 1841 1842 1843/* 1844 * This function converts an array of GLchan colors to GLfloat colors. 1845 * Most importantly, it undoes the non-uniform quantization of pixel 1846 * values introduced when we convert shallow (< 8 bit) pixel values 1847 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions. 1848 * This fixes a number of OpenGL conformance failures when running on 1849 * 16bpp displays, for example. 1850 */ 1851void 1852_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n, 1853 CONST GLchan rgba[][4], GLfloat rgbaf[][4]) 1854{ 1855#if CHAN_TYPE == GL_FLOAT 1856 MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat)); 1857#else 1858 const GLuint rShift = CHAN_BITS - ctx->Visual.redBits; 1859 const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits; 1860 const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits; 1861 GLuint aShift; 1862 const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits ) - 1); 1863 const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1); 1864 const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1); 1865 GLfloat aScale; 1866 GLuint i; 1867 1868 if (ctx->Visual.alphaBits > 0) { 1869 aShift = CHAN_BITS - ctx->Visual.alphaBits; 1870 aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1); 1871 } 1872 else { 1873 aShift = 0; 1874 aScale = 1.0F / CHAN_MAXF; 1875 } 1876 1877 for (i = 0; i < n; i++) { 1878 const GLint r = rgba[i][RCOMP] >> rShift; 1879 const GLint g = rgba[i][GCOMP] >> gShift; 1880 const GLint b = rgba[i][BCOMP] >> bShift; 1881 const GLint a = rgba[i][ACOMP] >> aShift; 1882 rgbaf[i][RCOMP] = (GLfloat) r * rScale; 1883 rgbaf[i][GCOMP] = (GLfloat) g * gScale; 1884 rgbaf[i][BCOMP] = (GLfloat) b * bScale; 1885 rgbaf[i][ACOMP] = (GLfloat) a * aScale; 1886 } 1887#endif 1888} 1889 1890/**********************************************************************/ 1891/***** State Management *****/ 1892/**********************************************************************/ 1893 1894/* 1895 * Return a bitmask of IMAGE_*_BIT flags which to indicate which 1896 * pixel transfer operations are enabled. 1897 */ 1898static void 1899update_image_transfer_state(GLcontext *ctx) 1900{ 1901 GLuint mask = 0; 1902 1903 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || 1904 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || 1905 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || 1906 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) 1907 mask |= IMAGE_SCALE_BIAS_BIT; 1908 1909 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) 1910 mask |= IMAGE_SHIFT_OFFSET_BIT; 1911 1912 if (ctx->Pixel.MapColorFlag) 1913 mask |= IMAGE_MAP_COLOR_BIT; 1914 1915 if (ctx->Pixel.ColorTableEnabled) 1916 mask |= IMAGE_COLOR_TABLE_BIT; 1917 1918 if (ctx->Pixel.Convolution1DEnabled || 1919 ctx->Pixel.Convolution2DEnabled || 1920 ctx->Pixel.Separable2DEnabled) { 1921 mask |= IMAGE_CONVOLUTION_BIT; 1922 if (ctx->Pixel.PostConvolutionScale[0] != 1.0F || 1923 ctx->Pixel.PostConvolutionScale[1] != 1.0F || 1924 ctx->Pixel.PostConvolutionScale[2] != 1.0F || 1925 ctx->Pixel.PostConvolutionScale[3] != 1.0F || 1926 ctx->Pixel.PostConvolutionBias[0] != 0.0F || 1927 ctx->Pixel.PostConvolutionBias[1] != 0.0F || 1928 ctx->Pixel.PostConvolutionBias[2] != 0.0F || 1929 ctx->Pixel.PostConvolutionBias[3] != 0.0F) { 1930 mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS; 1931 } 1932 } 1933 1934 if (ctx->Pixel.PostConvolutionColorTableEnabled) 1935 mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT; 1936 1937 if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY || 1938 ctx->Pixel.PostColorMatrixScale[0] != 1.0F || 1939 ctx->Pixel.PostColorMatrixBias[0] != 0.0F || 1940 ctx->Pixel.PostColorMatrixScale[1] != 1.0F || 1941 ctx->Pixel.PostColorMatrixBias[1] != 0.0F || 1942 ctx->Pixel.PostColorMatrixScale[2] != 1.0F || 1943 ctx->Pixel.PostColorMatrixBias[2] != 0.0F || 1944 ctx->Pixel.PostColorMatrixScale[3] != 1.0F || 1945 ctx->Pixel.PostColorMatrixBias[3] != 0.0F) 1946 mask |= IMAGE_COLOR_MATRIX_BIT; 1947 1948 if (ctx->Pixel.PostColorMatrixColorTableEnabled) 1949 mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT; 1950 1951 if (ctx->Pixel.HistogramEnabled) 1952 mask |= IMAGE_HISTOGRAM_BIT; 1953 1954 if (ctx->Pixel.MinMaxEnabled) 1955 mask |= IMAGE_MIN_MAX_BIT; 1956 1957 ctx->_ImageTransferState = mask; 1958} 1959 1960 1961void _mesa_update_pixel( GLcontext *ctx, GLuint new_state ) 1962{ 1963 if (new_state & _NEW_COLOR_MATRIX) 1964 _math_matrix_analyse( ctx->ColorMatrixStack.Top ); 1965 1966 /* References ColorMatrix.type (derived above). 1967 */ 1968 if (new_state & _IMAGE_NEW_TRANSFER_STATE) 1969 update_image_transfer_state(ctx); 1970} 1971 1972 1973/**********************************************************************/ 1974/***** Initialization *****/ 1975/**********************************************************************/ 1976 1977 1978/** 1979 * Initialize the context's PIXEL attribute group. 1980 */ 1981void 1982_mesa_init_pixel( GLcontext *ctx ) 1983{ 1984 int i; 1985 1986 /* Pixel group */ 1987 ctx->Pixel.RedBias = 0.0; 1988 ctx->Pixel.RedScale = 1.0; 1989 ctx->Pixel.GreenBias = 0.0; 1990 ctx->Pixel.GreenScale = 1.0; 1991 ctx->Pixel.BlueBias = 0.0; 1992 ctx->Pixel.BlueScale = 1.0; 1993 ctx->Pixel.AlphaBias = 0.0; 1994 ctx->Pixel.AlphaScale = 1.0; 1995 ctx->Pixel.DepthBias = 0.0; 1996 ctx->Pixel.DepthScale = 1.0; 1997 ctx->Pixel.IndexOffset = 0; 1998 ctx->Pixel.IndexShift = 0; 1999 ctx->Pixel.ZoomX = 1.0; 2000 ctx->Pixel.ZoomY = 1.0; 2001 ctx->Pixel.MapColorFlag = GL_FALSE; 2002 ctx->Pixel.MapStencilFlag = GL_FALSE; 2003 ctx->Pixel.MapStoSsize = 1; 2004 ctx->Pixel.MapItoIsize = 1; 2005 ctx->Pixel.MapItoRsize = 1; 2006 ctx->Pixel.MapItoGsize = 1; 2007 ctx->Pixel.MapItoBsize = 1; 2008 ctx->Pixel.MapItoAsize = 1; 2009 ctx->Pixel.MapRtoRsize = 1; 2010 ctx->Pixel.MapGtoGsize = 1; 2011 ctx->Pixel.MapBtoBsize = 1; 2012 ctx->Pixel.MapAtoAsize = 1; 2013 ctx->Pixel.MapStoS[0] = 0; 2014 ctx->Pixel.MapItoI[0] = 0; 2015 ctx->Pixel.MapItoR[0] = 0.0; 2016 ctx->Pixel.MapItoG[0] = 0.0; 2017 ctx->Pixel.MapItoB[0] = 0.0; 2018 ctx->Pixel.MapItoA[0] = 0.0; 2019 ctx->Pixel.MapItoR8[0] = 0; 2020 ctx->Pixel.MapItoG8[0] = 0; 2021 ctx->Pixel.MapItoB8[0] = 0; 2022 ctx->Pixel.MapItoA8[0] = 0; 2023 ctx->Pixel.MapRtoR[0] = 0.0; 2024 ctx->Pixel.MapGtoG[0] = 0.0; 2025 ctx->Pixel.MapBtoB[0] = 0.0; 2026 ctx->Pixel.MapAtoA[0] = 0.0; 2027 ctx->Pixel.HistogramEnabled = GL_FALSE; 2028 ctx->Pixel.MinMaxEnabled = GL_FALSE; 2029 ctx->Pixel.PixelTextureEnabled = GL_FALSE; 2030 ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS; 2031 ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS; 2032 ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0); 2033 ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0); 2034 ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0); 2035 ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0); 2036 ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0); 2037 ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0); 2038 ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0); 2039 ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0); 2040 ctx->Pixel.ColorTableEnabled = GL_FALSE; 2041 ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE; 2042 ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE; 2043 ctx->Pixel.Convolution1DEnabled = GL_FALSE; 2044 ctx->Pixel.Convolution2DEnabled = GL_FALSE; 2045 ctx->Pixel.Separable2DEnabled = GL_FALSE; 2046 for (i = 0; i < 3; i++) { 2047 ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0); 2048 ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE; 2049 ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0); 2050 ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0); 2051 } 2052 for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) { 2053 ctx->Convolution1D.Filter[i] = 0.0; 2054 ctx->Convolution2D.Filter[i] = 0.0; 2055 ctx->Separable2D.Filter[i] = 0.0; 2056 } 2057 ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0); 2058 ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0); 2059 /* GL_SGI_texture_color_table */ 2060 ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0); 2061 ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0); 2062 2063 /* Pixel transfer */ 2064 ctx->Pack.Alignment = 4; 2065 ctx->Pack.RowLength = 0; 2066 ctx->Pack.ImageHeight = 0; 2067 ctx->Pack.SkipPixels = 0; 2068 ctx->Pack.SkipRows = 0; 2069 ctx->Pack.SkipImages = 0; 2070 ctx->Pack.SwapBytes = GL_FALSE; 2071 ctx->Pack.LsbFirst = GL_FALSE; 2072 ctx->Pack.ClientStorage = GL_FALSE; 2073 ctx->Pack.Invert = GL_FALSE; 2074#if FEATURE_EXT_pixel_buffer_object 2075 ctx->Pack.BufferObj = ctx->Array.NullBufferObj; 2076#endif 2077 ctx->Unpack.Alignment = 4; 2078 ctx->Unpack.RowLength = 0; 2079 ctx->Unpack.ImageHeight = 0; 2080 ctx->Unpack.SkipPixels = 0; 2081 ctx->Unpack.SkipRows = 0; 2082 ctx->Unpack.SkipImages = 0; 2083 ctx->Unpack.SwapBytes = GL_FALSE; 2084 ctx->Unpack.LsbFirst = GL_FALSE; 2085 ctx->Unpack.ClientStorage = GL_FALSE; 2086 ctx->Unpack.Invert = GL_FALSE; 2087#if FEATURE_EXT_pixel_buffer_object 2088 ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; 2089#endif 2090 2091 /* 2092 * _mesa_unpack_image() returns image data in this format. When we 2093 * execute image commands (glDrawPixels(), glTexImage(), etc) from 2094 * within display lists we have to be sure to set the current 2095 * unpacking parameters to these values! 2096 */ 2097 ctx->DefaultPacking.Alignment = 1; 2098 ctx->DefaultPacking.RowLength = 0; 2099 ctx->DefaultPacking.SkipPixels = 0; 2100 ctx->DefaultPacking.SkipRows = 0; 2101 ctx->DefaultPacking.ImageHeight = 0; 2102 ctx->DefaultPacking.SkipImages = 0; 2103 ctx->DefaultPacking.SwapBytes = GL_FALSE; 2104 ctx->DefaultPacking.LsbFirst = GL_FALSE; 2105 ctx->DefaultPacking.ClientStorage = GL_FALSE; 2106 ctx->DefaultPacking.Invert = GL_FALSE; 2107#if FEATURE_EXT_pixel_buffer_object 2108 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; 2109#endif 2110 2111 if (ctx->Visual.doubleBufferMode) { 2112 ctx->Pixel.ReadBuffer = GL_BACK; 2113 ctx->Pixel._ReadSrcMask = DD_BACK_LEFT_BIT; 2114 } 2115 else { 2116 ctx->Pixel.ReadBuffer = GL_FRONT; 2117 ctx->Pixel._ReadSrcMask = DD_FRONT_LEFT_BIT; 2118 } 2119 2120 /* Miscellaneous */ 2121 ctx->_ImageTransferState = 0; 2122} 2123