Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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