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