2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
30 #include "histogram.h"
33 /**********************************************************************
39 * Update the min/max values from an array of fragment colors.
42 _mesa_update_minmax(GLcontext
*ctx
, GLuint n
, const GLfloat rgba
[][4])
45 for (i
= 0; i
< n
; i
++) {
47 if (rgba
[i
][RCOMP
] < ctx
->MinMax
.Min
[RCOMP
])
48 ctx
->MinMax
.Min
[RCOMP
] = rgba
[i
][RCOMP
];
49 if (rgba
[i
][GCOMP
] < ctx
->MinMax
.Min
[GCOMP
])
50 ctx
->MinMax
.Min
[GCOMP
] = rgba
[i
][GCOMP
];
51 if (rgba
[i
][BCOMP
] < ctx
->MinMax
.Min
[BCOMP
])
52 ctx
->MinMax
.Min
[BCOMP
] = rgba
[i
][BCOMP
];
53 if (rgba
[i
][ACOMP
] < ctx
->MinMax
.Min
[ACOMP
])
54 ctx
->MinMax
.Min
[ACOMP
] = rgba
[i
][ACOMP
];
57 if (rgba
[i
][RCOMP
] > ctx
->MinMax
.Max
[RCOMP
])
58 ctx
->MinMax
.Max
[RCOMP
] = rgba
[i
][RCOMP
];
59 if (rgba
[i
][GCOMP
] > ctx
->MinMax
.Max
[GCOMP
])
60 ctx
->MinMax
.Max
[GCOMP
] = rgba
[i
][GCOMP
];
61 if (rgba
[i
][BCOMP
] > ctx
->MinMax
.Max
[BCOMP
])
62 ctx
->MinMax
.Max
[BCOMP
] = rgba
[i
][BCOMP
];
63 if (rgba
[i
][ACOMP
] > ctx
->MinMax
.Max
[ACOMP
])
64 ctx
->MinMax
.Max
[ACOMP
] = rgba
[i
][ACOMP
];
70 * Update the histogram values from an array of fragment colors.
73 _mesa_update_histogram(GLcontext
*ctx
, GLuint n
, const GLfloat rgba
[][4])
75 const GLint max
= ctx
->Histogram
.Width
- 1;
76 GLfloat w
= (GLfloat
) max
;
79 if (ctx
->Histogram
.Width
== 0)
82 for (i
= 0; i
< n
; i
++) {
83 GLint ri
= IROUND(rgba
[i
][RCOMP
] * w
);
84 GLint gi
= IROUND(rgba
[i
][GCOMP
] * w
);
85 GLint bi
= IROUND(rgba
[i
][BCOMP
] * w
);
86 GLint ai
= IROUND(rgba
[i
][ACOMP
] * w
);
87 ri
= CLAMP(ri
, 0, max
);
88 gi
= CLAMP(gi
, 0, max
);
89 bi
= CLAMP(bi
, 0, max
);
90 ai
= CLAMP(ai
, 0, max
);
91 ctx
->Histogram
.Count
[ri
][RCOMP
]++;
92 ctx
->Histogram
.Count
[gi
][GCOMP
]++;
93 ctx
->Histogram
.Count
[bi
][BCOMP
]++;
94 ctx
->Histogram
.Count
[ai
][ACOMP
]++;
100 * XXX the packed pixel formats haven't been tested.
103 pack_histogram( GLcontext
*ctx
,
104 GLuint n
, CONST GLuint rgba
[][4],
105 GLenum format
, GLenum type
, GLvoid
*destination
,
106 const struct gl_pixelstore_attrib
*packing
)
108 const GLint comps
= _mesa_components_in_format(format
);
109 GLuint luminance
[MAX_WIDTH
];
111 if (format
== GL_LUMINANCE
|| format
== GL_LUMINANCE_ALPHA
) {
113 for (i
= 0; i
< n
; i
++) {
114 luminance
[i
] = rgba
[i
][RCOMP
] + rgba
[i
][GCOMP
] + rgba
[i
][BCOMP
];
118 #define PACK_MACRO(TYPE) \
124 dst[i] = (TYPE) rgba[i][RCOMP]; \
128 dst[i] = (TYPE) rgba[i][GCOMP]; \
132 dst[i] = (TYPE) rgba[i][BCOMP]; \
136 dst[i] = (TYPE) rgba[i][ACOMP]; \
140 dst[i] = (TYPE) luminance[i]; \
142 case GL_LUMINANCE_ALPHA: \
143 for (i=0;i<n;i++) { \
144 dst[i*2+0] = (TYPE) luminance[i]; \
145 dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \
149 for (i=0;i<n;i++) { \
150 dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \
151 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
152 dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \
156 for (i=0;i<n;i++) { \
157 dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \
158 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
159 dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \
160 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
164 for (i=0;i<n;i++) { \
165 dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \
166 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
167 dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \
171 for (i=0;i<n;i++) { \
172 dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \
173 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
174 dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \
175 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
179 for (i=0;i<n;i++) { \
180 dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \
181 dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \
182 dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \
183 dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \
187 _mesa_problem(ctx, "bad format in pack_histogram"); \
192 case GL_UNSIGNED_BYTE
:
194 GLubyte
*dst
= (GLubyte
*) destination
;
200 GLbyte
*dst
= (GLbyte
*) destination
;
204 case GL_UNSIGNED_SHORT
:
206 GLushort
*dst
= (GLushort
*) destination
;
207 PACK_MACRO(GLushort
);
208 if (packing
->SwapBytes
) {
209 _mesa_swap2(dst
, n
* comps
);
215 GLshort
*dst
= (GLshort
*) destination
;
217 if (packing
->SwapBytes
) {
218 _mesa_swap2((GLushort
*) dst
, n
* comps
);
222 case GL_UNSIGNED_INT
:
224 GLuint
*dst
= (GLuint
*) destination
;
226 if (packing
->SwapBytes
) {
227 _mesa_swap4(dst
, n
* comps
);
233 GLint
*dst
= (GLint
*) destination
;
235 if (packing
->SwapBytes
) {
236 _mesa_swap4((GLuint
*) dst
, n
* comps
);
242 GLfloat
*dst
= (GLfloat
*) destination
;
244 if (packing
->SwapBytes
) {
245 _mesa_swap4((GLuint
*) dst
, n
* comps
);
249 case GL_HALF_FLOAT_ARB
:
251 /* temporarily store as GLuints */
252 GLuint temp
[4*HISTOGRAM_TABLE_SIZE
];
253 GLhalfARB
*dst
= (GLhalfARB
*) destination
;
255 /* get GLuint values */
257 /* convert to GLhalf */
258 for (i
= 0; i
< n
* comps
; i
++) {
259 dst
[i
] = _mesa_float_to_half((GLfloat
) temp
[i
]);
261 if (packing
->SwapBytes
) {
262 _mesa_swap2((GLushort
*) dst
, n
* comps
);
266 case GL_UNSIGNED_BYTE_3_3_2
:
267 if (format
== GL_RGB
) {
268 GLubyte
*dst
= (GLubyte
*) destination
;
270 for (i
= 0; i
< n
; i
++) {
271 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x7) << 5)
272 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
273 | ((rgba
[i
][BCOMP
] & 0x3) );
277 GLubyte
*dst
= (GLubyte
*) destination
;
279 ASSERT(format
== GL_BGR
);
280 for (i
= 0; i
< n
; i
++) {
281 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x7) << 5)
282 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
283 | ((rgba
[i
][RCOMP
] & 0x3) );
287 case GL_UNSIGNED_BYTE_2_3_3_REV
:
288 if (format
== GL_RGB
) {
289 GLubyte
*dst
= (GLubyte
*) destination
;
291 for (i
= 0; i
< n
; i
++) {
292 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3) << 6)
293 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
294 | ((rgba
[i
][BCOMP
] & 0x7) );
298 GLubyte
*dst
= (GLubyte
*) destination
;
300 ASSERT(format
== GL_BGR
);
301 for (i
= 0; i
< n
; i
++) {
302 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3) << 6)
303 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
304 | ((rgba
[i
][RCOMP
] & 0x7) );
308 case GL_UNSIGNED_SHORT_5_6_5
:
309 if (format
== GL_RGB
) {
310 GLushort
*dst
= (GLushort
*) destination
;
312 for (i
= 0; i
< n
; i
++) {
313 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
314 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
315 | ((rgba
[i
][BCOMP
] & 0x1f) );
319 GLushort
*dst
= (GLushort
*) destination
;
321 ASSERT(format
== GL_BGR
);
322 for (i
= 0; i
< n
; i
++) {
323 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
324 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
325 | ((rgba
[i
][RCOMP
] & 0x1f) );
329 case GL_UNSIGNED_SHORT_5_6_5_REV
:
330 if (format
== GL_RGB
) {
331 GLushort
*dst
= (GLushort
*) destination
;
333 for (i
= 0; i
< n
; i
++) {
334 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
335 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
336 | ((rgba
[i
][RCOMP
] & 0x1f) );
340 GLushort
*dst
= (GLushort
*) destination
;
342 ASSERT(format
== GL_BGR
);
343 for (i
= 0; i
< n
; i
++) {
344 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
345 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
346 | ((rgba
[i
][BCOMP
] & 0x1f) );
350 case GL_UNSIGNED_SHORT_4_4_4_4
:
351 if (format
== GL_RGBA
) {
352 GLushort
*dst
= (GLushort
*) destination
;
354 for (i
= 0; i
< n
; i
++) {
355 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
356 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
357 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
358 | ((rgba
[i
][ACOMP
] & 0xf) );
361 else if (format
== GL_BGRA
) {
362 GLushort
*dst
= (GLushort
*) destination
;
364 for (i
= 0; i
< n
; i
++) {
365 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xf) << 12)
366 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
367 | ((rgba
[i
][RCOMP
] & 0xf) << 4)
368 | ((rgba
[i
][ACOMP
] & 0xf) );
372 GLushort
*dst
= (GLushort
*) destination
;
374 ASSERT(format
== GL_ABGR_EXT
);
375 for (i
= 0; i
< n
; i
++) {
376 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
377 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
378 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
379 | ((rgba
[i
][RCOMP
] & 0xf) );
383 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
384 if (format
== GL_RGBA
) {
385 GLushort
*dst
= (GLushort
*) destination
;
387 for (i
= 0; i
< n
; i
++) {
388 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
389 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
390 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
391 | ((rgba
[i
][RCOMP
] & 0xf) );
394 else if (format
== GL_BGRA
) {
395 GLushort
*dst
= (GLushort
*) destination
;
397 for (i
= 0; i
< n
; i
++) {
398 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
399 | ((rgba
[i
][RCOMP
] & 0xf) << 8)
400 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
401 | ((rgba
[i
][BCOMP
] & 0xf) );
405 GLushort
*dst
= (GLushort
*) destination
;
407 ASSERT(format
== GL_ABGR_EXT
);
408 for (i
= 0; i
< n
; i
++) {
409 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
410 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
411 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
412 | ((rgba
[i
][ACOMP
] & 0xf) );
416 case GL_UNSIGNED_SHORT_5_5_5_1
:
417 if (format
== GL_RGBA
) {
418 GLushort
*dst
= (GLushort
*) destination
;
420 for (i
= 0; i
< n
; i
++) {
421 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
422 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
423 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
424 | ((rgba
[i
][ACOMP
] & 0x1) );
427 else if (format
== GL_BGRA
) {
428 GLushort
*dst
= (GLushort
*) destination
;
430 for (i
= 0; i
< n
; i
++) {
431 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
432 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
433 | ((rgba
[i
][RCOMP
] & 0x1f) << 1)
434 | ((rgba
[i
][ACOMP
] & 0x1) );
438 GLushort
*dst
= (GLushort
*) destination
;
440 ASSERT(format
== GL_ABGR_EXT
);
441 for (i
= 0; i
< n
; i
++) {
442 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
443 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
444 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
445 | ((rgba
[i
][RCOMP
] & 0x1) );
449 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
450 if (format
== GL_RGBA
) {
451 GLushort
*dst
= (GLushort
*) destination
;
453 for (i
= 0; i
< n
; i
++) {
454 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
455 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
456 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
457 | ((rgba
[i
][RCOMP
] & 0x1) );
460 else if (format
== GL_BGRA
) {
461 GLushort
*dst
= (GLushort
*) destination
;
463 for (i
= 0; i
< n
; i
++) {
464 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
465 | ((rgba
[i
][RCOMP
] & 0x1f) << 6)
466 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
467 | ((rgba
[i
][BCOMP
] & 0x1) );
471 GLushort
*dst
= (GLushort
*) destination
;
473 ASSERT(format
== GL_ABGR_EXT
);
474 for (i
= 0; i
< n
; i
++) {
475 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
476 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
477 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
478 | ((rgba
[i
][ACOMP
] & 0x1) );
482 case GL_UNSIGNED_INT_8_8_8_8
:
483 if (format
== GL_RGBA
) {
484 GLuint
*dst
= (GLuint
*) destination
;
486 for (i
= 0; i
< n
; i
++) {
487 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
488 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
489 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
490 | ((rgba
[i
][ACOMP
] & 0xff) );
493 else if (format
== GL_BGRA
) {
494 GLuint
*dst
= (GLuint
*) destination
;
496 for (i
= 0; i
< n
; i
++) {
497 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xff) << 24)
498 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
499 | ((rgba
[i
][RCOMP
] & 0xff) << 8)
500 | ((rgba
[i
][ACOMP
] & 0xff) );
504 GLuint
*dst
= (GLuint
*) destination
;
506 ASSERT(format
== GL_ABGR_EXT
);
507 for (i
= 0; i
< n
; i
++) {
508 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
509 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
510 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
511 | ((rgba
[i
][RCOMP
] & 0xff) );
515 case GL_UNSIGNED_INT_8_8_8_8_REV
:
516 if (format
== GL_RGBA
) {
517 GLuint
*dst
= (GLuint
*) destination
;
519 for (i
= 0; i
< n
; i
++) {
520 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
521 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
522 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
523 | ((rgba
[i
][RCOMP
] & 0xff) );
526 else if (format
== GL_BGRA
) {
527 GLuint
*dst
= (GLuint
*) destination
;
529 for (i
= 0; i
< n
; i
++) {
530 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
531 | ((rgba
[i
][RCOMP
] & 0xff) << 16)
532 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
533 | ((rgba
[i
][BCOMP
] & 0xff) );
537 GLuint
*dst
= (GLuint
*) destination
;
539 ASSERT(format
== GL_ABGR_EXT
);
540 for (i
= 0; i
< n
; i
++) {
541 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
542 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
543 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
544 | ((rgba
[i
][ACOMP
] & 0xff) );
548 case GL_UNSIGNED_INT_10_10_10_2
:
549 if (format
== GL_RGBA
) {
550 GLuint
*dst
= (GLuint
*) destination
;
552 for (i
= 0; i
< n
; i
++) {
553 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
554 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
555 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
556 | ((rgba
[i
][ACOMP
] & 0x3) );
559 else if (format
== GL_BGRA
) {
560 GLuint
*dst
= (GLuint
*) destination
;
562 for (i
= 0; i
< n
; i
++) {
563 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3ff) << 22)
564 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
565 | ((rgba
[i
][RCOMP
] & 0x3ff) << 2)
566 | ((rgba
[i
][ACOMP
] & 0x3) );
570 GLuint
*dst
= (GLuint
*) destination
;
572 ASSERT(format
== GL_ABGR_EXT
);
573 for (i
= 0; i
< n
; i
++) {
574 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
575 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
576 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
577 | ((rgba
[i
][RCOMP
] & 0x3) );
581 case GL_UNSIGNED_INT_2_10_10_10_REV
:
582 if (format
== GL_RGBA
) {
583 GLuint
*dst
= (GLuint
*) destination
;
585 for (i
= 0; i
< n
; i
++) {
586 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
587 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
588 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
589 | ((rgba
[i
][RCOMP
] & 0x3) );
592 else if (format
== GL_BGRA
) {
593 GLuint
*dst
= (GLuint
*) destination
;
595 for (i
= 0; i
< n
; i
++) {
596 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
597 | ((rgba
[i
][RCOMP
] & 0x3ff) << 12)
598 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
599 | ((rgba
[i
][BCOMP
] & 0x3) );
603 GLuint
*dst
= (GLuint
*) destination
;
605 ASSERT(format
== GL_ABGR_EXT
);
606 for (i
= 0; i
< n
; i
++) {
607 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
608 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
609 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
610 | ((rgba
[i
][ACOMP
] & 0x3) );
615 _mesa_problem(ctx
, "Bad type in pack_histogram");
623 * Given an internalFormat token passed to glHistogram or glMinMax,
624 * return the corresponding base format.
625 * Return -1 if invalid token.
628 base_histogram_format( GLenum format
)
643 case GL_LUMINANCE_ALPHA
:
644 case GL_LUMINANCE4_ALPHA4
:
645 case GL_LUMINANCE6_ALPHA2
:
646 case GL_LUMINANCE8_ALPHA8
:
647 case GL_LUMINANCE12_ALPHA4
:
648 case GL_LUMINANCE12_ALPHA12
:
649 case GL_LUMINANCE16_ALPHA16
:
650 return GL_LUMINANCE_ALPHA
;
670 return -1; /* error */
676 /**********************************************************************
682 _mesa_GetMinmax(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
684 GET_CURRENT_CONTEXT(ctx
);
685 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
687 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
688 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax");
692 if (target
!= GL_MINMAX
) {
693 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmax(target)");
697 if (format
!= GL_RED
&&
698 format
!= GL_GREEN
&&
700 format
!= GL_ALPHA
&&
705 format
!= GL_ABGR_EXT
&&
706 format
!= GL_LUMINANCE
&&
707 format
!= GL_LUMINANCE_ALPHA
) {
708 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(format)");
711 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
712 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax(format or type)");
720 GLfloat minmax
[2][4];
721 minmax
[0][RCOMP
] = CLAMP(ctx
->MinMax
.Min
[RCOMP
], 0.0F
, 1.0F
);
722 minmax
[0][GCOMP
] = CLAMP(ctx
->MinMax
.Min
[GCOMP
], 0.0F
, 1.0F
);
723 minmax
[0][BCOMP
] = CLAMP(ctx
->MinMax
.Min
[BCOMP
], 0.0F
, 1.0F
);
724 minmax
[0][ACOMP
] = CLAMP(ctx
->MinMax
.Min
[ACOMP
], 0.0F
, 1.0F
);
725 minmax
[1][RCOMP
] = CLAMP(ctx
->MinMax
.Max
[RCOMP
], 0.0F
, 1.0F
);
726 minmax
[1][GCOMP
] = CLAMP(ctx
->MinMax
.Max
[GCOMP
], 0.0F
, 1.0F
);
727 minmax
[1][BCOMP
] = CLAMP(ctx
->MinMax
.Max
[BCOMP
], 0.0F
, 1.0F
);
728 minmax
[1][ACOMP
] = CLAMP(ctx
->MinMax
.Max
[ACOMP
], 0.0F
, 1.0F
);
729 _mesa_pack_rgba_span_float(ctx
, 2, (CONST
GLfloat (*)[4]) minmax
,
730 format
, type
, values
, &ctx
->Pack
, 0);
734 _mesa_ResetMinmax(GL_MINMAX
);
740 _mesa_GetHistogram(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
742 GET_CURRENT_CONTEXT(ctx
);
743 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
745 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
746 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram");
750 if (target
!= GL_HISTOGRAM
) {
751 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(target)");
755 if (format
!= GL_RED
&&
756 format
!= GL_GREEN
&&
758 format
!= GL_ALPHA
&&
763 format
!= GL_ABGR_EXT
&&
764 format
!= GL_LUMINANCE
&&
765 format
!= GL_LUMINANCE_ALPHA
) {
766 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(format)");
769 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
770 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram(format or type)");
777 pack_histogram(ctx
, ctx
->Histogram
.Width
,
778 (CONST
GLuint (*)[4]) ctx
->Histogram
.Count
,
779 format
, type
, values
, &ctx
->Pack
);
783 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
784 ctx
->Histogram
.Count
[i
][0] = 0;
785 ctx
->Histogram
.Count
[i
][1] = 0;
786 ctx
->Histogram
.Count
[i
][2] = 0;
787 ctx
->Histogram
.Count
[i
][3] = 0;
794 _mesa_GetHistogramParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
796 GET_CURRENT_CONTEXT(ctx
);
797 ASSERT_OUTSIDE_BEGIN_END(ctx
);
799 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
800 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameterfv");
804 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
805 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(target)");
810 case GL_HISTOGRAM_WIDTH
:
811 *params
= (GLfloat
) ctx
->Histogram
.Width
;
813 case GL_HISTOGRAM_FORMAT
:
814 *params
= (GLfloat
) ctx
->Histogram
.Format
;
816 case GL_HISTOGRAM_RED_SIZE
:
817 *params
= (GLfloat
) ctx
->Histogram
.RedSize
;
819 case GL_HISTOGRAM_GREEN_SIZE
:
820 *params
= (GLfloat
) ctx
->Histogram
.GreenSize
;
822 case GL_HISTOGRAM_BLUE_SIZE
:
823 *params
= (GLfloat
) ctx
->Histogram
.BlueSize
;
825 case GL_HISTOGRAM_ALPHA_SIZE
:
826 *params
= (GLfloat
) ctx
->Histogram
.AlphaSize
;
828 case GL_HISTOGRAM_LUMINANCE_SIZE
:
829 *params
= (GLfloat
) ctx
->Histogram
.LuminanceSize
;
831 case GL_HISTOGRAM_SINK
:
832 *params
= (GLfloat
) ctx
->Histogram
.Sink
;
835 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(pname)");
841 _mesa_GetHistogramParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
843 GET_CURRENT_CONTEXT(ctx
);
844 ASSERT_OUTSIDE_BEGIN_END(ctx
);
846 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
847 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameteriv");
851 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
852 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(target)");
857 case GL_HISTOGRAM_WIDTH
:
858 *params
= (GLint
) ctx
->Histogram
.Width
;
860 case GL_HISTOGRAM_FORMAT
:
861 *params
= (GLint
) ctx
->Histogram
.Format
;
863 case GL_HISTOGRAM_RED_SIZE
:
864 *params
= (GLint
) ctx
->Histogram
.RedSize
;
866 case GL_HISTOGRAM_GREEN_SIZE
:
867 *params
= (GLint
) ctx
->Histogram
.GreenSize
;
869 case GL_HISTOGRAM_BLUE_SIZE
:
870 *params
= (GLint
) ctx
->Histogram
.BlueSize
;
872 case GL_HISTOGRAM_ALPHA_SIZE
:
873 *params
= (GLint
) ctx
->Histogram
.AlphaSize
;
875 case GL_HISTOGRAM_LUMINANCE_SIZE
:
876 *params
= (GLint
) ctx
->Histogram
.LuminanceSize
;
878 case GL_HISTOGRAM_SINK
:
879 *params
= (GLint
) ctx
->Histogram
.Sink
;
882 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(pname)");
888 _mesa_GetMinmaxParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
890 GET_CURRENT_CONTEXT(ctx
);
891 ASSERT_OUTSIDE_BEGIN_END(ctx
);
893 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
894 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameterfv");
897 if (target
!= GL_MINMAX
) {
898 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameterfv(target)");
901 if (pname
== GL_MINMAX_FORMAT
) {
902 *params
= (GLfloat
) ctx
->MinMax
.Format
;
904 else if (pname
== GL_MINMAX_SINK
) {
905 *params
= (GLfloat
) ctx
->MinMax
.Sink
;
908 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameterfv(pname)");
914 _mesa_GetMinmaxParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
916 GET_CURRENT_CONTEXT(ctx
);
917 ASSERT_OUTSIDE_BEGIN_END(ctx
);
919 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
920 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameteriv");
923 if (target
!= GL_MINMAX
) {
924 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameteriv(target)");
927 if (pname
== GL_MINMAX_FORMAT
) {
928 *params
= (GLint
) ctx
->MinMax
.Format
;
930 else if (pname
== GL_MINMAX_SINK
) {
931 *params
= (GLint
) ctx
->MinMax
.Sink
;
934 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameteriv(pname)");
940 _mesa_Histogram(GLenum target
, GLsizei width
, GLenum internalFormat
, GLboolean sink
)
943 GLboolean error
= GL_FALSE
;
944 GET_CURRENT_CONTEXT(ctx
);
945 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
947 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
948 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glHistogram");
952 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
953 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(target)");
957 if (width
< 0 || width
> HISTOGRAM_TABLE_SIZE
) {
958 if (target
== GL_PROXY_HISTOGRAM
) {
963 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
965 _mesa_error(ctx
, GL_TABLE_TOO_LARGE
, "glHistogram(width)");
970 if (width
!= 0 && _mesa_bitcount(width
) != 1) {
971 if (target
== GL_PROXY_HISTOGRAM
) {
975 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
980 if (base_histogram_format(internalFormat
) < 0) {
981 if (target
== GL_PROXY_HISTOGRAM
) {
985 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(internalFormat)");
990 /* reset histograms */
991 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
992 ctx
->Histogram
.Count
[i
][0] = 0;
993 ctx
->Histogram
.Count
[i
][1] = 0;
994 ctx
->Histogram
.Count
[i
][2] = 0;
995 ctx
->Histogram
.Count
[i
][3] = 0;
999 ctx
->Histogram
.Width
= 0;
1000 ctx
->Histogram
.Format
= 0;
1001 ctx
->Histogram
.RedSize
= 0;
1002 ctx
->Histogram
.GreenSize
= 0;
1003 ctx
->Histogram
.BlueSize
= 0;
1004 ctx
->Histogram
.AlphaSize
= 0;
1005 ctx
->Histogram
.LuminanceSize
= 0;
1008 ctx
->Histogram
.Width
= width
;
1009 ctx
->Histogram
.Format
= internalFormat
;
1010 ctx
->Histogram
.Sink
= sink
;
1011 ctx
->Histogram
.RedSize
= 8 * sizeof(GLuint
);
1012 ctx
->Histogram
.GreenSize
= 8 * sizeof(GLuint
);
1013 ctx
->Histogram
.BlueSize
= 8 * sizeof(GLuint
);
1014 ctx
->Histogram
.AlphaSize
= 8 * sizeof(GLuint
);
1015 ctx
->Histogram
.LuminanceSize
= 8 * sizeof(GLuint
);
1018 ctx
->NewState
|= _NEW_PIXEL
;
1023 _mesa_Minmax(GLenum target
, GLenum internalFormat
, GLboolean sink
)
1025 GET_CURRENT_CONTEXT(ctx
);
1026 ASSERT_OUTSIDE_BEGIN_END(ctx
);
1028 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1029 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glMinmax");
1033 if (target
!= GL_MINMAX
) {
1034 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(target)");
1038 if (base_histogram_format(internalFormat
) < 0) {
1039 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(internalFormat)");
1043 if (ctx
->MinMax
.Sink
== sink
)
1045 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
1046 ctx
->MinMax
.Sink
= sink
;
1051 _mesa_ResetHistogram(GLenum target
)
1054 GET_CURRENT_CONTEXT(ctx
);
1055 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
1057 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1058 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetHistogram");
1062 if (target
!= GL_HISTOGRAM
) {
1063 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetHistogram(target)");
1067 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1068 ctx
->Histogram
.Count
[i
][0] = 0;
1069 ctx
->Histogram
.Count
[i
][1] = 0;
1070 ctx
->Histogram
.Count
[i
][2] = 0;
1071 ctx
->Histogram
.Count
[i
][3] = 0;
1074 ctx
->NewState
|= _NEW_PIXEL
;
1079 _mesa_ResetMinmax(GLenum target
)
1081 GET_CURRENT_CONTEXT(ctx
);
1082 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1084 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1085 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetMinmax");
1089 if (target
!= GL_MINMAX
) {
1090 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetMinMax(target)");
1094 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1095 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1096 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1097 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;
1098 ctx
->NewState
|= _NEW_PIXEL
;
1103 /**********************************************************************/
1104 /***** Initialization *****/
1105 /**********************************************************************/
1107 void _mesa_init_histogram( GLcontext
* ctx
)
1111 /* Histogram group */
1112 ctx
->Histogram
.Width
= 0;
1113 ctx
->Histogram
.Format
= GL_RGBA
;
1114 ctx
->Histogram
.Sink
= GL_FALSE
;
1115 ctx
->Histogram
.RedSize
= 0;
1116 ctx
->Histogram
.GreenSize
= 0;
1117 ctx
->Histogram
.BlueSize
= 0;
1118 ctx
->Histogram
.AlphaSize
= 0;
1119 ctx
->Histogram
.LuminanceSize
= 0;
1120 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1121 ctx
->Histogram
.Count
[i
][0] = 0;
1122 ctx
->Histogram
.Count
[i
][1] = 0;
1123 ctx
->Histogram
.Count
[i
][2] = 0;
1124 ctx
->Histogram
.Count
[i
][3] = 0;
1128 ctx
->MinMax
.Format
= GL_RGBA
;
1129 ctx
->MinMax
.Sink
= GL_FALSE
;
1130 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1131 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1132 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1133 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;