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.
27 #include "bufferobj.h"
31 #include "histogram.h"
34 /**********************************************************************
40 * Update the min/max values from an array of fragment colors.
43 _mesa_update_minmax(GLcontext
*ctx
, GLuint n
, const GLfloat rgba
[][4])
46 for (i
= 0; i
< n
; i
++) {
48 if (rgba
[i
][RCOMP
] < ctx
->MinMax
.Min
[RCOMP
])
49 ctx
->MinMax
.Min
[RCOMP
] = rgba
[i
][RCOMP
];
50 if (rgba
[i
][GCOMP
] < ctx
->MinMax
.Min
[GCOMP
])
51 ctx
->MinMax
.Min
[GCOMP
] = rgba
[i
][GCOMP
];
52 if (rgba
[i
][BCOMP
] < ctx
->MinMax
.Min
[BCOMP
])
53 ctx
->MinMax
.Min
[BCOMP
] = rgba
[i
][BCOMP
];
54 if (rgba
[i
][ACOMP
] < ctx
->MinMax
.Min
[ACOMP
])
55 ctx
->MinMax
.Min
[ACOMP
] = rgba
[i
][ACOMP
];
58 if (rgba
[i
][RCOMP
] > ctx
->MinMax
.Max
[RCOMP
])
59 ctx
->MinMax
.Max
[RCOMP
] = rgba
[i
][RCOMP
];
60 if (rgba
[i
][GCOMP
] > ctx
->MinMax
.Max
[GCOMP
])
61 ctx
->MinMax
.Max
[GCOMP
] = rgba
[i
][GCOMP
];
62 if (rgba
[i
][BCOMP
] > ctx
->MinMax
.Max
[BCOMP
])
63 ctx
->MinMax
.Max
[BCOMP
] = rgba
[i
][BCOMP
];
64 if (rgba
[i
][ACOMP
] > ctx
->MinMax
.Max
[ACOMP
])
65 ctx
->MinMax
.Max
[ACOMP
] = rgba
[i
][ACOMP
];
71 * Update the histogram values from an array of fragment colors.
74 _mesa_update_histogram(GLcontext
*ctx
, GLuint n
, const GLfloat rgba
[][4])
76 const GLint max
= ctx
->Histogram
.Width
- 1;
77 GLfloat w
= (GLfloat
) max
;
80 if (ctx
->Histogram
.Width
== 0)
83 for (i
= 0; i
< n
; i
++) {
84 GLint ri
= IROUND(rgba
[i
][RCOMP
] * w
);
85 GLint gi
= IROUND(rgba
[i
][GCOMP
] * w
);
86 GLint bi
= IROUND(rgba
[i
][BCOMP
] * w
);
87 GLint ai
= IROUND(rgba
[i
][ACOMP
] * w
);
88 ri
= CLAMP(ri
, 0, max
);
89 gi
= CLAMP(gi
, 0, max
);
90 bi
= CLAMP(bi
, 0, max
);
91 ai
= CLAMP(ai
, 0, max
);
92 ctx
->Histogram
.Count
[ri
][RCOMP
]++;
93 ctx
->Histogram
.Count
[gi
][GCOMP
]++;
94 ctx
->Histogram
.Count
[bi
][BCOMP
]++;
95 ctx
->Histogram
.Count
[ai
][ACOMP
]++;
101 * XXX the packed pixel formats haven't been tested.
104 pack_histogram( GLcontext
*ctx
,
105 GLuint n
, CONST GLuint rgba
[][4],
106 GLenum format
, GLenum type
, GLvoid
*destination
,
107 const struct gl_pixelstore_attrib
*packing
)
109 const GLint comps
= _mesa_components_in_format(format
);
110 GLuint luminance
[MAX_WIDTH
];
112 if (format
== GL_LUMINANCE
|| format
== GL_LUMINANCE_ALPHA
) {
114 for (i
= 0; i
< n
; i
++) {
115 luminance
[i
] = rgba
[i
][RCOMP
] + rgba
[i
][GCOMP
] + rgba
[i
][BCOMP
];
119 #define PACK_MACRO(TYPE) \
125 dst[i] = (TYPE) rgba[i][RCOMP]; \
129 dst[i] = (TYPE) rgba[i][GCOMP]; \
133 dst[i] = (TYPE) rgba[i][BCOMP]; \
137 dst[i] = (TYPE) rgba[i][ACOMP]; \
141 dst[i] = (TYPE) luminance[i]; \
143 case GL_LUMINANCE_ALPHA: \
144 for (i=0;i<n;i++) { \
145 dst[i*2+0] = (TYPE) luminance[i]; \
146 dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \
150 for (i=0;i<n;i++) { \
151 dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \
152 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
153 dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \
157 for (i=0;i<n;i++) { \
158 dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \
159 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
160 dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \
161 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
165 for (i=0;i<n;i++) { \
166 dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \
167 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
168 dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \
172 for (i=0;i<n;i++) { \
173 dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \
174 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
175 dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \
176 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
180 for (i=0;i<n;i++) { \
181 dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \
182 dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \
183 dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \
184 dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \
188 _mesa_problem(ctx, "bad format in pack_histogram"); \
193 case GL_UNSIGNED_BYTE
:
195 GLubyte
*dst
= (GLubyte
*) destination
;
201 GLbyte
*dst
= (GLbyte
*) destination
;
205 case GL_UNSIGNED_SHORT
:
207 GLushort
*dst
= (GLushort
*) destination
;
208 PACK_MACRO(GLushort
);
209 if (packing
->SwapBytes
) {
210 _mesa_swap2(dst
, n
* comps
);
216 GLshort
*dst
= (GLshort
*) destination
;
218 if (packing
->SwapBytes
) {
219 _mesa_swap2((GLushort
*) dst
, n
* comps
);
223 case GL_UNSIGNED_INT
:
225 GLuint
*dst
= (GLuint
*) destination
;
227 if (packing
->SwapBytes
) {
228 _mesa_swap4(dst
, n
* comps
);
234 GLint
*dst
= (GLint
*) destination
;
236 if (packing
->SwapBytes
) {
237 _mesa_swap4((GLuint
*) dst
, n
* comps
);
243 GLfloat
*dst
= (GLfloat
*) destination
;
245 if (packing
->SwapBytes
) {
246 _mesa_swap4((GLuint
*) dst
, n
* comps
);
250 case GL_HALF_FLOAT_ARB
:
252 /* temporarily store as GLuints */
253 GLuint temp
[4*HISTOGRAM_TABLE_SIZE
];
254 GLhalfARB
*dst
= (GLhalfARB
*) destination
;
256 /* get GLuint values */
258 /* convert to GLhalf */
259 for (i
= 0; i
< n
* comps
; i
++) {
260 dst
[i
] = _mesa_float_to_half((GLfloat
) temp
[i
]);
262 if (packing
->SwapBytes
) {
263 _mesa_swap2((GLushort
*) dst
, n
* comps
);
267 case GL_UNSIGNED_BYTE_3_3_2
:
268 if (format
== GL_RGB
) {
269 GLubyte
*dst
= (GLubyte
*) destination
;
271 for (i
= 0; i
< n
; i
++) {
272 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x7) << 5)
273 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
274 | ((rgba
[i
][BCOMP
] & 0x3) );
278 GLubyte
*dst
= (GLubyte
*) destination
;
280 ASSERT(format
== GL_BGR
);
281 for (i
= 0; i
< n
; i
++) {
282 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x7) << 5)
283 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
284 | ((rgba
[i
][RCOMP
] & 0x3) );
288 case GL_UNSIGNED_BYTE_2_3_3_REV
:
289 if (format
== GL_RGB
) {
290 GLubyte
*dst
= (GLubyte
*) destination
;
292 for (i
= 0; i
< n
; i
++) {
293 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3) << 6)
294 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
295 | ((rgba
[i
][BCOMP
] & 0x7) );
299 GLubyte
*dst
= (GLubyte
*) destination
;
301 ASSERT(format
== GL_BGR
);
302 for (i
= 0; i
< n
; i
++) {
303 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3) << 6)
304 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
305 | ((rgba
[i
][RCOMP
] & 0x7) );
309 case GL_UNSIGNED_SHORT_5_6_5
:
310 if (format
== GL_RGB
) {
311 GLushort
*dst
= (GLushort
*) destination
;
313 for (i
= 0; i
< n
; i
++) {
314 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
315 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
316 | ((rgba
[i
][BCOMP
] & 0x1f) );
320 GLushort
*dst
= (GLushort
*) destination
;
322 ASSERT(format
== GL_BGR
);
323 for (i
= 0; i
< n
; i
++) {
324 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
325 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
326 | ((rgba
[i
][RCOMP
] & 0x1f) );
330 case GL_UNSIGNED_SHORT_5_6_5_REV
:
331 if (format
== GL_RGB
) {
332 GLushort
*dst
= (GLushort
*) destination
;
334 for (i
= 0; i
< n
; i
++) {
335 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
336 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
337 | ((rgba
[i
][RCOMP
] & 0x1f) );
341 GLushort
*dst
= (GLushort
*) destination
;
343 ASSERT(format
== GL_BGR
);
344 for (i
= 0; i
< n
; i
++) {
345 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
346 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
347 | ((rgba
[i
][BCOMP
] & 0x1f) );
351 case GL_UNSIGNED_SHORT_4_4_4_4
:
352 if (format
== GL_RGBA
) {
353 GLushort
*dst
= (GLushort
*) destination
;
355 for (i
= 0; i
< n
; i
++) {
356 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
357 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
358 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
359 | ((rgba
[i
][ACOMP
] & 0xf) );
362 else if (format
== GL_BGRA
) {
363 GLushort
*dst
= (GLushort
*) destination
;
365 for (i
= 0; i
< n
; i
++) {
366 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xf) << 12)
367 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
368 | ((rgba
[i
][RCOMP
] & 0xf) << 4)
369 | ((rgba
[i
][ACOMP
] & 0xf) );
373 GLushort
*dst
= (GLushort
*) destination
;
375 ASSERT(format
== GL_ABGR_EXT
);
376 for (i
= 0; i
< n
; i
++) {
377 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
378 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
379 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
380 | ((rgba
[i
][RCOMP
] & 0xf) );
384 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
385 if (format
== GL_RGBA
) {
386 GLushort
*dst
= (GLushort
*) destination
;
388 for (i
= 0; i
< n
; i
++) {
389 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
390 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
391 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
392 | ((rgba
[i
][RCOMP
] & 0xf) );
395 else if (format
== GL_BGRA
) {
396 GLushort
*dst
= (GLushort
*) destination
;
398 for (i
= 0; i
< n
; i
++) {
399 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
400 | ((rgba
[i
][RCOMP
] & 0xf) << 8)
401 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
402 | ((rgba
[i
][BCOMP
] & 0xf) );
406 GLushort
*dst
= (GLushort
*) destination
;
408 ASSERT(format
== GL_ABGR_EXT
);
409 for (i
= 0; i
< n
; i
++) {
410 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
411 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
412 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
413 | ((rgba
[i
][ACOMP
] & 0xf) );
417 case GL_UNSIGNED_SHORT_5_5_5_1
:
418 if (format
== GL_RGBA
) {
419 GLushort
*dst
= (GLushort
*) destination
;
421 for (i
= 0; i
< n
; i
++) {
422 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
423 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
424 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
425 | ((rgba
[i
][ACOMP
] & 0x1) );
428 else if (format
== GL_BGRA
) {
429 GLushort
*dst
= (GLushort
*) destination
;
431 for (i
= 0; i
< n
; i
++) {
432 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
433 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
434 | ((rgba
[i
][RCOMP
] & 0x1f) << 1)
435 | ((rgba
[i
][ACOMP
] & 0x1) );
439 GLushort
*dst
= (GLushort
*) destination
;
441 ASSERT(format
== GL_ABGR_EXT
);
442 for (i
= 0; i
< n
; i
++) {
443 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
444 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
445 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
446 | ((rgba
[i
][RCOMP
] & 0x1) );
450 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
451 if (format
== GL_RGBA
) {
452 GLushort
*dst
= (GLushort
*) destination
;
454 for (i
= 0; i
< n
; i
++) {
455 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
456 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
457 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
458 | ((rgba
[i
][RCOMP
] & 0x1) );
461 else if (format
== GL_BGRA
) {
462 GLushort
*dst
= (GLushort
*) destination
;
464 for (i
= 0; i
< n
; i
++) {
465 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
466 | ((rgba
[i
][RCOMP
] & 0x1f) << 6)
467 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
468 | ((rgba
[i
][BCOMP
] & 0x1) );
472 GLushort
*dst
= (GLushort
*) destination
;
474 ASSERT(format
== GL_ABGR_EXT
);
475 for (i
= 0; i
< n
; i
++) {
476 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
477 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
478 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
479 | ((rgba
[i
][ACOMP
] & 0x1) );
483 case GL_UNSIGNED_INT_8_8_8_8
:
484 if (format
== GL_RGBA
) {
485 GLuint
*dst
= (GLuint
*) destination
;
487 for (i
= 0; i
< n
; i
++) {
488 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
489 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
490 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
491 | ((rgba
[i
][ACOMP
] & 0xff) );
494 else if (format
== GL_BGRA
) {
495 GLuint
*dst
= (GLuint
*) destination
;
497 for (i
= 0; i
< n
; i
++) {
498 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xff) << 24)
499 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
500 | ((rgba
[i
][RCOMP
] & 0xff) << 8)
501 | ((rgba
[i
][ACOMP
] & 0xff) );
505 GLuint
*dst
= (GLuint
*) destination
;
507 ASSERT(format
== GL_ABGR_EXT
);
508 for (i
= 0; i
< n
; i
++) {
509 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
510 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
511 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
512 | ((rgba
[i
][RCOMP
] & 0xff) );
516 case GL_UNSIGNED_INT_8_8_8_8_REV
:
517 if (format
== GL_RGBA
) {
518 GLuint
*dst
= (GLuint
*) destination
;
520 for (i
= 0; i
< n
; i
++) {
521 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
522 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
523 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
524 | ((rgba
[i
][RCOMP
] & 0xff) );
527 else if (format
== GL_BGRA
) {
528 GLuint
*dst
= (GLuint
*) destination
;
530 for (i
= 0; i
< n
; i
++) {
531 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
532 | ((rgba
[i
][RCOMP
] & 0xff) << 16)
533 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
534 | ((rgba
[i
][BCOMP
] & 0xff) );
538 GLuint
*dst
= (GLuint
*) destination
;
540 ASSERT(format
== GL_ABGR_EXT
);
541 for (i
= 0; i
< n
; i
++) {
542 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
543 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
544 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
545 | ((rgba
[i
][ACOMP
] & 0xff) );
549 case GL_UNSIGNED_INT_10_10_10_2
:
550 if (format
== GL_RGBA
) {
551 GLuint
*dst
= (GLuint
*) destination
;
553 for (i
= 0; i
< n
; i
++) {
554 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
555 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
556 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
557 | ((rgba
[i
][ACOMP
] & 0x3) );
560 else if (format
== GL_BGRA
) {
561 GLuint
*dst
= (GLuint
*) destination
;
563 for (i
= 0; i
< n
; i
++) {
564 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3ff) << 22)
565 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
566 | ((rgba
[i
][RCOMP
] & 0x3ff) << 2)
567 | ((rgba
[i
][ACOMP
] & 0x3) );
571 GLuint
*dst
= (GLuint
*) destination
;
573 ASSERT(format
== GL_ABGR_EXT
);
574 for (i
= 0; i
< n
; i
++) {
575 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
576 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
577 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
578 | ((rgba
[i
][RCOMP
] & 0x3) );
582 case GL_UNSIGNED_INT_2_10_10_10_REV
:
583 if (format
== GL_RGBA
) {
584 GLuint
*dst
= (GLuint
*) destination
;
586 for (i
= 0; i
< n
; i
++) {
587 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
588 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
589 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
590 | ((rgba
[i
][RCOMP
] & 0x3) );
593 else if (format
== GL_BGRA
) {
594 GLuint
*dst
= (GLuint
*) destination
;
596 for (i
= 0; i
< n
; i
++) {
597 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
598 | ((rgba
[i
][RCOMP
] & 0x3ff) << 12)
599 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
600 | ((rgba
[i
][BCOMP
] & 0x3) );
604 GLuint
*dst
= (GLuint
*) destination
;
606 ASSERT(format
== GL_ABGR_EXT
);
607 for (i
= 0; i
< n
; i
++) {
608 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
609 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
610 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
611 | ((rgba
[i
][ACOMP
] & 0x3) );
616 _mesa_problem(ctx
, "Bad type in pack_histogram");
624 * Given an internalFormat token passed to glHistogram or glMinMax,
625 * return the corresponding base format.
626 * Return -1 if invalid token.
629 base_histogram_format( GLenum format
)
644 case GL_LUMINANCE_ALPHA
:
645 case GL_LUMINANCE4_ALPHA4
:
646 case GL_LUMINANCE6_ALPHA2
:
647 case GL_LUMINANCE8_ALPHA8
:
648 case GL_LUMINANCE12_ALPHA4
:
649 case GL_LUMINANCE12_ALPHA12
:
650 case GL_LUMINANCE16_ALPHA16
:
651 return GL_LUMINANCE_ALPHA
;
671 return -1; /* error */
677 /**********************************************************************
683 _mesa_GetMinmax(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
685 GET_CURRENT_CONTEXT(ctx
);
686 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
688 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
689 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax");
693 if (target
!= GL_MINMAX
) {
694 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmax(target)");
698 if (format
!= GL_RED
&&
699 format
!= GL_GREEN
&&
701 format
!= GL_ALPHA
&&
706 format
!= GL_ABGR_EXT
&&
707 format
!= GL_LUMINANCE
&&
708 format
!= GL_LUMINANCE_ALPHA
) {
709 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMax(format)");
712 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
713 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax(format or type)");
717 if (ctx
->Pack
.BufferObj
->Name
) {
718 /* pack min/max values into a PBO */
720 if (!_mesa_validate_pbo_access(1, &ctx
->Pack
, 2, 1, 1,
721 format
, type
, values
)) {
722 _mesa_error(ctx
, GL_INVALID_OPERATION
,
723 "glGetMinMax(invalid PBO access)");
726 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
728 ctx
->Pack
.BufferObj
);
730 /* buffer is already mapped - that's an error */
731 _mesa_error(ctx
, GL_INVALID_OPERATION
,"glGetMinMax(PBO is mapped)");
734 values
= ADD_POINTERS(buf
, values
);
742 GLfloat minmax
[2][4];
743 minmax
[0][RCOMP
] = CLAMP(ctx
->MinMax
.Min
[RCOMP
], 0.0F
, 1.0F
);
744 minmax
[0][GCOMP
] = CLAMP(ctx
->MinMax
.Min
[GCOMP
], 0.0F
, 1.0F
);
745 minmax
[0][BCOMP
] = CLAMP(ctx
->MinMax
.Min
[BCOMP
], 0.0F
, 1.0F
);
746 minmax
[0][ACOMP
] = CLAMP(ctx
->MinMax
.Min
[ACOMP
], 0.0F
, 1.0F
);
747 minmax
[1][RCOMP
] = CLAMP(ctx
->MinMax
.Max
[RCOMP
], 0.0F
, 1.0F
);
748 minmax
[1][GCOMP
] = CLAMP(ctx
->MinMax
.Max
[GCOMP
], 0.0F
, 1.0F
);
749 minmax
[1][BCOMP
] = CLAMP(ctx
->MinMax
.Max
[BCOMP
], 0.0F
, 1.0F
);
750 minmax
[1][ACOMP
] = CLAMP(ctx
->MinMax
.Max
[ACOMP
], 0.0F
, 1.0F
);
751 _mesa_pack_rgba_span_float(ctx
, 2, minmax
,
752 format
, type
, values
, &ctx
->Pack
, 0x0);
755 if (ctx
->Pack
.BufferObj
->Name
) {
756 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
757 ctx
->Pack
.BufferObj
);
761 _mesa_ResetMinmax(GL_MINMAX
);
767 _mesa_GetHistogram(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
769 GET_CURRENT_CONTEXT(ctx
);
770 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
772 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
773 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram");
777 if (target
!= GL_HISTOGRAM
) {
778 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(target)");
782 if (format
!= GL_RED
&&
783 format
!= GL_GREEN
&&
785 format
!= GL_ALPHA
&&
790 format
!= GL_ABGR_EXT
&&
791 format
!= GL_LUMINANCE
&&
792 format
!= GL_LUMINANCE_ALPHA
) {
793 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(format)");
796 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
797 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram(format or type)");
801 if (ctx
->Pack
.BufferObj
->Name
) {
802 /* pack min/max values into a PBO */
804 if (!_mesa_validate_pbo_access(1, &ctx
->Pack
, ctx
->Histogram
.Width
, 1, 1,
805 format
, type
, values
)) {
806 _mesa_error(ctx
, GL_INVALID_OPERATION
,
807 "glGetHistogram(invalid PBO access)");
810 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
812 ctx
->Pack
.BufferObj
);
814 /* buffer is already mapped - that's an error */
815 _mesa_error(ctx
,GL_INVALID_OPERATION
,"glGetHistogram(PBO is mapped)");
818 values
= ADD_POINTERS(buf
, values
);
825 pack_histogram(ctx
, ctx
->Histogram
.Width
,
826 (CONST
GLuint (*)[4]) ctx
->Histogram
.Count
,
827 format
, type
, values
, &ctx
->Pack
);
829 if (ctx
->Pack
.BufferObj
->Name
) {
830 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
831 ctx
->Pack
.BufferObj
);
836 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
837 ctx
->Histogram
.Count
[i
][0] = 0;
838 ctx
->Histogram
.Count
[i
][1] = 0;
839 ctx
->Histogram
.Count
[i
][2] = 0;
840 ctx
->Histogram
.Count
[i
][3] = 0;
847 _mesa_GetHistogramParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
849 GET_CURRENT_CONTEXT(ctx
);
850 ASSERT_OUTSIDE_BEGIN_END(ctx
);
852 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
853 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameterfv");
857 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
858 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(target)");
863 case GL_HISTOGRAM_WIDTH
:
864 *params
= (GLfloat
) ctx
->Histogram
.Width
;
866 case GL_HISTOGRAM_FORMAT
:
867 *params
= (GLfloat
) ctx
->Histogram
.Format
;
869 case GL_HISTOGRAM_RED_SIZE
:
870 *params
= (GLfloat
) ctx
->Histogram
.RedSize
;
872 case GL_HISTOGRAM_GREEN_SIZE
:
873 *params
= (GLfloat
) ctx
->Histogram
.GreenSize
;
875 case GL_HISTOGRAM_BLUE_SIZE
:
876 *params
= (GLfloat
) ctx
->Histogram
.BlueSize
;
878 case GL_HISTOGRAM_ALPHA_SIZE
:
879 *params
= (GLfloat
) ctx
->Histogram
.AlphaSize
;
881 case GL_HISTOGRAM_LUMINANCE_SIZE
:
882 *params
= (GLfloat
) ctx
->Histogram
.LuminanceSize
;
884 case GL_HISTOGRAM_SINK
:
885 *params
= (GLfloat
) ctx
->Histogram
.Sink
;
888 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(pname)");
894 _mesa_GetHistogramParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
896 GET_CURRENT_CONTEXT(ctx
);
897 ASSERT_OUTSIDE_BEGIN_END(ctx
);
899 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
900 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameteriv");
904 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
905 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(target)");
910 case GL_HISTOGRAM_WIDTH
:
911 *params
= (GLint
) ctx
->Histogram
.Width
;
913 case GL_HISTOGRAM_FORMAT
:
914 *params
= (GLint
) ctx
->Histogram
.Format
;
916 case GL_HISTOGRAM_RED_SIZE
:
917 *params
= (GLint
) ctx
->Histogram
.RedSize
;
919 case GL_HISTOGRAM_GREEN_SIZE
:
920 *params
= (GLint
) ctx
->Histogram
.GreenSize
;
922 case GL_HISTOGRAM_BLUE_SIZE
:
923 *params
= (GLint
) ctx
->Histogram
.BlueSize
;
925 case GL_HISTOGRAM_ALPHA_SIZE
:
926 *params
= (GLint
) ctx
->Histogram
.AlphaSize
;
928 case GL_HISTOGRAM_LUMINANCE_SIZE
:
929 *params
= (GLint
) ctx
->Histogram
.LuminanceSize
;
931 case GL_HISTOGRAM_SINK
:
932 *params
= (GLint
) ctx
->Histogram
.Sink
;
935 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(pname)");
941 _mesa_GetMinmaxParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
943 GET_CURRENT_CONTEXT(ctx
);
944 ASSERT_OUTSIDE_BEGIN_END(ctx
);
946 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
947 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameterfv");
950 if (target
!= GL_MINMAX
) {
951 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameterfv(target)");
954 if (pname
== GL_MINMAX_FORMAT
) {
955 *params
= (GLfloat
) ctx
->MinMax
.Format
;
957 else if (pname
== GL_MINMAX_SINK
) {
958 *params
= (GLfloat
) ctx
->MinMax
.Sink
;
961 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameterfv(pname)");
967 _mesa_GetMinmaxParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
969 GET_CURRENT_CONTEXT(ctx
);
970 ASSERT_OUTSIDE_BEGIN_END(ctx
);
972 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
973 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameteriv");
976 if (target
!= GL_MINMAX
) {
977 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameteriv(target)");
980 if (pname
== GL_MINMAX_FORMAT
) {
981 *params
= (GLint
) ctx
->MinMax
.Format
;
983 else if (pname
== GL_MINMAX_SINK
) {
984 *params
= (GLint
) ctx
->MinMax
.Sink
;
987 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameteriv(pname)");
993 _mesa_Histogram(GLenum target
, GLsizei width
, GLenum internalFormat
, GLboolean sink
)
996 GLboolean error
= GL_FALSE
;
997 GET_CURRENT_CONTEXT(ctx
);
998 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
1000 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1001 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glHistogram");
1005 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
1006 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(target)");
1010 if (width
< 0 || width
> HISTOGRAM_TABLE_SIZE
) {
1011 if (target
== GL_PROXY_HISTOGRAM
) {
1016 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
1018 _mesa_error(ctx
, GL_TABLE_TOO_LARGE
, "glHistogram(width)");
1023 if (width
!= 0 && _mesa_bitcount(width
) != 1) {
1024 if (target
== GL_PROXY_HISTOGRAM
) {
1028 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
1033 if (base_histogram_format(internalFormat
) < 0) {
1034 if (target
== GL_PROXY_HISTOGRAM
) {
1038 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(internalFormat)");
1043 /* reset histograms */
1044 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1045 ctx
->Histogram
.Count
[i
][0] = 0;
1046 ctx
->Histogram
.Count
[i
][1] = 0;
1047 ctx
->Histogram
.Count
[i
][2] = 0;
1048 ctx
->Histogram
.Count
[i
][3] = 0;
1052 ctx
->Histogram
.Width
= 0;
1053 ctx
->Histogram
.Format
= 0;
1054 ctx
->Histogram
.RedSize
= 0;
1055 ctx
->Histogram
.GreenSize
= 0;
1056 ctx
->Histogram
.BlueSize
= 0;
1057 ctx
->Histogram
.AlphaSize
= 0;
1058 ctx
->Histogram
.LuminanceSize
= 0;
1061 ctx
->Histogram
.Width
= width
;
1062 ctx
->Histogram
.Format
= internalFormat
;
1063 ctx
->Histogram
.Sink
= sink
;
1064 ctx
->Histogram
.RedSize
= 8 * sizeof(GLuint
);
1065 ctx
->Histogram
.GreenSize
= 8 * sizeof(GLuint
);
1066 ctx
->Histogram
.BlueSize
= 8 * sizeof(GLuint
);
1067 ctx
->Histogram
.AlphaSize
= 8 * sizeof(GLuint
);
1068 ctx
->Histogram
.LuminanceSize
= 8 * sizeof(GLuint
);
1071 ctx
->NewState
|= _NEW_PIXEL
;
1076 _mesa_Minmax(GLenum target
, GLenum internalFormat
, GLboolean sink
)
1078 GET_CURRENT_CONTEXT(ctx
);
1079 ASSERT_OUTSIDE_BEGIN_END(ctx
);
1081 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1082 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glMinmax");
1086 if (target
!= GL_MINMAX
) {
1087 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(target)");
1091 if (base_histogram_format(internalFormat
) < 0) {
1092 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(internalFormat)");
1096 if (ctx
->MinMax
.Sink
== sink
)
1098 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
1099 ctx
->MinMax
.Sink
= sink
;
1104 _mesa_ResetHistogram(GLenum target
)
1107 GET_CURRENT_CONTEXT(ctx
);
1108 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
1110 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1111 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetHistogram");
1115 if (target
!= GL_HISTOGRAM
) {
1116 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetHistogram(target)");
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;
1127 ctx
->NewState
|= _NEW_PIXEL
;
1132 _mesa_ResetMinmax(GLenum target
)
1134 GET_CURRENT_CONTEXT(ctx
);
1135 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1137 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1138 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetMinmax");
1142 if (target
!= GL_MINMAX
) {
1143 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetMinMax(target)");
1147 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1148 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1149 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1150 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;
1151 ctx
->NewState
|= _NEW_PIXEL
;
1156 /**********************************************************************/
1157 /***** Initialization *****/
1158 /**********************************************************************/
1160 void _mesa_init_histogram( GLcontext
* ctx
)
1164 /* Histogram group */
1165 ctx
->Histogram
.Width
= 0;
1166 ctx
->Histogram
.Format
= GL_RGBA
;
1167 ctx
->Histogram
.Sink
= GL_FALSE
;
1168 ctx
->Histogram
.RedSize
= 0;
1169 ctx
->Histogram
.GreenSize
= 0;
1170 ctx
->Histogram
.BlueSize
= 0;
1171 ctx
->Histogram
.AlphaSize
= 0;
1172 ctx
->Histogram
.LuminanceSize
= 0;
1173 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1174 ctx
->Histogram
.Count
[i
][0] = 0;
1175 ctx
->Histogram
.Count
[i
][1] = 0;
1176 ctx
->Histogram
.Count
[i
][2] = 0;
1177 ctx
->Histogram
.Count
[i
][3] = 0;
1181 ctx
->MinMax
.Format
= GL_RGBA
;
1182 ctx
->MinMax
.Sink
= GL_FALSE
;
1183 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1184 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1185 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1186 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;