histogram.c revision c1f859d4
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 26#include "glheader.h" 27#include "bufferobj.h" 28#include "colormac.h" 29#include "context.h" 30#include "image.h" 31#include "histogram.h" 32 33 34 35/* 36 * XXX the packed pixel formats haven't been tested. 37 */ 38static void 39pack_histogram( GLcontext *ctx, 40 GLuint n, CONST GLuint rgba[][4], 41 GLenum format, GLenum type, GLvoid *destination, 42 const struct gl_pixelstore_attrib *packing ) 43{ 44 const GLint comps = _mesa_components_in_format(format); 45 GLuint luminance[MAX_WIDTH]; 46 47 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { 48 GLuint i; 49 for (i = 0; i < n; i++) { 50 luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; 51 } 52 } 53 54#define PACK_MACRO(TYPE) \ 55 { \ 56 GLuint i; \ 57 switch (format) { \ 58 case GL_RED: \ 59 for (i=0;i<n;i++) \ 60 dst[i] = (TYPE) rgba[i][RCOMP]; \ 61 break; \ 62 case GL_GREEN: \ 63 for (i=0;i<n;i++) \ 64 dst[i] = (TYPE) rgba[i][GCOMP]; \ 65 break; \ 66 case GL_BLUE: \ 67 for (i=0;i<n;i++) \ 68 dst[i] = (TYPE) rgba[i][BCOMP]; \ 69 break; \ 70 case GL_ALPHA: \ 71 for (i=0;i<n;i++) \ 72 dst[i] = (TYPE) rgba[i][ACOMP]; \ 73 break; \ 74 case GL_LUMINANCE: \ 75 for (i=0;i<n;i++) \ 76 dst[i] = (TYPE) luminance[i]; \ 77 break; \ 78 case GL_LUMINANCE_ALPHA: \ 79 for (i=0;i<n;i++) { \ 80 dst[i*2+0] = (TYPE) luminance[i]; \ 81 dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \ 82 } \ 83 break; \ 84 case GL_RGB: \ 85 for (i=0;i<n;i++) { \ 86 dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \ 87 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \ 88 dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \ 89 } \ 90 break; \ 91 case GL_RGBA: \ 92 for (i=0;i<n;i++) { \ 93 dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \ 94 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \ 95 dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \ 96 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \ 97 } \ 98 break; \ 99 case GL_BGR: \ 100 for (i=0;i<n;i++) { \ 101 dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \ 102 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \ 103 dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \ 104 } \ 105 break; \ 106 case GL_BGRA: \ 107 for (i=0;i<n;i++) { \ 108 dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \ 109 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \ 110 dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \ 111 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \ 112 } \ 113 break; \ 114 case GL_ABGR_EXT: \ 115 for (i=0;i<n;i++) { \ 116 dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \ 117 dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \ 118 dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \ 119 dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \ 120 } \ 121 break; \ 122 default: \ 123 _mesa_problem(ctx, "bad format in pack_histogram"); \ 124 } \ 125 } 126 127 switch (type) { 128 case GL_UNSIGNED_BYTE: 129 { 130 GLubyte *dst = (GLubyte *) destination; 131 PACK_MACRO(GLubyte); 132 } 133 break; 134 case GL_BYTE: 135 { 136 GLbyte *dst = (GLbyte *) destination; 137 PACK_MACRO(GLbyte); 138 } 139 break; 140 case GL_UNSIGNED_SHORT: 141 { 142 GLushort *dst = (GLushort *) destination; 143 PACK_MACRO(GLushort); 144 if (packing->SwapBytes) { 145 _mesa_swap2(dst, n * comps); 146 } 147 } 148 break; 149 case GL_SHORT: 150 { 151 GLshort *dst = (GLshort *) destination; 152 PACK_MACRO(GLshort); 153 if (packing->SwapBytes) { 154 _mesa_swap2((GLushort *) dst, n * comps); 155 } 156 } 157 break; 158 case GL_UNSIGNED_INT: 159 { 160 GLuint *dst = (GLuint *) destination; 161 PACK_MACRO(GLuint); 162 if (packing->SwapBytes) { 163 _mesa_swap4(dst, n * comps); 164 } 165 } 166 break; 167 case GL_INT: 168 { 169 GLint *dst = (GLint *) destination; 170 PACK_MACRO(GLint); 171 if (packing->SwapBytes) { 172 _mesa_swap4((GLuint *) dst, n * comps); 173 } 174 } 175 break; 176 case GL_FLOAT: 177 { 178 GLfloat *dst = (GLfloat *) destination; 179 PACK_MACRO(GLfloat); 180 if (packing->SwapBytes) { 181 _mesa_swap4((GLuint *) dst, n * comps); 182 } 183 } 184 break; 185 case GL_HALF_FLOAT_ARB: 186 { 187 /* temporarily store as GLuints */ 188 GLuint temp[4*HISTOGRAM_TABLE_SIZE]; 189 GLhalfARB *dst = (GLhalfARB *) destination; 190 GLuint i; 191 /* get GLuint values */ 192 PACK_MACRO(GLuint); 193 /* convert to GLhalf */ 194 for (i = 0; i < n * comps; i++) { 195 dst[i] = _mesa_float_to_half((GLfloat) temp[i]); 196 } 197 if (packing->SwapBytes) { 198 _mesa_swap2((GLushort *) dst, n * comps); 199 } 200 } 201 break; 202 case GL_UNSIGNED_BYTE_3_3_2: 203 if (format == GL_RGB) { 204 GLubyte *dst = (GLubyte *) destination; 205 GLuint i; 206 for (i = 0; i < n; i++) { 207 dst[i] = ((rgba[i][RCOMP] & 0x7) << 5) 208 | ((rgba[i][GCOMP] & 0x7) << 2) 209 | ((rgba[i][BCOMP] & 0x3) ); 210 } 211 } 212 else { 213 GLubyte *dst = (GLubyte *) destination; 214 GLuint i; 215 ASSERT(format == GL_BGR); 216 for (i = 0; i < n; i++) { 217 dst[i] = ((rgba[i][BCOMP] & 0x7) << 5) 218 | ((rgba[i][GCOMP] & 0x7) << 2) 219 | ((rgba[i][RCOMP] & 0x3) ); 220 } 221 } 222 break; 223 case GL_UNSIGNED_BYTE_2_3_3_REV: 224 if (format == GL_RGB) { 225 GLubyte *dst = (GLubyte *) destination; 226 GLuint i; 227 for (i = 0; i < n; i++) { 228 dst[i] = ((rgba[i][RCOMP] & 0x3) << 6) 229 | ((rgba[i][GCOMP] & 0x7) << 3) 230 | ((rgba[i][BCOMP] & 0x7) ); 231 } 232 } 233 else { 234 GLubyte *dst = (GLubyte *) destination; 235 GLuint i; 236 ASSERT(format == GL_BGR); 237 for (i = 0; i < n; i++) { 238 dst[i] = ((rgba[i][BCOMP] & 0x3) << 6) 239 | ((rgba[i][GCOMP] & 0x7) << 3) 240 | ((rgba[i][RCOMP] & 0x7) ); 241 } 242 } 243 break; 244 case GL_UNSIGNED_SHORT_5_6_5: 245 if (format == GL_RGB) { 246 GLushort *dst = (GLushort *) destination; 247 GLuint i; 248 for (i = 0; i < n; i++) { 249 dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) 250 | ((rgba[i][GCOMP] & 0x3f) << 5) 251 | ((rgba[i][BCOMP] & 0x1f) ); 252 } 253 } 254 else { 255 GLushort *dst = (GLushort *) destination; 256 GLuint i; 257 ASSERT(format == GL_BGR); 258 for (i = 0; i < n; i++) { 259 dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) 260 | ((rgba[i][GCOMP] & 0x3f) << 5) 261 | ((rgba[i][RCOMP] & 0x1f) ); 262 } 263 } 264 break; 265 case GL_UNSIGNED_SHORT_5_6_5_REV: 266 if (format == GL_RGB) { 267 GLushort *dst = (GLushort *) destination; 268 GLuint i; 269 for (i = 0; i < n; i++) { 270 dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) 271 | ((rgba[i][GCOMP] & 0x3f) << 5) 272 | ((rgba[i][RCOMP] & 0x1f) ); 273 } 274 } 275 else { 276 GLushort *dst = (GLushort *) destination; 277 GLuint i; 278 ASSERT(format == GL_BGR); 279 for (i = 0; i < n; i++) { 280 dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) 281 | ((rgba[i][GCOMP] & 0x3f) << 5) 282 | ((rgba[i][BCOMP] & 0x1f) ); 283 } 284 } 285 break; 286 case GL_UNSIGNED_SHORT_4_4_4_4: 287 if (format == GL_RGBA) { 288 GLushort *dst = (GLushort *) destination; 289 GLuint i; 290 for (i = 0; i < n; i++) { 291 dst[i] = ((rgba[i][RCOMP] & 0xf) << 12) 292 | ((rgba[i][GCOMP] & 0xf) << 8) 293 | ((rgba[i][BCOMP] & 0xf) << 4) 294 | ((rgba[i][ACOMP] & 0xf) ); 295 } 296 } 297 else if (format == GL_BGRA) { 298 GLushort *dst = (GLushort *) destination; 299 GLuint i; 300 for (i = 0; i < n; i++) { 301 dst[i] = ((rgba[i][BCOMP] & 0xf) << 12) 302 | ((rgba[i][GCOMP] & 0xf) << 8) 303 | ((rgba[i][RCOMP] & 0xf) << 4) 304 | ((rgba[i][ACOMP] & 0xf) ); 305 } 306 } 307 else { 308 GLushort *dst = (GLushort *) destination; 309 GLuint i; 310 ASSERT(format == GL_ABGR_EXT); 311 for (i = 0; i < n; i++) { 312 dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) 313 | ((rgba[i][BCOMP] & 0xf) << 8) 314 | ((rgba[i][GCOMP] & 0xf) << 4) 315 | ((rgba[i][RCOMP] & 0xf) ); 316 } 317 } 318 break; 319 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 320 if (format == GL_RGBA) { 321 GLushort *dst = (GLushort *) destination; 322 GLuint i; 323 for (i = 0; i < n; i++) { 324 dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) 325 | ((rgba[i][BCOMP] & 0xf) << 8) 326 | ((rgba[i][GCOMP] & 0xf) << 4) 327 | ((rgba[i][RCOMP] & 0xf) ); 328 } 329 } 330 else if (format == GL_BGRA) { 331 GLushort *dst = (GLushort *) destination; 332 GLuint i; 333 for (i = 0; i < n; i++) { 334 dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) 335 | ((rgba[i][RCOMP] & 0xf) << 8) 336 | ((rgba[i][GCOMP] & 0xf) << 4) 337 | ((rgba[i][BCOMP] & 0xf) ); 338 } 339 } 340 else { 341 GLushort *dst = (GLushort *) destination; 342 GLuint i; 343 ASSERT(format == GL_ABGR_EXT); 344 for (i = 0; i < n; i++) { 345 dst[i] = ((rgba[i][RCOMP] & 0xf) << 12) 346 | ((rgba[i][GCOMP] & 0xf) << 8) 347 | ((rgba[i][BCOMP] & 0xf) << 4) 348 | ((rgba[i][ACOMP] & 0xf) ); 349 } 350 } 351 break; 352 case GL_UNSIGNED_SHORT_5_5_5_1: 353 if (format == GL_RGBA) { 354 GLushort *dst = (GLushort *) destination; 355 GLuint i; 356 for (i = 0; i < n; i++) { 357 dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) 358 | ((rgba[i][GCOMP] & 0x1f) << 6) 359 | ((rgba[i][BCOMP] & 0x1f) << 1) 360 | ((rgba[i][ACOMP] & 0x1) ); 361 } 362 } 363 else if (format == GL_BGRA) { 364 GLushort *dst = (GLushort *) destination; 365 GLuint i; 366 for (i = 0; i < n; i++) { 367 dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) 368 | ((rgba[i][GCOMP] & 0x1f) << 6) 369 | ((rgba[i][RCOMP] & 0x1f) << 1) 370 | ((rgba[i][ACOMP] & 0x1) ); 371 } 372 } 373 else { 374 GLushort *dst = (GLushort *) destination; 375 GLuint i; 376 ASSERT(format == GL_ABGR_EXT); 377 for (i = 0; i < n; i++) { 378 dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11) 379 | ((rgba[i][BCOMP] & 0x1f) << 6) 380 | ((rgba[i][GCOMP] & 0x1f) << 1) 381 | ((rgba[i][RCOMP] & 0x1) ); 382 } 383 } 384 break; 385 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 386 if (format == GL_RGBA) { 387 GLushort *dst = (GLushort *) destination; 388 GLuint i; 389 for (i = 0; i < n; i++) { 390 dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11) 391 | ((rgba[i][BCOMP] & 0x1f) << 6) 392 | ((rgba[i][GCOMP] & 0x1f) << 1) 393 | ((rgba[i][RCOMP] & 0x1) ); 394 } 395 } 396 else if (format == GL_BGRA) { 397 GLushort *dst = (GLushort *) destination; 398 GLuint i; 399 for (i = 0; i < n; i++) { 400 dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11) 401 | ((rgba[i][RCOMP] & 0x1f) << 6) 402 | ((rgba[i][GCOMP] & 0x1f) << 1) 403 | ((rgba[i][BCOMP] & 0x1) ); 404 } 405 } 406 else { 407 GLushort *dst = (GLushort *) destination; 408 GLuint i; 409 ASSERT(format == GL_ABGR_EXT); 410 for (i = 0; i < n; i++) { 411 dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) 412 | ((rgba[i][GCOMP] & 0x1f) << 6) 413 | ((rgba[i][BCOMP] & 0x1f) << 1) 414 | ((rgba[i][ACOMP] & 0x1) ); 415 } 416 } 417 break; 418 case GL_UNSIGNED_INT_8_8_8_8: 419 if (format == GL_RGBA) { 420 GLuint *dst = (GLuint *) destination; 421 GLuint i; 422 for (i = 0; i < n; i++) { 423 dst[i] = ((rgba[i][RCOMP] & 0xff) << 24) 424 | ((rgba[i][GCOMP] & 0xff) << 16) 425 | ((rgba[i][BCOMP] & 0xff) << 8) 426 | ((rgba[i][ACOMP] & 0xff) ); 427 } 428 } 429 else if (format == GL_BGRA) { 430 GLuint *dst = (GLuint *) destination; 431 GLuint i; 432 for (i = 0; i < n; i++) { 433 dst[i] = ((rgba[i][BCOMP] & 0xff) << 24) 434 | ((rgba[i][GCOMP] & 0xff) << 16) 435 | ((rgba[i][RCOMP] & 0xff) << 8) 436 | ((rgba[i][ACOMP] & 0xff) ); 437 } 438 } 439 else { 440 GLuint *dst = (GLuint *) destination; 441 GLuint i; 442 ASSERT(format == GL_ABGR_EXT); 443 for (i = 0; i < n; i++) { 444 dst[i] = ((rgba[i][ACOMP] & 0xff) << 24) 445 | ((rgba[i][BCOMP] & 0xff) << 16) 446 | ((rgba[i][GCOMP] & 0xff) << 8) 447 | ((rgba[i][RCOMP] & 0xff) ); 448 } 449 } 450 break; 451 case GL_UNSIGNED_INT_8_8_8_8_REV: 452 if (format == GL_RGBA) { 453 GLuint *dst = (GLuint *) destination; 454 GLuint i; 455 for (i = 0; i < n; i++) { 456 dst[i] = ((rgba[i][ACOMP] & 0xff) << 24) 457 | ((rgba[i][BCOMP] & 0xff) << 16) 458 | ((rgba[i][GCOMP] & 0xff) << 8) 459 | ((rgba[i][RCOMP] & 0xff) ); 460 } 461 } 462 else if (format == GL_BGRA) { 463 GLuint *dst = (GLuint *) destination; 464 GLuint i; 465 for (i = 0; i < n; i++) { 466 dst[i] = ((rgba[i][ACOMP] & 0xff) << 24) 467 | ((rgba[i][RCOMP] & 0xff) << 16) 468 | ((rgba[i][GCOMP] & 0xff) << 8) 469 | ((rgba[i][BCOMP] & 0xff) ); 470 } 471 } 472 else { 473 GLuint *dst = (GLuint *) destination; 474 GLuint i; 475 ASSERT(format == GL_ABGR_EXT); 476 for (i = 0; i < n; i++) { 477 dst[i] = ((rgba[i][RCOMP] & 0xff) << 24) 478 | ((rgba[i][GCOMP] & 0xff) << 16) 479 | ((rgba[i][BCOMP] & 0xff) << 8) 480 | ((rgba[i][ACOMP] & 0xff) ); 481 } 482 } 483 break; 484 case GL_UNSIGNED_INT_10_10_10_2: 485 if (format == GL_RGBA) { 486 GLuint *dst = (GLuint *) destination; 487 GLuint i; 488 for (i = 0; i < n; i++) { 489 dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22) 490 | ((rgba[i][GCOMP] & 0x3ff) << 12) 491 | ((rgba[i][BCOMP] & 0x3ff) << 2) 492 | ((rgba[i][ACOMP] & 0x3) ); 493 } 494 } 495 else if (format == GL_BGRA) { 496 GLuint *dst = (GLuint *) destination; 497 GLuint i; 498 for (i = 0; i < n; i++) { 499 dst[i] = ((rgba[i][BCOMP] & 0x3ff) << 22) 500 | ((rgba[i][GCOMP] & 0x3ff) << 12) 501 | ((rgba[i][RCOMP] & 0x3ff) << 2) 502 | ((rgba[i][ACOMP] & 0x3) ); 503 } 504 } 505 else { 506 GLuint *dst = (GLuint *) destination; 507 GLuint i; 508 ASSERT(format == GL_ABGR_EXT); 509 for (i = 0; i < n; i++) { 510 dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22) 511 | ((rgba[i][BCOMP] & 0x3ff) << 12) 512 | ((rgba[i][GCOMP] & 0x3ff) << 2) 513 | ((rgba[i][RCOMP] & 0x3) ); 514 } 515 } 516 break; 517 case GL_UNSIGNED_INT_2_10_10_10_REV: 518 if (format == GL_RGBA) { 519 GLuint *dst = (GLuint *) destination; 520 GLuint i; 521 for (i = 0; i < n; i++) { 522 dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22) 523 | ((rgba[i][BCOMP] & 0x3ff) << 12) 524 | ((rgba[i][GCOMP] & 0x3ff) << 2) 525 | ((rgba[i][RCOMP] & 0x3) ); 526 } 527 } 528 else if (format == GL_BGRA) { 529 GLuint *dst = (GLuint *) destination; 530 GLuint i; 531 for (i = 0; i < n; i++) { 532 dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22) 533 | ((rgba[i][RCOMP] & 0x3ff) << 12) 534 | ((rgba[i][GCOMP] & 0x3ff) << 2) 535 | ((rgba[i][BCOMP] & 0x3) ); 536 } 537 } 538 else { 539 GLuint *dst = (GLuint *) destination; 540 GLuint i; 541 ASSERT(format == GL_ABGR_EXT); 542 for (i = 0; i < n; i++) { 543 dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22) 544 | ((rgba[i][GCOMP] & 0x3ff) << 12) 545 | ((rgba[i][BCOMP] & 0x3ff) << 2) 546 | ((rgba[i][ACOMP] & 0x3) ); 547 } 548 } 549 break; 550 default: 551 _mesa_problem(ctx, "Bad type in pack_histogram"); 552 } 553 554#undef PACK_MACRO 555} 556 557 558/* 559 * Given an internalFormat token passed to glHistogram or glMinMax, 560 * return the corresponding base format. 561 * Return -1 if invalid token. 562 */ 563static GLint 564base_histogram_format( GLenum format ) 565{ 566 switch (format) { 567 case GL_ALPHA: 568 case GL_ALPHA4: 569 case GL_ALPHA8: 570 case GL_ALPHA12: 571 case GL_ALPHA16: 572 return GL_ALPHA; 573 case GL_LUMINANCE: 574 case GL_LUMINANCE4: 575 case GL_LUMINANCE8: 576 case GL_LUMINANCE12: 577 case GL_LUMINANCE16: 578 return GL_LUMINANCE; 579 case GL_LUMINANCE_ALPHA: 580 case GL_LUMINANCE4_ALPHA4: 581 case GL_LUMINANCE6_ALPHA2: 582 case GL_LUMINANCE8_ALPHA8: 583 case GL_LUMINANCE12_ALPHA4: 584 case GL_LUMINANCE12_ALPHA12: 585 case GL_LUMINANCE16_ALPHA16: 586 return GL_LUMINANCE_ALPHA; 587 case GL_RGB: 588 case GL_R3_G3_B2: 589 case GL_RGB4: 590 case GL_RGB5: 591 case GL_RGB8: 592 case GL_RGB10: 593 case GL_RGB12: 594 case GL_RGB16: 595 return GL_RGB; 596 case GL_RGBA: 597 case GL_RGBA2: 598 case GL_RGBA4: 599 case GL_RGB5_A1: 600 case GL_RGBA8: 601 case GL_RGB10_A2: 602 case GL_RGBA12: 603 case GL_RGBA16: 604 return GL_RGBA; 605 default: 606 return -1; /* error */ 607 } 608} 609 610 611 612/********************************************************************** 613 * API functions 614 */ 615 616 617void GLAPIENTRY 618_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) 619{ 620 GET_CURRENT_CONTEXT(ctx); 621 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 622 623 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 624 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax"); 625 return; 626 } 627 628 if (target != GL_MINMAX) { 629 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)"); 630 return; 631 } 632 633 if (format != GL_RED && 634 format != GL_GREEN && 635 format != GL_BLUE && 636 format != GL_ALPHA && 637 format != GL_RGB && 638 format != GL_BGR && 639 format != GL_RGBA && 640 format != GL_BGRA && 641 format != GL_ABGR_EXT && 642 format != GL_LUMINANCE && 643 format != GL_LUMINANCE_ALPHA) { 644 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMax(format)"); 645 } 646 647 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 648 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)"); 649 return; 650 } 651 652 if (ctx->Pack.BufferObj->Name) { 653 /* pack min/max values into a PBO */ 654 GLubyte *buf; 655 if (!_mesa_validate_pbo_access(1, &ctx->Pack, 2, 1, 1, 656 format, type, values)) { 657 _mesa_error(ctx, GL_INVALID_OPERATION, 658 "glGetMinMax(invalid PBO access)"); 659 return; 660 } 661 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 662 GL_WRITE_ONLY_ARB, 663 ctx->Pack.BufferObj); 664 if (!buf) { 665 /* buffer is already mapped - that's an error */ 666 _mesa_error(ctx, GL_INVALID_OPERATION,"glGetMinMax(PBO is mapped)"); 667 return; 668 } 669 values = ADD_POINTERS(buf, values); 670 } 671 else if (!values) { 672 /* not an error */ 673 return; 674 } 675 676 { 677 GLfloat minmax[2][4]; 678 minmax[0][RCOMP] = CLAMP(ctx->MinMax.Min[RCOMP], 0.0F, 1.0F); 679 minmax[0][GCOMP] = CLAMP(ctx->MinMax.Min[GCOMP], 0.0F, 1.0F); 680 minmax[0][BCOMP] = CLAMP(ctx->MinMax.Min[BCOMP], 0.0F, 1.0F); 681 minmax[0][ACOMP] = CLAMP(ctx->MinMax.Min[ACOMP], 0.0F, 1.0F); 682 minmax[1][RCOMP] = CLAMP(ctx->MinMax.Max[RCOMP], 0.0F, 1.0F); 683 minmax[1][GCOMP] = CLAMP(ctx->MinMax.Max[GCOMP], 0.0F, 1.0F); 684 minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F); 685 minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F); 686 _mesa_pack_rgba_span_float(ctx, 2, minmax, 687 format, type, values, &ctx->Pack, 0x0); 688 } 689 690 if (ctx->Pack.BufferObj->Name) { 691 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 692 ctx->Pack.BufferObj); 693 } 694 695 if (reset) { 696 _mesa_ResetMinmax(GL_MINMAX); 697 } 698} 699 700 701void GLAPIENTRY 702_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) 703{ 704 GET_CURRENT_CONTEXT(ctx); 705 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 706 707 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 708 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram"); 709 return; 710 } 711 712 if (target != GL_HISTOGRAM) { 713 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)"); 714 return; 715 } 716 717 if (format != GL_RED && 718 format != GL_GREEN && 719 format != GL_BLUE && 720 format != GL_ALPHA && 721 format != GL_RGB && 722 format != GL_BGR && 723 format != GL_RGBA && 724 format != GL_BGRA && 725 format != GL_ABGR_EXT && 726 format != GL_LUMINANCE && 727 format != GL_LUMINANCE_ALPHA) { 728 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(format)"); 729 } 730 731 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 732 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)"); 733 return; 734 } 735 736 if (ctx->Pack.BufferObj->Name) { 737 /* pack min/max values into a PBO */ 738 GLubyte *buf; 739 if (!_mesa_validate_pbo_access(1, &ctx->Pack, ctx->Histogram.Width, 1, 1, 740 format, type, values)) { 741 _mesa_error(ctx, GL_INVALID_OPERATION, 742 "glGetHistogram(invalid PBO access)"); 743 return; 744 } 745 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 746 GL_WRITE_ONLY_ARB, 747 ctx->Pack.BufferObj); 748 if (!buf) { 749 /* buffer is already mapped - that's an error */ 750 _mesa_error(ctx,GL_INVALID_OPERATION,"glGetHistogram(PBO is mapped)"); 751 return; 752 } 753 values = ADD_POINTERS(buf, values); 754 } 755 else if (!values) { 756 /* not an error */ 757 return; 758 } 759 760 pack_histogram(ctx, ctx->Histogram.Width, 761 (CONST GLuint (*)[4]) ctx->Histogram.Count, 762 format, type, values, &ctx->Pack); 763 764 if (ctx->Pack.BufferObj->Name) { 765 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 766 ctx->Pack.BufferObj); 767 } 768 769 if (reset) { 770 GLuint i; 771 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { 772 ctx->Histogram.Count[i][0] = 0; 773 ctx->Histogram.Count[i][1] = 0; 774 ctx->Histogram.Count[i][2] = 0; 775 ctx->Histogram.Count[i][3] = 0; 776 } 777 } 778} 779 780 781void GLAPIENTRY 782_mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params) 783{ 784 GET_CURRENT_CONTEXT(ctx); 785 ASSERT_OUTSIDE_BEGIN_END(ctx); 786 787 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 788 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv"); 789 return; 790 } 791 792 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) { 793 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)"); 794 return; 795 } 796 797 switch (pname) { 798 case GL_HISTOGRAM_WIDTH: 799 *params = (GLfloat) ctx->Histogram.Width; 800 break; 801 case GL_HISTOGRAM_FORMAT: 802 *params = (GLfloat) ctx->Histogram.Format; 803 break; 804 case GL_HISTOGRAM_RED_SIZE: 805 *params = (GLfloat) ctx->Histogram.RedSize; 806 break; 807 case GL_HISTOGRAM_GREEN_SIZE: 808 *params = (GLfloat) ctx->Histogram.GreenSize; 809 break; 810 case GL_HISTOGRAM_BLUE_SIZE: 811 *params = (GLfloat) ctx->Histogram.BlueSize; 812 break; 813 case GL_HISTOGRAM_ALPHA_SIZE: 814 *params = (GLfloat) ctx->Histogram.AlphaSize; 815 break; 816 case GL_HISTOGRAM_LUMINANCE_SIZE: 817 *params = (GLfloat) ctx->Histogram.LuminanceSize; 818 break; 819 case GL_HISTOGRAM_SINK: 820 *params = (GLfloat) ctx->Histogram.Sink; 821 break; 822 default: 823 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)"); 824 } 825} 826 827 828void GLAPIENTRY 829_mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params) 830{ 831 GET_CURRENT_CONTEXT(ctx); 832 ASSERT_OUTSIDE_BEGIN_END(ctx); 833 834 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 835 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv"); 836 return; 837 } 838 839 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) { 840 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)"); 841 return; 842 } 843 844 switch (pname) { 845 case GL_HISTOGRAM_WIDTH: 846 *params = (GLint) ctx->Histogram.Width; 847 break; 848 case GL_HISTOGRAM_FORMAT: 849 *params = (GLint) ctx->Histogram.Format; 850 break; 851 case GL_HISTOGRAM_RED_SIZE: 852 *params = (GLint) ctx->Histogram.RedSize; 853 break; 854 case GL_HISTOGRAM_GREEN_SIZE: 855 *params = (GLint) ctx->Histogram.GreenSize; 856 break; 857 case GL_HISTOGRAM_BLUE_SIZE: 858 *params = (GLint) ctx->Histogram.BlueSize; 859 break; 860 case GL_HISTOGRAM_ALPHA_SIZE: 861 *params = (GLint) ctx->Histogram.AlphaSize; 862 break; 863 case GL_HISTOGRAM_LUMINANCE_SIZE: 864 *params = (GLint) ctx->Histogram.LuminanceSize; 865 break; 866 case GL_HISTOGRAM_SINK: 867 *params = (GLint) ctx->Histogram.Sink; 868 break; 869 default: 870 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)"); 871 } 872} 873 874 875void GLAPIENTRY 876_mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params) 877{ 878 GET_CURRENT_CONTEXT(ctx); 879 ASSERT_OUTSIDE_BEGIN_END(ctx); 880 881 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 882 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv"); 883 return; 884 } 885 if (target != GL_MINMAX) { 886 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)"); 887 return; 888 } 889 if (pname == GL_MINMAX_FORMAT) { 890 *params = (GLfloat) ctx->MinMax.Format; 891 } 892 else if (pname == GL_MINMAX_SINK) { 893 *params = (GLfloat) ctx->MinMax.Sink; 894 } 895 else { 896 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)"); 897 } 898} 899 900 901void GLAPIENTRY 902_mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params) 903{ 904 GET_CURRENT_CONTEXT(ctx); 905 ASSERT_OUTSIDE_BEGIN_END(ctx); 906 907 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 908 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv"); 909 return; 910 } 911 if (target != GL_MINMAX) { 912 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)"); 913 return; 914 } 915 if (pname == GL_MINMAX_FORMAT) { 916 *params = (GLint) ctx->MinMax.Format; 917 } 918 else if (pname == GL_MINMAX_SINK) { 919 *params = (GLint) ctx->MinMax.Sink; 920 } 921 else { 922 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)"); 923 } 924} 925 926 927void GLAPIENTRY 928_mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink) 929{ 930 GLuint i; 931 GLboolean error = GL_FALSE; 932 GET_CURRENT_CONTEXT(ctx); 933 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */ 934 935 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 936 _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram"); 937 return; 938 } 939 940 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) { 941 _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(target)"); 942 return; 943 } 944 945 if (width < 0 || width > HISTOGRAM_TABLE_SIZE) { 946 if (target == GL_PROXY_HISTOGRAM) { 947 error = GL_TRUE; 948 } 949 else { 950 if (width < 0) 951 _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)"); 952 else 953 _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)"); 954 return; 955 } 956 } 957 958 if (width != 0 && !_mesa_is_pow_two(width)) { 959 if (target == GL_PROXY_HISTOGRAM) { 960 error = GL_TRUE; 961 } 962 else { 963 _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)"); 964 return; 965 } 966 } 967 968 if (base_histogram_format(internalFormat) < 0) { 969 if (target == GL_PROXY_HISTOGRAM) { 970 error = GL_TRUE; 971 } 972 else { 973 _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)"); 974 return; 975 } 976 } 977 978 /* reset histograms */ 979 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { 980 ctx->Histogram.Count[i][0] = 0; 981 ctx->Histogram.Count[i][1] = 0; 982 ctx->Histogram.Count[i][2] = 0; 983 ctx->Histogram.Count[i][3] = 0; 984 } 985 986 if (error) { 987 ctx->Histogram.Width = 0; 988 ctx->Histogram.Format = 0; 989 ctx->Histogram.RedSize = 0; 990 ctx->Histogram.GreenSize = 0; 991 ctx->Histogram.BlueSize = 0; 992 ctx->Histogram.AlphaSize = 0; 993 ctx->Histogram.LuminanceSize = 0; 994 } 995 else { 996 ctx->Histogram.Width = width; 997 ctx->Histogram.Format = internalFormat; 998 ctx->Histogram.Sink = sink; 999 ctx->Histogram.RedSize = 8 * sizeof(GLuint); 1000 ctx->Histogram.GreenSize = 8 * sizeof(GLuint); 1001 ctx->Histogram.BlueSize = 8 * sizeof(GLuint); 1002 ctx->Histogram.AlphaSize = 8 * sizeof(GLuint); 1003 ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint); 1004 } 1005 1006 ctx->NewState |= _NEW_PIXEL; 1007} 1008 1009 1010void GLAPIENTRY 1011_mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink) 1012{ 1013 GET_CURRENT_CONTEXT(ctx); 1014 ASSERT_OUTSIDE_BEGIN_END(ctx); 1015 1016 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 1017 _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax"); 1018 return; 1019 } 1020 1021 if (target != GL_MINMAX) { 1022 _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(target)"); 1023 return; 1024 } 1025 1026 if (base_histogram_format(internalFormat) < 0) { 1027 _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)"); 1028 return; 1029 } 1030 1031 if (ctx->MinMax.Sink == sink) 1032 return; 1033 FLUSH_VERTICES(ctx, _NEW_PIXEL); 1034 ctx->MinMax.Sink = sink; 1035} 1036 1037 1038void GLAPIENTRY 1039_mesa_ResetHistogram(GLenum target) 1040{ 1041 GLuint i; 1042 GET_CURRENT_CONTEXT(ctx); 1043 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */ 1044 1045 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 1046 _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram"); 1047 return; 1048 } 1049 1050 if (target != GL_HISTOGRAM) { 1051 _mesa_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)"); 1052 return; 1053 } 1054 1055 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { 1056 ctx->Histogram.Count[i][0] = 0; 1057 ctx->Histogram.Count[i][1] = 0; 1058 ctx->Histogram.Count[i][2] = 0; 1059 ctx->Histogram.Count[i][3] = 0; 1060 } 1061 1062 ctx->NewState |= _NEW_PIXEL; 1063} 1064 1065 1066void GLAPIENTRY 1067_mesa_ResetMinmax(GLenum target) 1068{ 1069 GET_CURRENT_CONTEXT(ctx); 1070 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1071 1072 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { 1073 _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax"); 1074 return; 1075 } 1076 1077 if (target != GL_MINMAX) { 1078 _mesa_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)"); 1079 return; 1080 } 1081 1082 ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000; 1083 ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000; 1084 ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; 1085 ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; 1086 ctx->NewState |= _NEW_PIXEL; 1087} 1088 1089 1090 1091/**********************************************************************/ 1092/***** Initialization *****/ 1093/**********************************************************************/ 1094 1095void _mesa_init_histogram( GLcontext * ctx ) 1096{ 1097 int i; 1098 1099 /* Histogram group */ 1100 ctx->Histogram.Width = 0; 1101 ctx->Histogram.Format = GL_RGBA; 1102 ctx->Histogram.Sink = GL_FALSE; 1103 ctx->Histogram.RedSize = 0; 1104 ctx->Histogram.GreenSize = 0; 1105 ctx->Histogram.BlueSize = 0; 1106 ctx->Histogram.AlphaSize = 0; 1107 ctx->Histogram.LuminanceSize = 0; 1108 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { 1109 ctx->Histogram.Count[i][0] = 0; 1110 ctx->Histogram.Count[i][1] = 0; 1111 ctx->Histogram.Count[i][2] = 0; 1112 ctx->Histogram.Count[i][3] = 0; 1113 } 1114 1115 /* Min/Max group */ 1116 ctx->MinMax.Format = GL_RGBA; 1117 ctx->MinMax.Sink = GL_FALSE; 1118 ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000; 1119 ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000; 1120 ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; 1121 ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; 1122} 1123