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