generate GL_INVALID_OPERATION error for bad image format/type combinations
[mesa.git] / src / mesa / main / histogram.c
1 /* $Id: histogram.c,v 1.3 2000/12/10 19:23:19 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 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 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "colormac.h"
33 #include "context.h"
34 #include "image.h"
35 #include "histogram.h"
36 #include "mmath.h"
37 #endif
38
39
40 /*
41 * XXX need to handle packed datatypes!
42 */
43 static void
44 pack_histogram( GLcontext *ctx,
45 GLuint n, CONST GLuint rgba[][4],
46 GLenum format, GLenum type, GLvoid *destination,
47 const struct gl_pixelstore_attrib *packing )
48 {
49 const GLint comps = _mesa_components_in_format(format);
50 GLuint luminance[MAX_WIDTH];
51
52 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
53 GLuint i;
54 for (i = 0; i < n; i++) {
55 luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
56 }
57 }
58
59 #define PACK_MACRO(TYPE) \
60 { \
61 GLuint i; \
62 switch (format) { \
63 case GL_RED: \
64 for (i=0;i<n;i++) \
65 dst[i] = (TYPE) rgba[i][RCOMP]; \
66 break; \
67 case GL_GREEN: \
68 for (i=0;i<n;i++) \
69 dst[i] = (TYPE) rgba[i][GCOMP]; \
70 break; \
71 case GL_BLUE: \
72 for (i=0;i<n;i++) \
73 dst[i] = (TYPE) rgba[i][BCOMP]; \
74 break; \
75 case GL_ALPHA: \
76 for (i=0;i<n;i++) \
77 dst[i] = (TYPE) rgba[i][ACOMP]; \
78 break; \
79 case GL_LUMINANCE: \
80 for (i=0;i<n;i++) \
81 dst[i] = (TYPE) luminance[i]; \
82 break; \
83 case GL_LUMINANCE_ALPHA: \
84 for (i=0;i<n;i++) { \
85 dst[i*2+0] = (TYPE) luminance[i]; \
86 dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \
87 } \
88 break; \
89 case GL_RGB: \
90 for (i=0;i<n;i++) { \
91 dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \
92 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
93 dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \
94 } \
95 break; \
96 case GL_RGBA: \
97 for (i=0;i<n;i++) { \
98 dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \
99 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
100 dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \
101 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
102 } \
103 break; \
104 case GL_BGR: \
105 for (i=0;i<n;i++) { \
106 dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \
107 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
108 dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \
109 } \
110 break; \
111 case GL_BGRA: \
112 for (i=0;i<n;i++) { \
113 dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \
114 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
115 dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \
116 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
117 } \
118 break; \
119 case GL_ABGR_EXT: \
120 for (i=0;i<n;i++) { \
121 dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \
122 dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \
123 dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \
124 dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \
125 } \
126 break; \
127 default: \
128 gl_problem(ctx, "bad format in pack_histogram"); \
129 } \
130 }
131
132 switch (type) {
133 case GL_UNSIGNED_BYTE:
134 {
135 GLubyte *dst = (GLubyte *) destination;
136 PACK_MACRO(GLubyte);
137 }
138 break;
139 case GL_BYTE:
140 {
141 GLbyte *dst = (GLbyte *) destination;
142 PACK_MACRO(GLbyte);
143 }
144 break;
145 case GL_UNSIGNED_SHORT:
146 {
147 GLushort *dst = (GLushort *) destination;
148 PACK_MACRO(GLushort);
149 if (packing->SwapBytes) {
150 _mesa_swap2(dst, n * comps);
151 }
152 }
153 break;
154 case GL_SHORT:
155 {
156 GLshort *dst = (GLshort *) destination;
157 PACK_MACRO(GLshort);
158 if (packing->SwapBytes) {
159 _mesa_swap2((GLushort *) dst, n * comps);
160 }
161 }
162 break;
163 case GL_UNSIGNED_INT:
164 {
165 GLuint *dst = (GLuint *) destination;
166 PACK_MACRO(GLuint);
167 if (packing->SwapBytes) {
168 _mesa_swap4(dst, n * comps);
169 }
170 }
171 break;
172 case GL_INT:
173 {
174 GLint *dst = (GLint *) destination;
175 PACK_MACRO(GLint);
176 if (packing->SwapBytes) {
177 _mesa_swap4((GLuint *) dst, n * comps);
178 }
179 }
180 break;
181 case GL_FLOAT:
182 {
183 GLfloat *dst = (GLfloat *) destination;
184 PACK_MACRO(GLfloat);
185 if (packing->SwapBytes) {
186 _mesa_swap4((GLuint *) dst, n * comps);
187 }
188 }
189 break;
190 default:
191 gl_problem(ctx, "Bad type in pack_histogram");
192 }
193
194 #undef PACK_MACRO
195 }
196
197
198
199 /*
200 * XXX need to handle packed datatypes!
201 */
202 static void
203 pack_minmax( GLcontext *ctx, CONST GLfloat minmax[2][4],
204 GLenum format, GLenum type, GLvoid *destination,
205 const struct gl_pixelstore_attrib *packing )
206 {
207 const GLint comps = _mesa_components_in_format(format);
208 GLuint luminance[2];
209
210 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
211 luminance[0] = minmax[0][RCOMP] + minmax[0][GCOMP] + minmax[0][BCOMP];
212 luminance[1] = minmax[1][RCOMP] + minmax[1][GCOMP] + minmax[1][BCOMP];
213 }
214
215 #define PACK_MACRO(TYPE, CONVERSION) \
216 { \
217 GLuint i; \
218 switch (format) { \
219 case GL_RED: \
220 for (i=0;i<2;i++) \
221 dst[i] = CONVERSION (minmax[i][RCOMP]); \
222 break; \
223 case GL_GREEN: \
224 for (i=0;i<2;i++) \
225 dst[i] = CONVERSION (minmax[i][GCOMP]); \
226 break; \
227 case GL_BLUE: \
228 for (i=0;i<2;i++) \
229 dst[i] = CONVERSION (minmax[i][BCOMP]); \
230 break; \
231 case GL_ALPHA: \
232 for (i=0;i<2;i++) \
233 dst[i] = CONVERSION (minmax[i][ACOMP]); \
234 break; \
235 case GL_LUMINANCE: \
236 for (i=0;i<2;i++) \
237 dst[i] = CONVERSION (luminance[i]); \
238 break; \
239 case GL_LUMINANCE_ALPHA: \
240 for (i=0;i<2;i++) { \
241 dst[i*2+0] = CONVERSION (luminance[i]); \
242 dst[i*2+1] = CONVERSION (minmax[i][ACOMP]); \
243 } \
244 break; \
245 case GL_RGB: \
246 for (i=0;i<2;i++) { \
247 dst[i*3+0] = CONVERSION (minmax[i][RCOMP]); \
248 dst[i*3+1] = CONVERSION (minmax[i][GCOMP]); \
249 dst[i*3+2] = CONVERSION (minmax[i][BCOMP]); \
250 } \
251 break; \
252 case GL_RGBA: \
253 for (i=0;i<2;i++) { \
254 dst[i*4+0] = CONVERSION (minmax[i][RCOMP]); \
255 dst[i*4+1] = CONVERSION (minmax[i][GCOMP]); \
256 dst[i*4+2] = CONVERSION (minmax[i][BCOMP]); \
257 dst[i*4+3] = CONVERSION (minmax[i][ACOMP]); \
258 } \
259 break; \
260 case GL_BGR: \
261 for (i=0;i<2;i++) { \
262 dst[i*3+0] = CONVERSION (minmax[i][BCOMP]); \
263 dst[i*3+1] = CONVERSION (minmax[i][GCOMP]); \
264 dst[i*3+2] = CONVERSION (minmax[i][RCOMP]); \
265 } \
266 break; \
267 case GL_BGRA: \
268 for (i=0;i<2;i++) { \
269 dst[i*4+0] = CONVERSION (minmax[i][BCOMP]); \
270 dst[i*4+1] = CONVERSION (minmax[i][GCOMP]); \
271 dst[i*4+2] = CONVERSION (minmax[i][RCOMP]); \
272 dst[i*4+3] = CONVERSION (minmax[i][ACOMP]); \
273 } \
274 break; \
275 case GL_ABGR_EXT: \
276 for (i=0;i<2;i++) { \
277 dst[i*4+0] = CONVERSION (minmax[i][ACOMP]); \
278 dst[i*4+1] = CONVERSION (minmax[i][BCOMP]); \
279 dst[i*4+2] = CONVERSION (minmax[i][GCOMP]); \
280 dst[i*4+3] = CONVERSION (minmax[i][RCOMP]); \
281 } \
282 break; \
283 default: \
284 gl_problem(ctx, "bad format in pack_minmax"); \
285 } \
286 }
287
288 switch (type) {
289 case GL_UNSIGNED_BYTE:
290 {
291 GLubyte *dst = (GLubyte *) destination;
292 PACK_MACRO(GLubyte, FLOAT_TO_UBYTE);
293 }
294 break;
295 case GL_BYTE:
296 {
297 GLbyte *dst = (GLbyte *) destination;
298 PACK_MACRO(GLbyte, FLOAT_TO_BYTE);
299 }
300 break;
301 case GL_UNSIGNED_SHORT:
302 {
303 GLushort *dst = (GLushort *) destination;
304 PACK_MACRO(GLushort, FLOAT_TO_USHORT);
305 if (packing->SwapBytes) {
306 _mesa_swap2(dst, 2 * comps);
307 }
308 }
309 break;
310 case GL_SHORT:
311 {
312 GLshort *dst = (GLshort *) destination;
313 PACK_MACRO(GLshort, FLOAT_TO_SHORT);
314 if (packing->SwapBytes) {
315 _mesa_swap2((GLushort *) dst, 2 * comps);
316 }
317 }
318 break;
319 case GL_UNSIGNED_INT:
320 {
321 GLuint *dst = (GLuint *) destination;
322 PACK_MACRO(GLuint, FLOAT_TO_UINT);
323 if (packing->SwapBytes) {
324 _mesa_swap4(dst, 2 * comps);
325 }
326 }
327 break;
328 case GL_INT:
329 {
330 GLint *dst = (GLint *) destination;
331 PACK_MACRO(GLint, FLOAT_TO_INT);
332 if (packing->SwapBytes) {
333 _mesa_swap4((GLuint *) dst, 2 * comps);
334 }
335 }
336 break;
337 case GL_FLOAT:
338 {
339 GLfloat *dst = (GLfloat *) destination;
340 PACK_MACRO(GLfloat, (GLfloat));
341 if (packing->SwapBytes) {
342 _mesa_swap4((GLuint *) dst, 2 * comps);
343 }
344 }
345 break;
346 default:
347 gl_problem(ctx, "Bad type in pack_minmax");
348 }
349
350 #undef PACK_MACRO
351 }
352
353
354 /*
355 * Given an internalFormat token passed to glHistogram or glMinMax,
356 * return the corresponding base format.
357 * Return -1 if invalid token.
358 */
359 static GLint
360 base_histogram_format( GLenum format )
361 {
362 switch (format) {
363 case GL_ALPHA:
364 case GL_ALPHA4:
365 case GL_ALPHA8:
366 case GL_ALPHA12:
367 case GL_ALPHA16:
368 return GL_ALPHA;
369 case GL_LUMINANCE:
370 case GL_LUMINANCE4:
371 case GL_LUMINANCE8:
372 case GL_LUMINANCE12:
373 case GL_LUMINANCE16:
374 return GL_LUMINANCE;
375 case GL_LUMINANCE_ALPHA:
376 case GL_LUMINANCE4_ALPHA4:
377 case GL_LUMINANCE6_ALPHA2:
378 case GL_LUMINANCE8_ALPHA8:
379 case GL_LUMINANCE12_ALPHA4:
380 case GL_LUMINANCE12_ALPHA12:
381 case GL_LUMINANCE16_ALPHA16:
382 return GL_LUMINANCE_ALPHA;
383 case GL_RGB:
384 case GL_R3_G3_B2:
385 case GL_RGB4:
386 case GL_RGB5:
387 case GL_RGB8:
388 case GL_RGB10:
389 case GL_RGB12:
390 case GL_RGB16:
391 return GL_RGB;
392 case GL_RGBA:
393 case GL_RGBA2:
394 case GL_RGBA4:
395 case GL_RGB5_A1:
396 case GL_RGBA8:
397 case GL_RGB10_A2:
398 case GL_RGBA12:
399 case GL_RGBA16:
400 return GL_RGBA;
401 default:
402 return -1; /* error */
403 }
404 }
405
406
407 void
408 _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
409 {
410 GET_CURRENT_CONTEXT(ctx);
411 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMinmax");
412
413 if (!ctx->Extensions.EXT_histogram) {
414 gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmax");
415 return;
416 }
417
418 if (target != GL_MINMAX) {
419 gl_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)");
420 return;
421 }
422
423 if (!_mesa_is_legal_format_and_type(format, type)) {
424 gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)");
425 return;
426 }
427
428 if (!values)
429 return;
430
431 {
432 GLfloat minmax[2][4];
433 minmax[0][RCOMP] = CLAMP(ctx->MinMax.Min[RCOMP], 0.0F, 1.0F);
434 minmax[0][GCOMP] = CLAMP(ctx->MinMax.Min[GCOMP], 0.0F, 1.0F);
435 minmax[0][BCOMP] = CLAMP(ctx->MinMax.Min[BCOMP], 0.0F, 1.0F);
436 minmax[0][ACOMP] = CLAMP(ctx->MinMax.Min[ACOMP], 0.0F, 1.0F);
437 minmax[1][RCOMP] = CLAMP(ctx->MinMax.Max[RCOMP], 0.0F, 1.0F);
438 minmax[1][GCOMP] = CLAMP(ctx->MinMax.Max[GCOMP], 0.0F, 1.0F);
439 minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
440 minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
441 pack_minmax(ctx, (CONST GLfloat (*)[4]) minmax,
442 format, type, values, &ctx->Pack);
443 }
444
445 if (reset) {
446 _mesa_ResetMinmax(GL_MINMAX);
447 }
448 }
449
450
451 void
452 _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
453 {
454 GET_CURRENT_CONTEXT(ctx);
455 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetHistogram");
456
457 if (!ctx->Extensions.EXT_histogram) {
458 gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogram");
459 return;
460 }
461
462 if (target != GL_HISTOGRAM) {
463 gl_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)");
464 return;
465 }
466
467 if (!_mesa_is_legal_format_and_type(format, type)) {
468 gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)");
469 return;
470 }
471
472 if (!values)
473 return;
474
475 pack_histogram(ctx, ctx->Histogram.Width,
476 (CONST GLuint (*)[4]) ctx->Histogram.Count,
477 format, type, values, &ctx->Pack);
478
479 if (reset) {
480 GLuint i;
481 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
482 ctx->Histogram.Count[i][0] = 0;
483 ctx->Histogram.Count[i][1] = 0;
484 ctx->Histogram.Count[i][2] = 0;
485 ctx->Histogram.Count[i][3] = 0;
486 }
487 }
488 }
489
490
491 void
492 _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
493 {
494 GET_CURRENT_CONTEXT(ctx);
495 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetHistogramParameterfv");
496
497 if (!ctx->Extensions.EXT_histogram) {
498 gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv");
499 return;
500 }
501
502 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
503 gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)");
504 return;
505 }
506
507 switch (pname) {
508 case GL_HISTOGRAM_WIDTH:
509 *params = (GLfloat) ctx->Histogram.Width;
510 break;
511 case GL_HISTOGRAM_FORMAT:
512 *params = (GLfloat) ctx->Histogram.Format;
513 break;
514 case GL_HISTOGRAM_RED_SIZE:
515 *params = (GLfloat) ctx->Histogram.RedSize;
516 break;
517 case GL_HISTOGRAM_GREEN_SIZE:
518 *params = (GLfloat) ctx->Histogram.GreenSize;
519 break;
520 case GL_HISTOGRAM_BLUE_SIZE:
521 *params = (GLfloat) ctx->Histogram.BlueSize;
522 break;
523 case GL_HISTOGRAM_ALPHA_SIZE:
524 *params = (GLfloat) ctx->Histogram.AlphaSize;
525 break;
526 case GL_HISTOGRAM_LUMINANCE_SIZE:
527 *params = (GLfloat) ctx->Histogram.LuminanceSize;
528 break;
529 case GL_HISTOGRAM_SINK:
530 *params = (GLfloat) ctx->Histogram.Sink;
531 break;
532 default:
533 gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)");
534 }
535 }
536
537
538 void
539 _mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
540 {
541 GET_CURRENT_CONTEXT(ctx);
542 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetHistogramParameteriv");
543
544 if (!ctx->Extensions.EXT_histogram) {
545 gl_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv");
546 return;
547 }
548
549 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
550 gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)");
551 return;
552 }
553
554 switch (pname) {
555 case GL_HISTOGRAM_WIDTH:
556 *params = (GLint) ctx->Histogram.Width;
557 break;
558 case GL_HISTOGRAM_FORMAT:
559 *params = (GLint) ctx->Histogram.Format;
560 break;
561 case GL_HISTOGRAM_RED_SIZE:
562 *params = (GLint) ctx->Histogram.RedSize;
563 break;
564 case GL_HISTOGRAM_GREEN_SIZE:
565 *params = (GLint) ctx->Histogram.GreenSize;
566 break;
567 case GL_HISTOGRAM_BLUE_SIZE:
568 *params = (GLint) ctx->Histogram.BlueSize;
569 break;
570 case GL_HISTOGRAM_ALPHA_SIZE:
571 *params = (GLint) ctx->Histogram.AlphaSize;
572 break;
573 case GL_HISTOGRAM_LUMINANCE_SIZE:
574 *params = (GLint) ctx->Histogram.LuminanceSize;
575 break;
576 case GL_HISTOGRAM_SINK:
577 *params = (GLint) ctx->Histogram.Sink;
578 break;
579 default:
580 gl_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)");
581 }
582 }
583
584
585 void
586 _mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
587 {
588 GET_CURRENT_CONTEXT(ctx);
589 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMinmaxParameterfv");
590
591 if (!ctx->Extensions.EXT_histogram) {
592 gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv");
593 return;
594 }
595 if (target != GL_MINMAX) {
596 gl_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)");
597 return;
598 }
599 if (pname == GL_MINMAX_FORMAT) {
600 *params = (GLfloat) ctx->MinMax.Format;
601 }
602 else if (pname == GL_MINMAX_SINK) {
603 *params = (GLfloat) ctx->MinMax.Sink;
604 }
605 else {
606 gl_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)");
607 }
608 }
609
610
611 void
612 _mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
613 {
614 GET_CURRENT_CONTEXT(ctx);
615 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMinmaxParameteriv");
616
617 if (!ctx->Extensions.EXT_histogram) {
618 gl_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv");
619 return;
620 }
621 if (target != GL_MINMAX) {
622 gl_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)");
623 return;
624 }
625 if (pname == GL_MINMAX_FORMAT) {
626 *params = (GLint) ctx->MinMax.Format;
627 }
628 else if (pname == GL_MINMAX_SINK) {
629 *params = (GLint) ctx->MinMax.Sink;
630 }
631 else {
632 gl_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)");
633 }
634 }
635
636
637 void
638 _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink)
639 {
640 GLuint i;
641 GLboolean error = GL_FALSE;
642 GET_CURRENT_CONTEXT(ctx);
643 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glHistogram");
644
645 if (!ctx->Extensions.EXT_histogram) {
646 gl_error(ctx, GL_INVALID_OPERATION, "glHistogram");
647 return;
648 }
649
650 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
651 gl_error(ctx, GL_INVALID_ENUM, "glHistogram(target)");
652 return;
653 }
654
655 if (width < 0 || width > HISTOGRAM_TABLE_SIZE) {
656 if (target == GL_PROXY_HISTOGRAM) {
657 error = GL_TRUE;
658 }
659 else {
660 if (width < 0)
661 gl_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
662 else
663 gl_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)");
664 return;
665 }
666 }
667
668 if (width != 0 && _mesa_bitcount(width) != 1) {
669 if (target == GL_PROXY_HISTOGRAM) {
670 error = GL_TRUE;
671 }
672 else {
673 gl_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
674 return;
675 }
676 }
677
678 if (base_histogram_format(internalFormat) < 0) {
679 if (target == GL_PROXY_HISTOGRAM) {
680 error = GL_TRUE;
681 }
682 else {
683 gl_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)");
684 return;
685 }
686 }
687
688 /* reset histograms */
689 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
690 ctx->Histogram.Count[i][0] = 0;
691 ctx->Histogram.Count[i][1] = 0;
692 ctx->Histogram.Count[i][2] = 0;
693 ctx->Histogram.Count[i][3] = 0;
694 }
695
696 if (error) {
697 ctx->Histogram.Width = 0;
698 ctx->Histogram.Format = 0;
699 ctx->Histogram.RedSize = 0;
700 ctx->Histogram.GreenSize = 0;
701 ctx->Histogram.BlueSize = 0;
702 ctx->Histogram.AlphaSize = 0;
703 ctx->Histogram.LuminanceSize = 0;
704 }
705 else {
706 ctx->Histogram.Width = width;
707 ctx->Histogram.Format = internalFormat;
708 ctx->Histogram.Sink = sink;
709 ctx->Histogram.RedSize = 0xffffffff;
710 ctx->Histogram.GreenSize = 0xffffffff;
711 ctx->Histogram.BlueSize = 0xffffffff;
712 ctx->Histogram.AlphaSize = 0xffffffff;
713 ctx->Histogram.LuminanceSize = 0xffffffff;
714 }
715
716 ctx->NewState |= _NEW_PIXEL;
717 }
718
719
720 void
721 _mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
722 {
723 GET_CURRENT_CONTEXT(ctx);
724 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMinmax");
725
726 if (!ctx->Extensions.EXT_histogram) {
727 gl_error(ctx, GL_INVALID_OPERATION, "glMinmax");
728 return;
729 }
730
731 if (target != GL_MINMAX) {
732 gl_error(ctx, GL_INVALID_ENUM, "glMinMax(target)");
733 return;
734 }
735
736 if (base_histogram_format(internalFormat) < 0) {
737 gl_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)");
738 return;
739 }
740
741 ctx->MinMax.Sink = sink;
742 ctx->NewState |= _NEW_PIXEL;
743 }
744
745
746 void
747 _mesa_ResetHistogram(GLenum target)
748 {
749 GLuint i;
750 GET_CURRENT_CONTEXT(ctx);
751 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glResetHistogram");
752
753 if (!ctx->Extensions.EXT_histogram) {
754 gl_error(ctx, GL_INVALID_OPERATION, "glResetHistogram");
755 return;
756 }
757
758 if (target != GL_HISTOGRAM) {
759 gl_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)");
760 return;
761 }
762
763 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
764 ctx->Histogram.Count[i][0] = 0;
765 ctx->Histogram.Count[i][1] = 0;
766 ctx->Histogram.Count[i][2] = 0;
767 ctx->Histogram.Count[i][3] = 0;
768 }
769
770 ctx->NewState |= _NEW_PIXEL;
771 }
772
773
774 void
775 _mesa_ResetMinmax(GLenum target)
776 {
777 GET_CURRENT_CONTEXT(ctx);
778 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glResetMinmax");
779
780 if (!ctx->Extensions.EXT_histogram) {
781 gl_error(ctx, GL_INVALID_OPERATION, "glResetMinmax");
782 return;
783 }
784
785 if (target != GL_MINMAX) {
786 gl_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)");
787 return;
788 }
789
790 ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000;
791 ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000;
792 ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000;
793 ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000;
794 ctx->NewState |= _NEW_PIXEL;
795 }