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