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