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