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