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