image.c revision a1287f549a3e6527b8cf3bf5b5f563ba63c6f48c
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27/** 28 * \file image.c 29 * Image handling. 30 */ 31 32 33#include "glheader.h" 34#include "colormac.h" 35#include "glformats.h" 36#include "image.h" 37#include "imports.h" 38#include "macros.h" 39#include "mfeatures.h" 40#include "mtypes.h" 41 42 43 44/** 45 * Flip the order of the 2 bytes in each word in the given array. 46 * 47 * \param p array. 48 * \param n number of words. 49 */ 50void 51_mesa_swap2( GLushort *p, GLuint n ) 52{ 53 GLuint i; 54 for (i = 0; i < n; i++) { 55 p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00); 56 } 57} 58 59 60 61/* 62 * Flip the order of the 4 bytes in each word in the given array. 63 */ 64void 65_mesa_swap4( GLuint *p, GLuint n ) 66{ 67 GLuint i, a, b; 68 for (i = 0; i < n; i++) { 69 b = p[i]; 70 a = (b >> 24) 71 | ((b >> 8) & 0xff00) 72 | ((b << 8) & 0xff0000) 73 | ((b << 24) & 0xff000000); 74 p[i] = a; 75 } 76} 77 78 79/** 80 * Do error checking of format/type combinations for glReadPixels, 81 * glDrawPixels and glTex[Sub]Image. Note that depending on the format 82 * and type values, we may either generate GL_INVALID_OPERATION or 83 * GL_INVALID_ENUM. 84 * 85 * \param format pixel format. 86 * \param type pixel type. 87 * 88 * \return GL_INVALID_ENUM, GL_INVALID_OPERATION or GL_NO_ERROR 89 */ 90GLenum 91_mesa_error_check_format_and_type(const struct gl_context *ctx, 92 GLenum format, GLenum type) 93{ 94 /* special type-based checks (see glReadPixels, glDrawPixels error lists) */ 95 switch (type) { 96 case GL_BITMAP: 97 if (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX) { 98 return GL_INVALID_ENUM; 99 } 100 break; 101 102 case GL_UNSIGNED_BYTE_3_3_2: 103 case GL_UNSIGNED_BYTE_2_3_3_REV: 104 case GL_UNSIGNED_SHORT_5_6_5: 105 case GL_UNSIGNED_SHORT_5_6_5_REV: 106 if (format == GL_RGB) { 107 break; /* OK */ 108 } 109 if (format == GL_RGB_INTEGER_EXT && 110 ctx->Extensions.ARB_texture_rgb10_a2ui) { 111 break; /* OK */ 112 } 113 return GL_INVALID_OPERATION; 114 115 case GL_UNSIGNED_SHORT_4_4_4_4: 116 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 117 case GL_UNSIGNED_SHORT_5_5_5_1: 118 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 119 case GL_UNSIGNED_INT_8_8_8_8: 120 case GL_UNSIGNED_INT_8_8_8_8_REV: 121 case GL_UNSIGNED_INT_10_10_10_2: 122 case GL_UNSIGNED_INT_2_10_10_10_REV: 123 if (format == GL_RGBA || 124 format == GL_BGRA || 125 format == GL_ABGR_EXT) { 126 break; /* OK */ 127 } 128 if ((format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) && 129 ctx->Extensions.ARB_texture_rgb10_a2ui) { 130 break; /* OK */ 131 } 132 return GL_INVALID_OPERATION; 133 134 case GL_UNSIGNED_INT_24_8: 135 if (!ctx->Extensions.EXT_packed_depth_stencil) { 136 return GL_INVALID_ENUM; 137 } 138 if (format != GL_DEPTH_STENCIL) { 139 return GL_INVALID_OPERATION; 140 } 141 return GL_NO_ERROR; 142 143 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 144 if (!ctx->Extensions.ARB_depth_buffer_float) { 145 return GL_INVALID_ENUM; 146 } 147 if (format != GL_DEPTH_STENCIL) { 148 return GL_INVALID_OPERATION; 149 } 150 return GL_NO_ERROR; 151 152 case GL_UNSIGNED_INT_10F_11F_11F_REV: 153 if (!ctx->Extensions.EXT_packed_float) { 154 return GL_INVALID_ENUM; 155 } 156 if (format != GL_RGB) { 157 return GL_INVALID_OPERATION; 158 } 159 return GL_NO_ERROR; 160 161 default: 162 ; /* fall-through */ 163 } 164 165 /* now, for each format, check the type for compatibility */ 166 switch (format) { 167 case GL_COLOR_INDEX: 168 case GL_STENCIL_INDEX: 169 switch (type) { 170 case GL_BITMAP: 171 case GL_BYTE: 172 case GL_UNSIGNED_BYTE: 173 case GL_SHORT: 174 case GL_UNSIGNED_SHORT: 175 case GL_INT: 176 case GL_UNSIGNED_INT: 177 case GL_FLOAT: 178 return GL_NO_ERROR; 179 case GL_HALF_FLOAT: 180 return ctx->Extensions.ARB_half_float_pixel 181 ? GL_NO_ERROR : GL_INVALID_ENUM; 182 default: 183 return GL_INVALID_ENUM; 184 } 185 186 case GL_RED: 187 case GL_GREEN: 188 case GL_BLUE: 189 case GL_ALPHA: 190#if 0 /* not legal! see table 3.6 of the 1.5 spec */ 191 case GL_INTENSITY: 192#endif 193 case GL_LUMINANCE: 194 case GL_LUMINANCE_ALPHA: 195 case GL_DEPTH_COMPONENT: 196 switch (type) { 197 case GL_BYTE: 198 case GL_UNSIGNED_BYTE: 199 case GL_SHORT: 200 case GL_UNSIGNED_SHORT: 201 case GL_INT: 202 case GL_UNSIGNED_INT: 203 case GL_FLOAT: 204 return GL_NO_ERROR; 205 case GL_HALF_FLOAT: 206 return ctx->Extensions.ARB_half_float_pixel 207 ? GL_NO_ERROR : GL_INVALID_ENUM; 208 default: 209 return GL_INVALID_ENUM; 210 } 211 212 case GL_RG: 213 if (!ctx->Extensions.ARB_texture_rg) 214 return GL_INVALID_ENUM; 215 switch (type) { 216 case GL_BYTE: 217 case GL_UNSIGNED_BYTE: 218 case GL_SHORT: 219 case GL_UNSIGNED_SHORT: 220 case GL_INT: 221 case GL_UNSIGNED_INT: 222 case GL_FLOAT: 223 return GL_NO_ERROR; 224 case GL_HALF_FLOAT: 225 return ctx->Extensions.ARB_half_float_pixel 226 ? GL_NO_ERROR : GL_INVALID_ENUM; 227 default: 228 return GL_INVALID_ENUM; 229 } 230 231 case GL_RGB: 232 switch (type) { 233 case GL_BYTE: 234 case GL_UNSIGNED_BYTE: 235 case GL_SHORT: 236 case GL_UNSIGNED_SHORT: 237 case GL_INT: 238 case GL_UNSIGNED_INT: 239 case GL_FLOAT: 240 case GL_UNSIGNED_BYTE_3_3_2: 241 case GL_UNSIGNED_BYTE_2_3_3_REV: 242 case GL_UNSIGNED_SHORT_5_6_5: 243 case GL_UNSIGNED_SHORT_5_6_5_REV: 244 return GL_NO_ERROR; 245 case GL_HALF_FLOAT: 246 return ctx->Extensions.ARB_half_float_pixel 247 ? GL_NO_ERROR : GL_INVALID_ENUM; 248 case GL_UNSIGNED_INT_5_9_9_9_REV: 249 return ctx->Extensions.EXT_texture_shared_exponent 250 ? GL_NO_ERROR : GL_INVALID_ENUM; 251 case GL_UNSIGNED_INT_10F_11F_11F_REV: 252 return ctx->Extensions.EXT_packed_float 253 ? GL_NO_ERROR : GL_INVALID_ENUM; 254 default: 255 return GL_INVALID_ENUM; 256 } 257 258 case GL_BGR: 259 switch (type) { 260 /* NOTE: no packed types are supported with BGR. That's 261 * intentional, according to the GL spec. 262 */ 263 case GL_BYTE: 264 case GL_UNSIGNED_BYTE: 265 case GL_SHORT: 266 case GL_UNSIGNED_SHORT: 267 case GL_INT: 268 case GL_UNSIGNED_INT: 269 case GL_FLOAT: 270 return GL_NO_ERROR; 271 case GL_HALF_FLOAT: 272 return ctx->Extensions.ARB_half_float_pixel 273 ? GL_NO_ERROR : GL_INVALID_ENUM; 274 default: 275 return GL_INVALID_ENUM; 276 } 277 278 case GL_RGBA: 279 case GL_BGRA: 280 case GL_ABGR_EXT: 281 switch (type) { 282 case GL_BYTE: 283 case GL_UNSIGNED_BYTE: 284 case GL_SHORT: 285 case GL_UNSIGNED_SHORT: 286 case GL_INT: 287 case GL_UNSIGNED_INT: 288 case GL_FLOAT: 289 case GL_UNSIGNED_SHORT_4_4_4_4: 290 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 291 case GL_UNSIGNED_SHORT_5_5_5_1: 292 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 293 case GL_UNSIGNED_INT_8_8_8_8: 294 case GL_UNSIGNED_INT_8_8_8_8_REV: 295 case GL_UNSIGNED_INT_10_10_10_2: 296 case GL_UNSIGNED_INT_2_10_10_10_REV: 297 return GL_NO_ERROR; 298 case GL_HALF_FLOAT: 299 return ctx->Extensions.ARB_half_float_pixel 300 ? GL_NO_ERROR : GL_INVALID_ENUM; 301 default: 302 return GL_INVALID_ENUM; 303 } 304 305 case GL_YCBCR_MESA: 306 if (!ctx->Extensions.MESA_ycbcr_texture) 307 return GL_INVALID_ENUM; 308 if (type == GL_UNSIGNED_SHORT_8_8_MESA || 309 type == GL_UNSIGNED_SHORT_8_8_REV_MESA) 310 return GL_NO_ERROR; 311 else 312 return GL_INVALID_OPERATION; 313 314 case GL_DEPTH_STENCIL_EXT: 315 if (ctx->Extensions.EXT_packed_depth_stencil && 316 type == GL_UNSIGNED_INT_24_8) 317 return GL_NO_ERROR; 318 else if (ctx->Extensions.ARB_depth_buffer_float && 319 type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) 320 return GL_NO_ERROR; 321 else 322 return GL_INVALID_ENUM; 323 324 case GL_DUDV_ATI: 325 case GL_DU8DV8_ATI: 326 if (!ctx->Extensions.ATI_envmap_bumpmap) 327 return GL_INVALID_ENUM; 328 switch (type) { 329 case GL_BYTE: 330 case GL_UNSIGNED_BYTE: 331 case GL_SHORT: 332 case GL_UNSIGNED_SHORT: 333 case GL_INT: 334 case GL_UNSIGNED_INT: 335 case GL_FLOAT: 336 return GL_NO_ERROR; 337 default: 338 return GL_INVALID_ENUM; 339 } 340 341 /* integer-valued formats */ 342 case GL_RED_INTEGER_EXT: 343 case GL_GREEN_INTEGER_EXT: 344 case GL_BLUE_INTEGER_EXT: 345 case GL_ALPHA_INTEGER_EXT: 346 case GL_RG_INTEGER: 347 switch (type) { 348 case GL_BYTE: 349 case GL_UNSIGNED_BYTE: 350 case GL_SHORT: 351 case GL_UNSIGNED_SHORT: 352 case GL_INT: 353 case GL_UNSIGNED_INT: 354 return (ctx->VersionMajor >= 3 || 355 ctx->Extensions.EXT_texture_integer) 356 ? GL_NO_ERROR : GL_INVALID_ENUM; 357 default: 358 return GL_INVALID_ENUM; 359 } 360 361 case GL_RGB_INTEGER_EXT: 362 switch (type) { 363 case GL_BYTE: 364 case GL_UNSIGNED_BYTE: 365 case GL_SHORT: 366 case GL_UNSIGNED_SHORT: 367 case GL_INT: 368 case GL_UNSIGNED_INT: 369 return (ctx->VersionMajor >= 3 || 370 ctx->Extensions.EXT_texture_integer) 371 ? GL_NO_ERROR : GL_INVALID_ENUM; 372 case GL_UNSIGNED_BYTE_3_3_2: 373 case GL_UNSIGNED_BYTE_2_3_3_REV: 374 case GL_UNSIGNED_SHORT_5_6_5: 375 case GL_UNSIGNED_SHORT_5_6_5_REV: 376 return ctx->Extensions.ARB_texture_rgb10_a2ui 377 ? GL_NO_ERROR : GL_INVALID_ENUM; 378 default: 379 return GL_INVALID_ENUM; 380 } 381 382 case GL_BGR_INTEGER_EXT: 383 switch (type) { 384 case GL_BYTE: 385 case GL_UNSIGNED_BYTE: 386 case GL_SHORT: 387 case GL_UNSIGNED_SHORT: 388 case GL_INT: 389 case GL_UNSIGNED_INT: 390 /* NOTE: no packed formats w/ BGR format */ 391 return (ctx->VersionMajor >= 3 || 392 ctx->Extensions.EXT_texture_integer) 393 ? GL_NO_ERROR : GL_INVALID_ENUM; 394 default: 395 return GL_INVALID_ENUM; 396 } 397 398 case GL_RGBA_INTEGER_EXT: 399 case GL_BGRA_INTEGER_EXT: 400 switch (type) { 401 case GL_BYTE: 402 case GL_UNSIGNED_BYTE: 403 case GL_SHORT: 404 case GL_UNSIGNED_SHORT: 405 case GL_INT: 406 case GL_UNSIGNED_INT: 407 return (ctx->VersionMajor >= 3 || 408 ctx->Extensions.EXT_texture_integer) 409 ? GL_NO_ERROR : GL_INVALID_ENUM; 410 case GL_UNSIGNED_SHORT_4_4_4_4: 411 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 412 case GL_UNSIGNED_SHORT_5_5_5_1: 413 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 414 case GL_UNSIGNED_INT_8_8_8_8: 415 case GL_UNSIGNED_INT_8_8_8_8_REV: 416 case GL_UNSIGNED_INT_10_10_10_2: 417 case GL_UNSIGNED_INT_2_10_10_10_REV: 418 return ctx->Extensions.ARB_texture_rgb10_a2ui 419 ? GL_NO_ERROR : GL_INVALID_ENUM; 420 default: 421 return GL_INVALID_ENUM; 422 } 423 424 case GL_LUMINANCE_INTEGER_EXT: 425 case GL_LUMINANCE_ALPHA_INTEGER_EXT: 426 switch (type) { 427 case GL_BYTE: 428 case GL_UNSIGNED_BYTE: 429 case GL_SHORT: 430 case GL_UNSIGNED_SHORT: 431 case GL_INT: 432 case GL_UNSIGNED_INT: 433 return ctx->Extensions.EXT_texture_integer 434 ? GL_NO_ERROR : GL_INVALID_ENUM; 435 default: 436 return GL_INVALID_ENUM; 437 } 438 439 default: 440 return GL_INVALID_ENUM; 441 } 442 return GL_NO_ERROR; 443} 444 445 446/** 447 * Return the byte offset of a specific pixel in an image (1D, 2D or 3D). 448 * 449 * Pixel unpacking/packing parameters are observed according to \p packing. 450 * 451 * \param dimensions either 1, 2 or 3 to indicate dimensionality of image 452 * \param packing the pixelstore attributes 453 * \param width the image width 454 * \param height the image height 455 * \param format the pixel format (must be validated beforehand) 456 * \param type the pixel data type (must be validated beforehand) 457 * \param img which image in the volume (0 for 1D or 2D images) 458 * \param row row of pixel in the image (0 for 1D images) 459 * \param column column of pixel in the image 460 * 461 * \return offset of pixel. 462 * 463 * \sa gl_pixelstore_attrib. 464 */ 465GLintptr 466_mesa_image_offset( GLuint dimensions, 467 const struct gl_pixelstore_attrib *packing, 468 GLsizei width, GLsizei height, 469 GLenum format, GLenum type, 470 GLint img, GLint row, GLint column ) 471{ 472 GLint alignment; /* 1, 2 or 4 */ 473 GLint pixels_per_row; 474 GLint rows_per_image; 475 GLint skiprows; 476 GLint skippixels; 477 GLint skipimages; /* for 3-D volume images */ 478 GLintptr offset; 479 480 ASSERT(dimensions >= 1 && dimensions <= 3); 481 482 alignment = packing->Alignment; 483 if (packing->RowLength > 0) { 484 pixels_per_row = packing->RowLength; 485 } 486 else { 487 pixels_per_row = width; 488 } 489 if (packing->ImageHeight > 0) { 490 rows_per_image = packing->ImageHeight; 491 } 492 else { 493 rows_per_image = height; 494 } 495 496 skippixels = packing->SkipPixels; 497 /* Note: SKIP_ROWS _is_ used for 1D images */ 498 skiprows = packing->SkipRows; 499 /* Note: SKIP_IMAGES is only used for 3D images */ 500 skipimages = (dimensions == 3) ? packing->SkipImages : 0; 501 502 if (type == GL_BITMAP) { 503 /* BITMAP data */ 504 GLint bytes_per_row; 505 GLint bytes_per_image; 506 /* components per pixel for color or stencil index: */ 507 const GLint comp_per_pixel = 1; 508 509 /* The pixel type and format should have been error checked earlier */ 510 assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX); 511 512 bytes_per_row = alignment 513 * CEILING( comp_per_pixel*pixels_per_row, 8*alignment ); 514 515 bytes_per_image = bytes_per_row * rows_per_image; 516 517 offset = (skipimages + img) * bytes_per_image 518 + (skiprows + row) * bytes_per_row 519 + (skippixels + column) / 8; 520 } 521 else { 522 /* Non-BITMAP data */ 523 GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image; 524 GLint topOfImage; 525 526 bytes_per_pixel = _mesa_bytes_per_pixel( format, type ); 527 528 /* The pixel type and format should have been error checked earlier */ 529 assert(bytes_per_pixel > 0); 530 531 bytes_per_row = pixels_per_row * bytes_per_pixel; 532 remainder = bytes_per_row % alignment; 533 if (remainder > 0) 534 bytes_per_row += (alignment - remainder); 535 536 ASSERT(bytes_per_row % alignment == 0); 537 538 bytes_per_image = bytes_per_row * rows_per_image; 539 540 if (packing->Invert) { 541 /* set pixel_addr to the last row */ 542 topOfImage = bytes_per_row * (height - 1); 543 bytes_per_row = -bytes_per_row; 544 } 545 else { 546 topOfImage = 0; 547 } 548 549 /* compute final pixel address */ 550 offset = (skipimages + img) * bytes_per_image 551 + topOfImage 552 + (skiprows + row) * bytes_per_row 553 + (skippixels + column) * bytes_per_pixel; 554 } 555 556 return offset; 557} 558 559 560/** 561 * Return the address of a specific pixel in an image (1D, 2D or 3D). 562 * 563 * Pixel unpacking/packing parameters are observed according to \p packing. 564 * 565 * \param dimensions either 1, 2 or 3 to indicate dimensionality of image 566 * \param packing the pixelstore attributes 567 * \param image starting address of image data 568 * \param width the image width 569 * \param height the image height 570 * \param format the pixel format (must be validated beforehand) 571 * \param type the pixel data type (must be validated beforehand) 572 * \param img which image in the volume (0 for 1D or 2D images) 573 * \param row row of pixel in the image (0 for 1D images) 574 * \param column column of pixel in the image 575 * 576 * \return address of pixel. 577 * 578 * \sa gl_pixelstore_attrib. 579 */ 580GLvoid * 581_mesa_image_address( GLuint dimensions, 582 const struct gl_pixelstore_attrib *packing, 583 const GLvoid *image, 584 GLsizei width, GLsizei height, 585 GLenum format, GLenum type, 586 GLint img, GLint row, GLint column ) 587{ 588 const GLubyte *addr = (const GLubyte *) image; 589 590 addr += _mesa_image_offset(dimensions, packing, width, height, 591 format, type, img, row, column); 592 593 return (GLvoid *) addr; 594} 595 596 597GLvoid * 598_mesa_image_address1d( const struct gl_pixelstore_attrib *packing, 599 const GLvoid *image, 600 GLsizei width, 601 GLenum format, GLenum type, 602 GLint column ) 603{ 604 return _mesa_image_address(1, packing, image, width, 1, 605 format, type, 0, 0, column); 606} 607 608 609GLvoid * 610_mesa_image_address2d( const struct gl_pixelstore_attrib *packing, 611 const GLvoid *image, 612 GLsizei width, GLsizei height, 613 GLenum format, GLenum type, 614 GLint row, GLint column ) 615{ 616 return _mesa_image_address(2, packing, image, width, height, 617 format, type, 0, row, column); 618} 619 620 621GLvoid * 622_mesa_image_address3d( const struct gl_pixelstore_attrib *packing, 623 const GLvoid *image, 624 GLsizei width, GLsizei height, 625 GLenum format, GLenum type, 626 GLint img, GLint row, GLint column ) 627{ 628 return _mesa_image_address(3, packing, image, width, height, 629 format, type, img, row, column); 630} 631 632 633 634/** 635 * Compute the stride (in bytes) between image rows. 636 * 637 * \param packing the pixelstore attributes 638 * \param width image width. 639 * \param format pixel format. 640 * \param type pixel data type. 641 * 642 * \return the stride in bytes for the given parameters, or -1 if error 643 */ 644GLint 645_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing, 646 GLint width, GLenum format, GLenum type ) 647{ 648 GLint bytesPerRow, remainder; 649 650 ASSERT(packing); 651 652 if (type == GL_BITMAP) { 653 if (packing->RowLength == 0) { 654 bytesPerRow = (width + 7) / 8; 655 } 656 else { 657 bytesPerRow = (packing->RowLength + 7) / 8; 658 } 659 } 660 else { 661 /* Non-BITMAP data */ 662 const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); 663 if (bytesPerPixel <= 0) 664 return -1; /* error */ 665 if (packing->RowLength == 0) { 666 bytesPerRow = bytesPerPixel * width; 667 } 668 else { 669 bytesPerRow = bytesPerPixel * packing->RowLength; 670 } 671 } 672 673 remainder = bytesPerRow % packing->Alignment; 674 if (remainder > 0) { 675 bytesPerRow += (packing->Alignment - remainder); 676 } 677 678 if (packing->Invert) { 679 /* negate the bytes per row (negative row stride) */ 680 bytesPerRow = -bytesPerRow; 681 } 682 683 return bytesPerRow; 684} 685 686 687/* 688 * Compute the stride between images in a 3D texture (in bytes) for the given 689 * pixel packing parameters and image width, format and type. 690 */ 691GLint 692_mesa_image_image_stride( const struct gl_pixelstore_attrib *packing, 693 GLint width, GLint height, 694 GLenum format, GLenum type ) 695{ 696 GLint bytesPerRow, bytesPerImage, remainder; 697 698 ASSERT(packing); 699 700 if (type == GL_BITMAP) { 701 if (packing->RowLength == 0) { 702 bytesPerRow = (width + 7) / 8; 703 } 704 else { 705 bytesPerRow = (packing->RowLength + 7) / 8; 706 } 707 } 708 else { 709 const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); 710 711 if (bytesPerPixel <= 0) 712 return -1; /* error */ 713 if (packing->RowLength == 0) { 714 bytesPerRow = bytesPerPixel * width; 715 } 716 else { 717 bytesPerRow = bytesPerPixel * packing->RowLength; 718 } 719 } 720 721 remainder = bytesPerRow % packing->Alignment; 722 if (remainder > 0) 723 bytesPerRow += (packing->Alignment - remainder); 724 725 if (packing->ImageHeight == 0) 726 bytesPerImage = bytesPerRow * height; 727 else 728 bytesPerImage = bytesPerRow * packing->ImageHeight; 729 730 return bytesPerImage; 731} 732 733 734 735/** 736 * "Expand" a bitmap from 1-bit per pixel to 8-bits per pixel. 737 * This is typically used to convert a bitmap into a GLubyte/pixel texture. 738 * "On" bits will set texels to \p onValue. 739 * "Off" bits will not modify texels. 740 * \param width src bitmap width in pixels 741 * \param height src bitmap height in pixels 742 * \param unpack bitmap unpacking state 743 * \param bitmap the src bitmap data 744 * \param destBuffer start of dest buffer 745 * \param destStride row stride in dest buffer 746 * \param onValue if bit is 1, set destBuffer pixel to this value 747 */ 748void 749_mesa_expand_bitmap(GLsizei width, GLsizei height, 750 const struct gl_pixelstore_attrib *unpack, 751 const GLubyte *bitmap, 752 GLubyte *destBuffer, GLint destStride, 753 GLubyte onValue) 754{ 755 const GLubyte *srcRow = (const GLubyte *) 756 _mesa_image_address2d(unpack, bitmap, width, height, 757 GL_COLOR_INDEX, GL_BITMAP, 0, 0); 758 const GLint srcStride = _mesa_image_row_stride(unpack, width, 759 GL_COLOR_INDEX, GL_BITMAP); 760 GLint row, col; 761 762#define SET_PIXEL(COL, ROW) \ 763 destBuffer[(ROW) * destStride + (COL)] = onValue; 764 765 for (row = 0; row < height; row++) { 766 const GLubyte *src = srcRow; 767 768 if (unpack->LsbFirst) { 769 /* Lsb first */ 770 GLubyte mask = 1U << (unpack->SkipPixels & 0x7); 771 for (col = 0; col < width; col++) { 772 773 if (*src & mask) { 774 SET_PIXEL(col, row); 775 } 776 777 if (mask == 128U) { 778 src++; 779 mask = 1U; 780 } 781 else { 782 mask = mask << 1; 783 } 784 } 785 786 /* get ready for next row */ 787 if (mask != 1) 788 src++; 789 } 790 else { 791 /* Msb first */ 792 GLubyte mask = 128U >> (unpack->SkipPixels & 0x7); 793 for (col = 0; col < width; col++) { 794 795 if (*src & mask) { 796 SET_PIXEL(col, row); 797 } 798 799 if (mask == 1U) { 800 src++; 801 mask = 128U; 802 } 803 else { 804 mask = mask >> 1; 805 } 806 } 807 808 /* get ready for next row */ 809 if (mask != 128) 810 src++; 811 } 812 813 srcRow += srcStride; 814 } /* row */ 815 816#undef SET_PIXEL 817} 818 819 820 821 822/** 823 * Convert an array of RGBA colors from one datatype to another. 824 * NOTE: src may equal dst. In that case, we use a temporary buffer. 825 */ 826void 827_mesa_convert_colors(GLenum srcType, const GLvoid *src, 828 GLenum dstType, GLvoid *dst, 829 GLuint count, const GLubyte mask[]) 830{ 831 GLuint *tempBuffer; 832 const GLboolean useTemp = (src == dst); 833 834 tempBuffer = malloc(count * MAX_PIXEL_BYTES); 835 if (!tempBuffer) 836 return; 837 838 ASSERT(srcType != dstType); 839 840 switch (srcType) { 841 case GL_UNSIGNED_BYTE: 842 if (dstType == GL_UNSIGNED_SHORT) { 843 const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; 844 GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst); 845 GLuint i; 846 for (i = 0; i < count; i++) { 847 if (!mask || mask[i]) { 848 dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]); 849 dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]); 850 dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]); 851 dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]); 852 } 853 } 854 if (useTemp) 855 memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); 856 } 857 else { 858 const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; 859 GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst); 860 GLuint i; 861 ASSERT(dstType == GL_FLOAT); 862 for (i = 0; i < count; i++) { 863 if (!mask || mask[i]) { 864 dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]); 865 dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]); 866 dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]); 867 dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]); 868 } 869 } 870 if (useTemp) 871 memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); 872 } 873 break; 874 case GL_UNSIGNED_SHORT: 875 if (dstType == GL_UNSIGNED_BYTE) { 876 const GLushort (*src2)[4] = (const GLushort (*)[4]) src; 877 GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); 878 GLuint i; 879 for (i = 0; i < count; i++) { 880 if (!mask || mask[i]) { 881 dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]); 882 dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]); 883 dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]); 884 dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]); 885 } 886 } 887 if (useTemp) 888 memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); 889 } 890 else { 891 const GLushort (*src2)[4] = (const GLushort (*)[4]) src; 892 GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst); 893 GLuint i; 894 ASSERT(dstType == GL_FLOAT); 895 for (i = 0; i < count; i++) { 896 if (!mask || mask[i]) { 897 dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]); 898 dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]); 899 dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]); 900 dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]); 901 } 902 } 903 if (useTemp) 904 memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); 905 } 906 break; 907 case GL_FLOAT: 908 if (dstType == GL_UNSIGNED_BYTE) { 909 const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; 910 GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); 911 GLuint i; 912 for (i = 0; i < count; i++) { 913 if (!mask || mask[i]) 914 _mesa_unclamped_float_rgba_to_ubyte(dst1[i], src4[i]); 915 } 916 if (useTemp) 917 memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); 918 } 919 else { 920 const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; 921 GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst); 922 GLuint i; 923 ASSERT(dstType == GL_UNSIGNED_SHORT); 924 for (i = 0; i < count; i++) { 925 if (!mask || mask[i]) { 926 UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]); 927 UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]); 928 UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]); 929 UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]); 930 } 931 } 932 if (useTemp) 933 memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); 934 } 935 break; 936 default: 937 _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors"); 938 } 939 940 free(tempBuffer); 941} 942 943 944 945 946/** 947 * Perform basic clipping for glDrawPixels. The image's position and size 948 * and the unpack SkipPixels and SkipRows are adjusted so that the image 949 * region is entirely within the window and scissor bounds. 950 * NOTE: this will only work when glPixelZoom is (1, 1) or (1, -1). 951 * If Pixel.ZoomY is -1, *destY will be changed to be the first row which 952 * we'll actually write. Beforehand, *destY-1 is the first drawing row. 953 * 954 * \return GL_TRUE if image is ready for drawing or 955 * GL_FALSE if image was completely clipped away (draw nothing) 956 */ 957GLboolean 958_mesa_clip_drawpixels(const struct gl_context *ctx, 959 GLint *destX, GLint *destY, 960 GLsizei *width, GLsizei *height, 961 struct gl_pixelstore_attrib *unpack) 962{ 963 const struct gl_framebuffer *buffer = ctx->DrawBuffer; 964 965 if (unpack->RowLength == 0) { 966 unpack->RowLength = *width; 967 } 968 969 ASSERT(ctx->Pixel.ZoomX == 1.0F); 970 ASSERT(ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F); 971 972 /* left clipping */ 973 if (*destX < buffer->_Xmin) { 974 unpack->SkipPixels += (buffer->_Xmin - *destX); 975 *width -= (buffer->_Xmin - *destX); 976 *destX = buffer->_Xmin; 977 } 978 /* right clipping */ 979 if (*destX + *width > buffer->_Xmax) 980 *width -= (*destX + *width - buffer->_Xmax); 981 982 if (*width <= 0) 983 return GL_FALSE; 984 985 if (ctx->Pixel.ZoomY == 1.0F) { 986 /* bottom clipping */ 987 if (*destY < buffer->_Ymin) { 988 unpack->SkipRows += (buffer->_Ymin - *destY); 989 *height -= (buffer->_Ymin - *destY); 990 *destY = buffer->_Ymin; 991 } 992 /* top clipping */ 993 if (*destY + *height > buffer->_Ymax) 994 *height -= (*destY + *height - buffer->_Ymax); 995 } 996 else { /* upside down */ 997 /* top clipping */ 998 if (*destY > buffer->_Ymax) { 999 unpack->SkipRows += (*destY - buffer->_Ymax); 1000 *height -= (*destY - buffer->_Ymax); 1001 *destY = buffer->_Ymax; 1002 } 1003 /* bottom clipping */ 1004 if (*destY - *height < buffer->_Ymin) 1005 *height -= (buffer->_Ymin - (*destY - *height)); 1006 /* adjust destY so it's the first row to write to */ 1007 (*destY)--; 1008 } 1009 1010 if (*height <= 0) 1011 return GL_FALSE; 1012 1013 return GL_TRUE; 1014} 1015 1016 1017/** 1018 * Perform clipping for glReadPixels. The image's window position 1019 * and size, and the pack skipPixels, skipRows and rowLength are adjusted 1020 * so that the image region is entirely within the window bounds. 1021 * Note: this is different from _mesa_clip_drawpixels() in that the 1022 * scissor box is ignored, and we use the bounds of the current readbuffer 1023 * surface. 1024 * 1025 * \return GL_TRUE if region to read is in bounds 1026 * GL_FALSE if region is completely out of bounds (nothing to read) 1027 */ 1028GLboolean 1029_mesa_clip_readpixels(const struct gl_context *ctx, 1030 GLint *srcX, GLint *srcY, 1031 GLsizei *width, GLsizei *height, 1032 struct gl_pixelstore_attrib *pack) 1033{ 1034 const struct gl_framebuffer *buffer = ctx->ReadBuffer; 1035 1036 if (pack->RowLength == 0) { 1037 pack->RowLength = *width; 1038 } 1039 1040 /* left clipping */ 1041 if (*srcX < 0) { 1042 pack->SkipPixels += (0 - *srcX); 1043 *width -= (0 - *srcX); 1044 *srcX = 0; 1045 } 1046 /* right clipping */ 1047 if (*srcX + *width > (GLsizei) buffer->Width) 1048 *width -= (*srcX + *width - buffer->Width); 1049 1050 if (*width <= 0) 1051 return GL_FALSE; 1052 1053 /* bottom clipping */ 1054 if (*srcY < 0) { 1055 pack->SkipRows += (0 - *srcY); 1056 *height -= (0 - *srcY); 1057 *srcY = 0; 1058 } 1059 /* top clipping */ 1060 if (*srcY + *height > (GLsizei) buffer->Height) 1061 *height -= (*srcY + *height - buffer->Height); 1062 1063 if (*height <= 0) 1064 return GL_FALSE; 1065 1066 return GL_TRUE; 1067} 1068 1069 1070/** 1071 * Do clipping for a glCopyTexSubImage call. 1072 * The framebuffer source region might extend outside the framebuffer 1073 * bounds. Clip the source region against the framebuffer bounds and 1074 * adjust the texture/dest position and size accordingly. 1075 * 1076 * \return GL_FALSE if region is totally clipped, GL_TRUE otherwise. 1077 */ 1078GLboolean 1079_mesa_clip_copytexsubimage(const struct gl_context *ctx, 1080 GLint *destX, GLint *destY, 1081 GLint *srcX, GLint *srcY, 1082 GLsizei *width, GLsizei *height) 1083{ 1084 const struct gl_framebuffer *fb = ctx->ReadBuffer; 1085 const GLint srcX0 = *srcX, srcY0 = *srcY; 1086 1087 if (_mesa_clip_to_region(0, 0, fb->Width, fb->Height, 1088 srcX, srcY, width, height)) { 1089 *destX = *destX + *srcX - srcX0; 1090 *destY = *destY + *srcY - srcY0; 1091 1092 return GL_TRUE; 1093 } 1094 else { 1095 return GL_FALSE; 1096 } 1097} 1098 1099 1100 1101/** 1102 * Clip the rectangle defined by (x, y, width, height) against the bounds 1103 * specified by [xmin, xmax) and [ymin, ymax). 1104 * \return GL_FALSE if rect is totally clipped, GL_TRUE otherwise. 1105 */ 1106GLboolean 1107_mesa_clip_to_region(GLint xmin, GLint ymin, 1108 GLint xmax, GLint ymax, 1109 GLint *x, GLint *y, 1110 GLsizei *width, GLsizei *height ) 1111{ 1112 /* left clipping */ 1113 if (*x < xmin) { 1114 *width -= (xmin - *x); 1115 *x = xmin; 1116 } 1117 1118 /* right clipping */ 1119 if (*x + *width > xmax) 1120 *width -= (*x + *width - xmax); 1121 1122 if (*width <= 0) 1123 return GL_FALSE; 1124 1125 /* bottom (or top) clipping */ 1126 if (*y < ymin) { 1127 *height -= (ymin - *y); 1128 *y = ymin; 1129 } 1130 1131 /* top (or bottom) clipping */ 1132 if (*y + *height > ymax) 1133 *height -= (*y + *height - ymax); 1134 1135 if (*height <= 0) 1136 return GL_FALSE; 1137 1138 return GL_TRUE; 1139} 1140 1141 1142/** 1143 * Clip dst coords against Xmax (or Ymax). 1144 */ 1145static inline void 1146clip_right_or_top(GLint *srcX0, GLint *srcX1, 1147 GLint *dstX0, GLint *dstX1, 1148 GLint maxValue) 1149{ 1150 GLfloat t, bias; 1151 1152 if (*dstX1 > maxValue) { 1153 /* X1 outside right edge */ 1154 ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */ 1155 t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0); 1156 /* chop off [t, 1] part */ 1157 ASSERT(t >= 0.0 && t <= 1.0); 1158 *dstX1 = maxValue; 1159 bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; 1160 *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); 1161 } 1162 else if (*dstX0 > maxValue) { 1163 /* X0 outside right edge */ 1164 ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */ 1165 t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1); 1166 /* chop off [t, 1] part */ 1167 ASSERT(t >= 0.0 && t <= 1.0); 1168 *dstX0 = maxValue; 1169 bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F; 1170 *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); 1171 } 1172} 1173 1174 1175/** 1176 * Clip dst coords against Xmin (or Ymin). 1177 */ 1178static inline void 1179clip_left_or_bottom(GLint *srcX0, GLint *srcX1, 1180 GLint *dstX0, GLint *dstX1, 1181 GLint minValue) 1182{ 1183 GLfloat t, bias; 1184 1185 if (*dstX0 < minValue) { 1186 /* X0 outside left edge */ 1187 ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */ 1188 t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0); 1189 /* chop off [0, t] part */ 1190 ASSERT(t >= 0.0 && t <= 1.0); 1191 *dstX0 = minValue; 1192 bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; /* flipped??? */ 1193 *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); 1194 } 1195 else if (*dstX1 < minValue) { 1196 /* X1 outside left edge */ 1197 ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */ 1198 t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1); 1199 /* chop off [0, t] part */ 1200 ASSERT(t >= 0.0 && t <= 1.0); 1201 *dstX1 = minValue; 1202 bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; 1203 *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); 1204 } 1205} 1206 1207 1208/** 1209 * Do clipping of blit src/dest rectangles. 1210 * The dest rect is clipped against both the buffer bounds and scissor bounds. 1211 * The src rect is just clipped against the buffer bounds. 1212 * 1213 * When either the src or dest rect is clipped, the other is also clipped 1214 * proportionately! 1215 * 1216 * Note that X0 need not be less than X1 (same for Y) for either the source 1217 * and dest rects. That makes the clipping a little trickier. 1218 * 1219 * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped 1220 */ 1221GLboolean 1222_mesa_clip_blit(struct gl_context *ctx, 1223 GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, 1224 GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1) 1225{ 1226 const GLint srcXmin = 0; 1227 const GLint srcXmax = ctx->ReadBuffer->Width; 1228 const GLint srcYmin = 0; 1229 const GLint srcYmax = ctx->ReadBuffer->Height; 1230 1231 /* these include scissor bounds */ 1232 const GLint dstXmin = ctx->DrawBuffer->_Xmin; 1233 const GLint dstXmax = ctx->DrawBuffer->_Xmax; 1234 const GLint dstYmin = ctx->DrawBuffer->_Ymin; 1235 const GLint dstYmax = ctx->DrawBuffer->_Ymax; 1236 1237 /* 1238 printf("PreClipX: src: %d .. %d dst: %d .. %d\n", 1239 *srcX0, *srcX1, *dstX0, *dstX1); 1240 printf("PreClipY: src: %d .. %d dst: %d .. %d\n", 1241 *srcY0, *srcY1, *dstY0, *dstY1); 1242 */ 1243 1244 /* trivial rejection tests */ 1245 if (*dstX0 == *dstX1) 1246 return GL_FALSE; /* no width */ 1247 if (*dstX0 <= dstXmin && *dstX1 <= dstXmin) 1248 return GL_FALSE; /* totally out (left) of bounds */ 1249 if (*dstX0 >= dstXmax && *dstX1 >= dstXmax) 1250 return GL_FALSE; /* totally out (right) of bounds */ 1251 1252 if (*dstY0 == *dstY1) 1253 return GL_FALSE; 1254 if (*dstY0 <= dstYmin && *dstY1 <= dstYmin) 1255 return GL_FALSE; 1256 if (*dstY0 >= dstYmax && *dstY1 >= dstYmax) 1257 return GL_FALSE; 1258 1259 if (*srcX0 == *srcX1) 1260 return GL_FALSE; 1261 if (*srcX0 <= srcXmin && *srcX1 <= srcXmin) 1262 return GL_FALSE; 1263 if (*srcX0 >= srcXmax && *srcX1 >= srcXmax) 1264 return GL_FALSE; 1265 1266 if (*srcY0 == *srcY1) 1267 return GL_FALSE; 1268 if (*srcY0 <= srcYmin && *srcY1 <= srcYmin) 1269 return GL_FALSE; 1270 if (*srcY0 >= srcYmax && *srcY1 >= srcYmax) 1271 return GL_FALSE; 1272 1273 /* 1274 * dest clip 1275 */ 1276 clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax); 1277 clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax); 1278 clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin); 1279 clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin); 1280 1281 /* 1282 * src clip (just swap src/dst values from above) 1283 */ 1284 clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax); 1285 clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax); 1286 clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin); 1287 clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin); 1288 1289 /* 1290 printf("PostClipX: src: %d .. %d dst: %d .. %d\n", 1291 *srcX0, *srcX1, *dstX0, *dstX1); 1292 printf("PostClipY: src: %d .. %d dst: %d .. %d\n", 1293 *srcY0, *srcY1, *dstY0, *dstY1); 1294 */ 1295 1296 ASSERT(*dstX0 >= dstXmin); 1297 ASSERT(*dstX0 <= dstXmax); 1298 ASSERT(*dstX1 >= dstXmin); 1299 ASSERT(*dstX1 <= dstXmax); 1300 1301 ASSERT(*dstY0 >= dstYmin); 1302 ASSERT(*dstY0 <= dstYmax); 1303 ASSERT(*dstY1 >= dstYmin); 1304 ASSERT(*dstY1 <= dstYmax); 1305 1306 ASSERT(*srcX0 >= srcXmin); 1307 ASSERT(*srcX0 <= srcXmax); 1308 ASSERT(*srcX1 >= srcXmin); 1309 ASSERT(*srcX1 <= srcXmax); 1310 1311 ASSERT(*srcY0 >= srcYmin); 1312 ASSERT(*srcY0 <= srcYmax); 1313 ASSERT(*srcY1 >= srcYmin); 1314 ASSERT(*srcY1 <= srcYmax); 1315 1316 return GL_TRUE; 1317} 1318