mesa: use new combined PBO validate/map helpers
[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
653 values = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack, 2, 1, 1,
654 format, type, values, "glGetMinmax");
655 if (!values)
656 return;
657
658 {
659 GLfloat minmax[2][4];
660 minmax[0][RCOMP] = CLAMP(ctx->MinMax.Min[RCOMP], 0.0F, 1.0F);
661 minmax[0][GCOMP] = CLAMP(ctx->MinMax.Min[GCOMP], 0.0F, 1.0F);
662 minmax[0][BCOMP] = CLAMP(ctx->MinMax.Min[BCOMP], 0.0F, 1.0F);
663 minmax[0][ACOMP] = CLAMP(ctx->MinMax.Min[ACOMP], 0.0F, 1.0F);
664 minmax[1][RCOMP] = CLAMP(ctx->MinMax.Max[RCOMP], 0.0F, 1.0F);
665 minmax[1][GCOMP] = CLAMP(ctx->MinMax.Max[GCOMP], 0.0F, 1.0F);
666 minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
667 minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
668 _mesa_pack_rgba_span_float(ctx, 2, minmax,
669 format, type, values, &ctx->Pack, 0x0);
670 }
671
672 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
673
674 if (reset) {
675 _mesa_ResetMinmax(GL_MINMAX);
676 }
677 }
678
679
680 void GLAPIENTRY
681 _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
682 {
683 GET_CURRENT_CONTEXT(ctx);
684 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
685
686 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
687 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram");
688 return;
689 }
690
691 if (target != GL_HISTOGRAM) {
692 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)");
693 return;
694 }
695
696 if (format != GL_RED &&
697 format != GL_GREEN &&
698 format != GL_BLUE &&
699 format != GL_ALPHA &&
700 format != GL_RGB &&
701 format != GL_BGR &&
702 format != GL_RGBA &&
703 format != GL_BGRA &&
704 format != GL_ABGR_EXT &&
705 format != GL_LUMINANCE &&
706 format != GL_LUMINANCE_ALPHA) {
707 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(format)");
708 }
709
710 if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
711 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)");
712 return;
713 }
714
715 values = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack,
716 ctx->Histogram.Width, 1, 1,
717 format, type, values,
718 "glGetHistogram");
719 if (!values)
720 return;
721
722 pack_histogram(ctx, ctx->Histogram.Width,
723 (CONST GLuint (*)[4]) ctx->Histogram.Count,
724 format, type, values, &ctx->Pack);
725
726 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
727
728 if (reset) {
729 GLuint i;
730 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
731 ctx->Histogram.Count[i][0] = 0;
732 ctx->Histogram.Count[i][1] = 0;
733 ctx->Histogram.Count[i][2] = 0;
734 ctx->Histogram.Count[i][3] = 0;
735 }
736 }
737 }
738
739
740 void GLAPIENTRY
741 _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
742 {
743 GET_CURRENT_CONTEXT(ctx);
744 ASSERT_OUTSIDE_BEGIN_END(ctx);
745
746 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
747 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv");
748 return;
749 }
750
751 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
752 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)");
753 return;
754 }
755
756 switch (pname) {
757 case GL_HISTOGRAM_WIDTH:
758 *params = (GLfloat) ctx->Histogram.Width;
759 break;
760 case GL_HISTOGRAM_FORMAT:
761 *params = (GLfloat) ctx->Histogram.Format;
762 break;
763 case GL_HISTOGRAM_RED_SIZE:
764 *params = (GLfloat) ctx->Histogram.RedSize;
765 break;
766 case GL_HISTOGRAM_GREEN_SIZE:
767 *params = (GLfloat) ctx->Histogram.GreenSize;
768 break;
769 case GL_HISTOGRAM_BLUE_SIZE:
770 *params = (GLfloat) ctx->Histogram.BlueSize;
771 break;
772 case GL_HISTOGRAM_ALPHA_SIZE:
773 *params = (GLfloat) ctx->Histogram.AlphaSize;
774 break;
775 case GL_HISTOGRAM_LUMINANCE_SIZE:
776 *params = (GLfloat) ctx->Histogram.LuminanceSize;
777 break;
778 case GL_HISTOGRAM_SINK:
779 *params = (GLfloat) ctx->Histogram.Sink;
780 break;
781 default:
782 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)");
783 }
784 }
785
786
787 void GLAPIENTRY
788 _mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
789 {
790 GET_CURRENT_CONTEXT(ctx);
791 ASSERT_OUTSIDE_BEGIN_END(ctx);
792
793 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
794 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv");
795 return;
796 }
797
798 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
799 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)");
800 return;
801 }
802
803 switch (pname) {
804 case GL_HISTOGRAM_WIDTH:
805 *params = (GLint) ctx->Histogram.Width;
806 break;
807 case GL_HISTOGRAM_FORMAT:
808 *params = (GLint) ctx->Histogram.Format;
809 break;
810 case GL_HISTOGRAM_RED_SIZE:
811 *params = (GLint) ctx->Histogram.RedSize;
812 break;
813 case GL_HISTOGRAM_GREEN_SIZE:
814 *params = (GLint) ctx->Histogram.GreenSize;
815 break;
816 case GL_HISTOGRAM_BLUE_SIZE:
817 *params = (GLint) ctx->Histogram.BlueSize;
818 break;
819 case GL_HISTOGRAM_ALPHA_SIZE:
820 *params = (GLint) ctx->Histogram.AlphaSize;
821 break;
822 case GL_HISTOGRAM_LUMINANCE_SIZE:
823 *params = (GLint) ctx->Histogram.LuminanceSize;
824 break;
825 case GL_HISTOGRAM_SINK:
826 *params = (GLint) ctx->Histogram.Sink;
827 break;
828 default:
829 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)");
830 }
831 }
832
833
834 void GLAPIENTRY
835 _mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
836 {
837 GET_CURRENT_CONTEXT(ctx);
838 ASSERT_OUTSIDE_BEGIN_END(ctx);
839
840 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
841 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv");
842 return;
843 }
844 if (target != GL_MINMAX) {
845 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)");
846 return;
847 }
848 if (pname == GL_MINMAX_FORMAT) {
849 *params = (GLfloat) ctx->MinMax.Format;
850 }
851 else if (pname == GL_MINMAX_SINK) {
852 *params = (GLfloat) ctx->MinMax.Sink;
853 }
854 else {
855 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)");
856 }
857 }
858
859
860 void GLAPIENTRY
861 _mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
862 {
863 GET_CURRENT_CONTEXT(ctx);
864 ASSERT_OUTSIDE_BEGIN_END(ctx);
865
866 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
867 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv");
868 return;
869 }
870 if (target != GL_MINMAX) {
871 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)");
872 return;
873 }
874 if (pname == GL_MINMAX_FORMAT) {
875 *params = (GLint) ctx->MinMax.Format;
876 }
877 else if (pname == GL_MINMAX_SINK) {
878 *params = (GLint) ctx->MinMax.Sink;
879 }
880 else {
881 _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)");
882 }
883 }
884
885
886 void GLAPIENTRY
887 _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink)
888 {
889 GLuint i;
890 GLboolean error = GL_FALSE;
891 GET_CURRENT_CONTEXT(ctx);
892 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
893
894 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
895 _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram");
896 return;
897 }
898
899 if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
900 _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(target)");
901 return;
902 }
903
904 if (width < 0 || width > HISTOGRAM_TABLE_SIZE) {
905 if (target == GL_PROXY_HISTOGRAM) {
906 error = GL_TRUE;
907 }
908 else {
909 if (width < 0)
910 _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
911 else
912 _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)");
913 return;
914 }
915 }
916
917 if (width != 0 && !_mesa_is_pow_two(width)) {
918 if (target == GL_PROXY_HISTOGRAM) {
919 error = GL_TRUE;
920 }
921 else {
922 _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
923 return;
924 }
925 }
926
927 if (base_histogram_format(internalFormat) < 0) {
928 if (target == GL_PROXY_HISTOGRAM) {
929 error = GL_TRUE;
930 }
931 else {
932 _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)");
933 return;
934 }
935 }
936
937 FLUSH_VERTICES(ctx, _NEW_PIXEL);
938
939 /* reset histograms */
940 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
941 ctx->Histogram.Count[i][0] = 0;
942 ctx->Histogram.Count[i][1] = 0;
943 ctx->Histogram.Count[i][2] = 0;
944 ctx->Histogram.Count[i][3] = 0;
945 }
946
947 if (error) {
948 ctx->Histogram.Width = 0;
949 ctx->Histogram.Format = 0;
950 ctx->Histogram.RedSize = 0;
951 ctx->Histogram.GreenSize = 0;
952 ctx->Histogram.BlueSize = 0;
953 ctx->Histogram.AlphaSize = 0;
954 ctx->Histogram.LuminanceSize = 0;
955 }
956 else {
957 ctx->Histogram.Width = width;
958 ctx->Histogram.Format = internalFormat;
959 ctx->Histogram.Sink = sink;
960 ctx->Histogram.RedSize = 8 * sizeof(GLuint);
961 ctx->Histogram.GreenSize = 8 * sizeof(GLuint);
962 ctx->Histogram.BlueSize = 8 * sizeof(GLuint);
963 ctx->Histogram.AlphaSize = 8 * sizeof(GLuint);
964 ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint);
965 }
966 }
967
968
969 void GLAPIENTRY
970 _mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
971 {
972 GET_CURRENT_CONTEXT(ctx);
973 ASSERT_OUTSIDE_BEGIN_END(ctx);
974
975 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
976 _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax");
977 return;
978 }
979
980 if (target != GL_MINMAX) {
981 _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(target)");
982 return;
983 }
984
985 if (base_histogram_format(internalFormat) < 0) {
986 _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)");
987 return;
988 }
989
990 if (ctx->MinMax.Sink == sink)
991 return;
992 FLUSH_VERTICES(ctx, _NEW_PIXEL);
993 ctx->MinMax.Sink = sink;
994 }
995
996
997 void GLAPIENTRY
998 _mesa_ResetHistogram(GLenum target)
999 {
1000 GLuint i;
1001 GET_CURRENT_CONTEXT(ctx);
1002 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
1003
1004 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
1005 _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram");
1006 return;
1007 }
1008
1009 if (target != GL_HISTOGRAM) {
1010 _mesa_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)");
1011 return;
1012 }
1013
1014 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
1015 ctx->Histogram.Count[i][0] = 0;
1016 ctx->Histogram.Count[i][1] = 0;
1017 ctx->Histogram.Count[i][2] = 0;
1018 ctx->Histogram.Count[i][3] = 0;
1019 }
1020 }
1021
1022
1023 void GLAPIENTRY
1024 _mesa_ResetMinmax(GLenum target)
1025 {
1026 GET_CURRENT_CONTEXT(ctx);
1027 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1028
1029 if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
1030 _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax");
1031 return;
1032 }
1033
1034 if (target != GL_MINMAX) {
1035 _mesa_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)");
1036 return;
1037 }
1038
1039 ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000;
1040 ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000;
1041 ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000;
1042 ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000;
1043 }
1044
1045
1046
1047 /**********************************************************************/
1048 /***** Initialization *****/
1049 /**********************************************************************/
1050
1051 void _mesa_init_histogram( GLcontext * ctx )
1052 {
1053 int i;
1054
1055 /* Histogram group */
1056 ctx->Histogram.Width = 0;
1057 ctx->Histogram.Format = GL_RGBA;
1058 ctx->Histogram.Sink = GL_FALSE;
1059 ctx->Histogram.RedSize = 0;
1060 ctx->Histogram.GreenSize = 0;
1061 ctx->Histogram.BlueSize = 0;
1062 ctx->Histogram.AlphaSize = 0;
1063 ctx->Histogram.LuminanceSize = 0;
1064 for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
1065 ctx->Histogram.Count[i][0] = 0;
1066 ctx->Histogram.Count[i][1] = 0;
1067 ctx->Histogram.Count[i][2] = 0;
1068 ctx->Histogram.Count[i][3] = 0;
1069 }
1070
1071 /* Min/Max group */
1072 ctx->MinMax.Format = GL_RGBA;
1073 ctx->MinMax.Sink = GL_FALSE;
1074 ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000;
1075 ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000;
1076 ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000;
1077 ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000;
1078 }