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