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