mesa: Remove _mesa_(un)pack_index_span
[mesa.git] / src / mesa / main / pack.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THEA AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file pack.c
28 * Image and pixel span packing and unpacking.
29 */
30
31
32 /*
33 * XXX: MSVC takes forever to compile this module for x86_64 unless we disable
34 * this global optimization.
35 *
36 * See also:
37 * - http://msdn.microsoft.com/en-us/library/1yk3ydd7.aspx
38 * - http://msdn.microsoft.com/en-us/library/chh3fb0k.aspx
39 */
40 #if defined(_MSC_VER) && defined(_M_X64)
41 # pragma optimize( "g", off )
42 #endif
43
44
45 #include "glheader.h"
46 #include "colormac.h"
47 #include "enums.h"
48 #include "image.h"
49 #include "imports.h"
50 #include "macros.h"
51 #include "mtypes.h"
52 #include "pack.h"
53 #include "pixeltransfer.h"
54 #include "imports.h"
55 #include "glformats.h"
56 #include "format_utils.h"
57 #include "format_pack.h"
58
59
60 /**
61 * Flip the 8 bits in each byte of the given array.
62 *
63 * \param p array.
64 * \param n number of bytes.
65 *
66 * \todo try this trick to flip bytes someday:
67 * \code
68 * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555);
69 * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333);
70 * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f);
71 * \endcode
72 */
73 static void
74 flip_bytes( GLubyte *p, GLuint n )
75 {
76 GLuint i, a, b;
77 for (i = 0; i < n; i++) {
78 b = (GLuint) p[i]; /* words are often faster than bytes */
79 a = ((b & 0x01) << 7) |
80 ((b & 0x02) << 5) |
81 ((b & 0x04) << 3) |
82 ((b & 0x08) << 1) |
83 ((b & 0x10) >> 1) |
84 ((b & 0x20) >> 3) |
85 ((b & 0x40) >> 5) |
86 ((b & 0x80) >> 7);
87 p[i] = (GLubyte) a;
88 }
89 }
90
91
92
93 /*
94 * Unpack a 32x32 pixel polygon stipple from user memory using the
95 * current pixel unpack settings.
96 */
97 void
98 _mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
99 const struct gl_pixelstore_attrib *unpacking )
100 {
101 GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX,
102 GL_BITMAP, pattern, unpacking);
103 if (ptrn) {
104 /* Convert pattern from GLubytes to GLuints and handle big/little
105 * endian differences
106 */
107 GLubyte *p = ptrn;
108 GLint i;
109 for (i = 0; i < 32; i++) {
110 dest[i] = (p[0] << 24)
111 | (p[1] << 16)
112 | (p[2] << 8)
113 | (p[3] );
114 p += 4;
115 }
116 free(ptrn);
117 }
118 }
119
120
121 /*
122 * Pack polygon stipple into user memory given current pixel packing
123 * settings.
124 */
125 void
126 _mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
127 const struct gl_pixelstore_attrib *packing )
128 {
129 /* Convert pattern from GLuints to GLubytes to handle big/little
130 * endian differences.
131 */
132 GLubyte ptrn[32*4];
133 GLint i;
134 for (i = 0; i < 32; i++) {
135 ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
136 ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
137 ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
138 ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff);
139 }
140
141 _mesa_pack_bitmap(32, 32, ptrn, dest, packing);
142 }
143
144
145 /*
146 * Pack bitmap data.
147 */
148 void
149 _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
150 GLubyte *dest, const struct gl_pixelstore_attrib *packing )
151 {
152 GLint row, width_in_bytes;
153 const GLubyte *src;
154
155 if (!source)
156 return;
157
158 width_in_bytes = CEILING( width, 8 );
159 src = source;
160 for (row = 0; row < height; row++) {
161 GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
162 width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
163 if (!dst)
164 return;
165
166 if ((packing->SkipPixels & 7) == 0) {
167 memcpy( dst, src, width_in_bytes );
168 if (packing->LsbFirst) {
169 flip_bytes( dst, width_in_bytes );
170 }
171 }
172 else {
173 /* handling SkipPixels is a bit tricky (no pun intended!) */
174 GLint i;
175 if (packing->LsbFirst) {
176 GLubyte srcMask = 128;
177 GLubyte dstMask = 1 << (packing->SkipPixels & 0x7);
178 const GLubyte *s = src;
179 GLubyte *d = dst;
180 *d = 0;
181 for (i = 0; i < width; i++) {
182 if (*s & srcMask) {
183 *d |= dstMask;
184 }
185 if (srcMask == 1) {
186 srcMask = 128;
187 s++;
188 }
189 else {
190 srcMask = srcMask >> 1;
191 }
192 if (dstMask == 128) {
193 dstMask = 1;
194 d++;
195 *d = 0;
196 }
197 else {
198 dstMask = dstMask << 1;
199 }
200 }
201 }
202 else {
203 GLubyte srcMask = 128;
204 GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7);
205 const GLubyte *s = src;
206 GLubyte *d = dst;
207 *d = 0;
208 for (i = 0; i < width; i++) {
209 if (*s & srcMask) {
210 *d |= dstMask;
211 }
212 if (srcMask == 1) {
213 srcMask = 128;
214 s++;
215 }
216 else {
217 srcMask = srcMask >> 1;
218 }
219 if (dstMask == 1) {
220 dstMask = 128;
221 d++;
222 *d = 0;
223 }
224 else {
225 dstMask = dstMask >> 1;
226 }
227 }
228 }
229 }
230 src += width_in_bytes;
231 }
232 }
233
234
235 #define SWAP2BYTE(VALUE) \
236 { \
237 GLubyte *bytes = (GLubyte *) &(VALUE); \
238 GLubyte tmp = bytes[0]; \
239 bytes[0] = bytes[1]; \
240 bytes[1] = tmp; \
241 }
242
243 #define SWAP4BYTE(VALUE) \
244 { \
245 GLubyte *bytes = (GLubyte *) &(VALUE); \
246 GLubyte tmp = bytes[0]; \
247 bytes[0] = bytes[3]; \
248 bytes[3] = tmp; \
249 tmp = bytes[1]; \
250 bytes[1] = bytes[2]; \
251 bytes[2] = tmp; \
252 }
253
254
255 static void
256 extract_uint_indexes(GLuint n, GLuint indexes[],
257 GLenum srcFormat, GLenum srcType, const GLvoid *src,
258 const struct gl_pixelstore_attrib *unpack )
259 {
260 ASSERT(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX);
261
262 ASSERT(srcType == GL_BITMAP ||
263 srcType == GL_UNSIGNED_BYTE ||
264 srcType == GL_BYTE ||
265 srcType == GL_UNSIGNED_SHORT ||
266 srcType == GL_SHORT ||
267 srcType == GL_UNSIGNED_INT ||
268 srcType == GL_INT ||
269 srcType == GL_UNSIGNED_INT_24_8_EXT ||
270 srcType == GL_HALF_FLOAT_ARB ||
271 srcType == GL_FLOAT ||
272 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
273
274 switch (srcType) {
275 case GL_BITMAP:
276 {
277 GLubyte *ubsrc = (GLubyte *) src;
278 if (unpack->LsbFirst) {
279 GLubyte mask = 1 << (unpack->SkipPixels & 0x7);
280 GLuint i;
281 for (i = 0; i < n; i++) {
282 indexes[i] = (*ubsrc & mask) ? 1 : 0;
283 if (mask == 128) {
284 mask = 1;
285 ubsrc++;
286 }
287 else {
288 mask = mask << 1;
289 }
290 }
291 }
292 else {
293 GLubyte mask = 128 >> (unpack->SkipPixels & 0x7);
294 GLuint i;
295 for (i = 0; i < n; i++) {
296 indexes[i] = (*ubsrc & mask) ? 1 : 0;
297 if (mask == 1) {
298 mask = 128;
299 ubsrc++;
300 }
301 else {
302 mask = mask >> 1;
303 }
304 }
305 }
306 }
307 break;
308 case GL_UNSIGNED_BYTE:
309 {
310 GLuint i;
311 const GLubyte *s = (const GLubyte *) src;
312 for (i = 0; i < n; i++)
313 indexes[i] = s[i];
314 }
315 break;
316 case GL_BYTE:
317 {
318 GLuint i;
319 const GLbyte *s = (const GLbyte *) src;
320 for (i = 0; i < n; i++)
321 indexes[i] = s[i];
322 }
323 break;
324 case GL_UNSIGNED_SHORT:
325 {
326 GLuint i;
327 const GLushort *s = (const GLushort *) src;
328 if (unpack->SwapBytes) {
329 for (i = 0; i < n; i++) {
330 GLushort value = s[i];
331 SWAP2BYTE(value);
332 indexes[i] = value;
333 }
334 }
335 else {
336 for (i = 0; i < n; i++)
337 indexes[i] = s[i];
338 }
339 }
340 break;
341 case GL_SHORT:
342 {
343 GLuint i;
344 const GLshort *s = (const GLshort *) src;
345 if (unpack->SwapBytes) {
346 for (i = 0; i < n; i++) {
347 GLshort value = s[i];
348 SWAP2BYTE(value);
349 indexes[i] = value;
350 }
351 }
352 else {
353 for (i = 0; i < n; i++)
354 indexes[i] = s[i];
355 }
356 }
357 break;
358 case GL_UNSIGNED_INT:
359 {
360 GLuint i;
361 const GLuint *s = (const GLuint *) src;
362 if (unpack->SwapBytes) {
363 for (i = 0; i < n; i++) {
364 GLuint value = s[i];
365 SWAP4BYTE(value);
366 indexes[i] = value;
367 }
368 }
369 else {
370 for (i = 0; i < n; i++)
371 indexes[i] = s[i];
372 }
373 }
374 break;
375 case GL_INT:
376 {
377 GLuint i;
378 const GLint *s = (const GLint *) src;
379 if (unpack->SwapBytes) {
380 for (i = 0; i < n; i++) {
381 GLint value = s[i];
382 SWAP4BYTE(value);
383 indexes[i] = value;
384 }
385 }
386 else {
387 for (i = 0; i < n; i++)
388 indexes[i] = s[i];
389 }
390 }
391 break;
392 case GL_FLOAT:
393 {
394 GLuint i;
395 const GLfloat *s = (const GLfloat *) src;
396 if (unpack->SwapBytes) {
397 for (i = 0; i < n; i++) {
398 GLfloat value = s[i];
399 SWAP4BYTE(value);
400 indexes[i] = (GLuint) value;
401 }
402 }
403 else {
404 for (i = 0; i < n; i++)
405 indexes[i] = (GLuint) s[i];
406 }
407 }
408 break;
409 case GL_HALF_FLOAT_ARB:
410 {
411 GLuint i;
412 const GLhalfARB *s = (const GLhalfARB *) src;
413 if (unpack->SwapBytes) {
414 for (i = 0; i < n; i++) {
415 GLhalfARB value = s[i];
416 SWAP2BYTE(value);
417 indexes[i] = (GLuint) _mesa_half_to_float(value);
418 }
419 }
420 else {
421 for (i = 0; i < n; i++)
422 indexes[i] = (GLuint) _mesa_half_to_float(s[i]);
423 }
424 }
425 break;
426 case GL_UNSIGNED_INT_24_8_EXT:
427 {
428 GLuint i;
429 const GLuint *s = (const GLuint *) src;
430 if (unpack->SwapBytes) {
431 for (i = 0; i < n; i++) {
432 GLuint value = s[i];
433 SWAP4BYTE(value);
434 indexes[i] = value & 0xff; /* lower 8 bits */
435 }
436 }
437 else {
438 for (i = 0; i < n; i++)
439 indexes[i] = s[i] & 0xff; /* lower 8 bits */
440 }
441 }
442 break;
443 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
444 {
445 GLuint i;
446 const GLuint *s = (const GLuint *) src;
447 if (unpack->SwapBytes) {
448 for (i = 0; i < n; i++) {
449 GLuint value = s[i*2+1];
450 SWAP4BYTE(value);
451 indexes[i] = value & 0xff; /* lower 8 bits */
452 }
453 }
454 else {
455 for (i = 0; i < n; i++)
456 indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */
457 }
458 }
459 break;
460
461 default:
462 _mesa_problem(NULL, "bad srcType in extract_uint_indexes");
463 return;
464 }
465 }
466
467
468 static inline GLuint
469 clamp_float_to_uint(GLfloat f)
470 {
471 return f < 0.0F ? 0 : F_TO_I(f);
472 }
473
474
475 static inline GLuint
476 clamp_half_to_uint(GLhalfARB h)
477 {
478 GLfloat f = _mesa_half_to_float(h);
479 return f < 0.0F ? 0 : F_TO_I(f);
480 }
481
482
483 /*
484 * Unpack a row of stencil data from a client buffer according to
485 * the pixel unpacking parameters.
486 * This is (or will be) used by glDrawPixels
487 *
488 * Args: ctx - the context
489 * n - number of pixels
490 * dstType - destination data type
491 * dest - destination array
492 * srcType - source pixel type
493 * source - source data pointer
494 * srcPacking - pixel unpacking parameters
495 * transferOps - apply offset/bias/lookup ops?
496 */
497 void
498 _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
499 GLenum dstType, GLvoid *dest,
500 GLenum srcType, const GLvoid *source,
501 const struct gl_pixelstore_attrib *srcPacking,
502 GLbitfield transferOps )
503 {
504 ASSERT(srcType == GL_BITMAP ||
505 srcType == GL_UNSIGNED_BYTE ||
506 srcType == GL_BYTE ||
507 srcType == GL_UNSIGNED_SHORT ||
508 srcType == GL_SHORT ||
509 srcType == GL_UNSIGNED_INT ||
510 srcType == GL_INT ||
511 srcType == GL_UNSIGNED_INT_24_8_EXT ||
512 srcType == GL_HALF_FLOAT_ARB ||
513 srcType == GL_FLOAT ||
514 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
515
516 ASSERT(dstType == GL_UNSIGNED_BYTE ||
517 dstType == GL_UNSIGNED_SHORT ||
518 dstType == GL_UNSIGNED_INT ||
519 dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
520
521 /* only shift and offset apply to stencil */
522 transferOps &= IMAGE_SHIFT_OFFSET_BIT;
523
524 /*
525 * Try simple cases first
526 */
527 if (transferOps == 0 &&
528 !ctx->Pixel.MapStencilFlag &&
529 srcType == GL_UNSIGNED_BYTE &&
530 dstType == GL_UNSIGNED_BYTE) {
531 memcpy(dest, source, n * sizeof(GLubyte));
532 }
533 else if (transferOps == 0 &&
534 !ctx->Pixel.MapStencilFlag &&
535 srcType == GL_UNSIGNED_INT &&
536 dstType == GL_UNSIGNED_INT &&
537 !srcPacking->SwapBytes) {
538 memcpy(dest, source, n * sizeof(GLuint));
539 }
540 else {
541 /*
542 * general solution
543 */
544 GLuint *indexes = malloc(n * sizeof(GLuint));
545
546 if (!indexes) {
547 _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking");
548 return;
549 }
550
551 extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
552 srcPacking);
553
554 if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
555 /* shift and offset indexes */
556 _mesa_shift_and_offset_ci(ctx, n, indexes);
557 }
558
559 if (ctx->Pixel.MapStencilFlag) {
560 /* Apply stencil lookup table */
561 const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
562 GLuint i;
563 for (i = 0; i < n; i++) {
564 indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
565 }
566 }
567
568 /* convert to dest type */
569 switch (dstType) {
570 case GL_UNSIGNED_BYTE:
571 {
572 GLubyte *dst = (GLubyte *) dest;
573 GLuint i;
574 for (i = 0; i < n; i++) {
575 dst[i] = (GLubyte) (indexes[i] & 0xff);
576 }
577 }
578 break;
579 case GL_UNSIGNED_SHORT:
580 {
581 GLuint *dst = (GLuint *) dest;
582 GLuint i;
583 for (i = 0; i < n; i++) {
584 dst[i] = (GLushort) (indexes[i] & 0xffff);
585 }
586 }
587 break;
588 case GL_UNSIGNED_INT:
589 memcpy(dest, indexes, n * sizeof(GLuint));
590 break;
591 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
592 {
593 GLuint *dst = (GLuint *) dest;
594 GLuint i;
595 for (i = 0; i < n; i++) {
596 dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */
597 }
598 }
599 break;
600 default:
601 _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span");
602 }
603
604 free(indexes);
605 }
606 }
607
608
609 void
610 _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n,
611 GLenum dstType, GLvoid *dest, const GLubyte *source,
612 const struct gl_pixelstore_attrib *dstPacking )
613 {
614 GLubyte *stencil = malloc(n * sizeof(GLubyte));
615
616 if (!stencil) {
617 _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing");
618 return;
619 }
620
621 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
622 ctx->Pixel.MapStencilFlag) {
623 /* make a copy of input */
624 memcpy(stencil, source, n * sizeof(GLubyte));
625 _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
626 source = stencil;
627 }
628
629 switch (dstType) {
630 case GL_UNSIGNED_BYTE:
631 memcpy(dest, source, n);
632 break;
633 case GL_BYTE:
634 {
635 GLbyte *dst = (GLbyte *) dest;
636 GLuint i;
637 for (i=0;i<n;i++) {
638 dst[i] = (GLbyte) (source[i] & 0x7f);
639 }
640 }
641 break;
642 case GL_UNSIGNED_SHORT:
643 {
644 GLushort *dst = (GLushort *) dest;
645 GLuint i;
646 for (i=0;i<n;i++) {
647 dst[i] = (GLushort) source[i];
648 }
649 if (dstPacking->SwapBytes) {
650 _mesa_swap2( (GLushort *) dst, n );
651 }
652 }
653 break;
654 case GL_SHORT:
655 {
656 GLshort *dst = (GLshort *) dest;
657 GLuint i;
658 for (i=0;i<n;i++) {
659 dst[i] = (GLshort) source[i];
660 }
661 if (dstPacking->SwapBytes) {
662 _mesa_swap2( (GLushort *) dst, n );
663 }
664 }
665 break;
666 case GL_UNSIGNED_INT:
667 {
668 GLuint *dst = (GLuint *) dest;
669 GLuint i;
670 for (i=0;i<n;i++) {
671 dst[i] = (GLuint) source[i];
672 }
673 if (dstPacking->SwapBytes) {
674 _mesa_swap4( (GLuint *) dst, n );
675 }
676 }
677 break;
678 case GL_INT:
679 {
680 GLint *dst = (GLint *) dest;
681 GLuint i;
682 for (i=0;i<n;i++) {
683 dst[i] = (GLint) source[i];
684 }
685 if (dstPacking->SwapBytes) {
686 _mesa_swap4( (GLuint *) dst, n );
687 }
688 }
689 break;
690 case GL_FLOAT:
691 {
692 GLfloat *dst = (GLfloat *) dest;
693 GLuint i;
694 for (i=0;i<n;i++) {
695 dst[i] = (GLfloat) source[i];
696 }
697 if (dstPacking->SwapBytes) {
698 _mesa_swap4( (GLuint *) dst, n );
699 }
700 }
701 break;
702 case GL_HALF_FLOAT_ARB:
703 {
704 GLhalfARB *dst = (GLhalfARB *) dest;
705 GLuint i;
706 for (i=0;i<n;i++) {
707 dst[i] = _mesa_float_to_half( (float) source[i] );
708 }
709 if (dstPacking->SwapBytes) {
710 _mesa_swap2( (GLushort *) dst, n );
711 }
712 }
713 break;
714 case GL_BITMAP:
715 if (dstPacking->LsbFirst) {
716 GLubyte *dst = (GLubyte *) dest;
717 GLint shift = 0;
718 GLuint i;
719 for (i = 0; i < n; i++) {
720 if (shift == 0)
721 *dst = 0;
722 *dst |= ((source[i] != 0) << shift);
723 shift++;
724 if (shift == 8) {
725 shift = 0;
726 dst++;
727 }
728 }
729 }
730 else {
731 GLubyte *dst = (GLubyte *) dest;
732 GLint shift = 7;
733 GLuint i;
734 for (i = 0; i < n; i++) {
735 if (shift == 7)
736 *dst = 0;
737 *dst |= ((source[i] != 0) << shift);
738 shift--;
739 if (shift < 0) {
740 shift = 7;
741 dst++;
742 }
743 }
744 }
745 break;
746 default:
747 _mesa_problem(ctx, "bad type in _mesa_pack_index_span");
748 }
749
750 free(stencil);
751 }
752
753 #define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT) \
754 do { \
755 GLuint i; \
756 const GLTYPE *src = (const GLTYPE *)source; \
757 for (i = 0; i < n; i++) { \
758 GLTYPE value = src[i]; \
759 if (srcPacking->SwapBytes) { \
760 if (sizeof(GLTYPE) == 2) { \
761 SWAP2BYTE(value); \
762 } else if (sizeof(GLTYPE) == 4) { \
763 SWAP4BYTE(value); \
764 } \
765 } \
766 depthValues[i] = GLTYPE2FLOAT(value); \
767 } \
768 } while (0)
769
770
771 /**
772 * Unpack a row of depth/z values from memory, returning GLushort, GLuint
773 * or GLfloat values.
774 * The glPixelTransfer (scale/bias) params will be applied.
775 *
776 * \param dstType one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT
777 * \param depthMax max value for returned GLushort or GLuint values
778 * (ignored for GLfloat).
779 */
780 void
781 _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
782 GLenum dstType, GLvoid *dest, GLuint depthMax,
783 GLenum srcType, const GLvoid *source,
784 const struct gl_pixelstore_attrib *srcPacking )
785 {
786 GLfloat *depthTemp = NULL, *depthValues;
787 GLboolean needClamp = GL_FALSE;
788
789 /* Look for special cases first.
790 * Not only are these faster, they're less prone to numeric conversion
791 * problems. Otherwise, converting from an int type to a float then
792 * back to an int type can introduce errors that will show up as
793 * artifacts in things like depth peeling which uses glCopyTexImage.
794 */
795 if (ctx->Pixel.DepthScale == 1.0 && ctx->Pixel.DepthBias == 0.0) {
796 if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) {
797 const GLuint *src = (const GLuint *) source;
798 GLushort *dst = (GLushort *) dest;
799 GLuint i;
800 for (i = 0; i < n; i++) {
801 dst[i] = src[i] >> 16;
802 }
803 return;
804 }
805 if (srcType == GL_UNSIGNED_SHORT
806 && dstType == GL_UNSIGNED_INT
807 && depthMax == 0xffffffff) {
808 const GLushort *src = (const GLushort *) source;
809 GLuint *dst = (GLuint *) dest;
810 GLuint i;
811 for (i = 0; i < n; i++) {
812 dst[i] = src[i] | (src[i] << 16);
813 }
814 return;
815 }
816 if (srcType == GL_UNSIGNED_INT_24_8
817 && dstType == GL_UNSIGNED_INT
818 && depthMax == 0xffffff) {
819 const GLuint *src = (const GLuint *) source;
820 GLuint *dst = (GLuint *) dest;
821 GLuint i;
822 for (i = 0; i < n; i++) {
823 dst[i] = src[i] >> 8;
824 }
825 return;
826 }
827 /* XXX may want to add additional cases here someday */
828 }
829
830 /* general case path follows */
831
832 if (dstType == GL_FLOAT) {
833 depthValues = (GLfloat *) dest;
834 }
835 else {
836 depthTemp = malloc(n * sizeof(GLfloat));
837 if (!depthTemp) {
838 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
839 return;
840 }
841
842 depthValues = depthTemp;
843 }
844
845 /* Convert incoming values to GLfloat. Some conversions will require
846 * clamping, below.
847 */
848 switch (srcType) {
849 case GL_BYTE:
850 DEPTH_VALUES(GLbyte, BYTE_TO_FLOATZ);
851 needClamp = GL_TRUE;
852 break;
853 case GL_UNSIGNED_BYTE:
854 DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT);
855 break;
856 case GL_SHORT:
857 DEPTH_VALUES(GLshort, SHORT_TO_FLOATZ);
858 needClamp = GL_TRUE;
859 break;
860 case GL_UNSIGNED_SHORT:
861 DEPTH_VALUES(GLushort, USHORT_TO_FLOAT);
862 break;
863 case GL_INT:
864 DEPTH_VALUES(GLint, INT_TO_FLOAT);
865 needClamp = GL_TRUE;
866 break;
867 case GL_UNSIGNED_INT:
868 DEPTH_VALUES(GLuint, UINT_TO_FLOAT);
869 break;
870 case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
871 if (dstType == GL_UNSIGNED_INT_24_8_EXT &&
872 depthMax == 0xffffff &&
873 ctx->Pixel.DepthScale == 1.0 &&
874 ctx->Pixel.DepthBias == 0.0) {
875 const GLuint *src = (const GLuint *) source;
876 GLuint *zValues = (GLuint *) dest;
877 GLuint i;
878 for (i = 0; i < n; i++) {
879 GLuint value = src[i];
880 if (srcPacking->SwapBytes) {
881 SWAP4BYTE(value);
882 }
883 zValues[i] = value & 0xffffff00;
884 }
885 free(depthTemp);
886 return;
887 }
888 else {
889 const GLuint *src = (const GLuint *) source;
890 const GLfloat scale = 1.0f / 0xffffff;
891 GLuint i;
892 for (i = 0; i < n; i++) {
893 GLuint value = src[i];
894 if (srcPacking->SwapBytes) {
895 SWAP4BYTE(value);
896 }
897 depthValues[i] = (value >> 8) * scale;
898 }
899 }
900 break;
901 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
902 {
903 GLuint i;
904 const GLfloat *src = (const GLfloat *)source;
905 for (i = 0; i < n; i++) {
906 GLfloat value = src[i * 2];
907 if (srcPacking->SwapBytes) {
908 SWAP4BYTE(value);
909 }
910 depthValues[i] = value;
911 }
912 needClamp = GL_TRUE;
913 }
914 break;
915 case GL_FLOAT:
916 DEPTH_VALUES(GLfloat, 1*);
917 needClamp = GL_TRUE;
918 break;
919 case GL_HALF_FLOAT_ARB:
920 {
921 GLuint i;
922 const GLhalfARB *src = (const GLhalfARB *) source;
923 for (i = 0; i < n; i++) {
924 GLhalfARB value = src[i];
925 if (srcPacking->SwapBytes) {
926 SWAP2BYTE(value);
927 }
928 depthValues[i] = _mesa_half_to_float(value);
929 }
930 needClamp = GL_TRUE;
931 }
932 break;
933 default:
934 _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
935 free(depthTemp);
936 return;
937 }
938
939 /* apply depth scale and bias */
940 {
941 const GLfloat scale = ctx->Pixel.DepthScale;
942 const GLfloat bias = ctx->Pixel.DepthBias;
943 if (scale != 1.0 || bias != 0.0) {
944 GLuint i;
945 for (i = 0; i < n; i++) {
946 depthValues[i] = depthValues[i] * scale + bias;
947 }
948 needClamp = GL_TRUE;
949 }
950 }
951
952 /* clamp to [0, 1] */
953 if (needClamp) {
954 GLuint i;
955 for (i = 0; i < n; i++) {
956 depthValues[i] = (GLfloat)CLAMP(depthValues[i], 0.0, 1.0);
957 }
958 }
959
960 /*
961 * Convert values to dstType
962 */
963 if (dstType == GL_UNSIGNED_INT) {
964 GLuint *zValues = (GLuint *) dest;
965 GLuint i;
966 if (depthMax <= 0xffffff) {
967 /* no overflow worries */
968 for (i = 0; i < n; i++) {
969 zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax);
970 }
971 }
972 else {
973 /* need to use double precision to prevent overflow problems */
974 for (i = 0; i < n; i++) {
975 GLdouble z = depthValues[i] * (GLdouble) depthMax;
976 if (z >= (GLdouble) 0xffffffff)
977 zValues[i] = 0xffffffff;
978 else
979 zValues[i] = (GLuint) z;
980 }
981 }
982 }
983 else if (dstType == GL_UNSIGNED_SHORT) {
984 GLushort *zValues = (GLushort *) dest;
985 GLuint i;
986 ASSERT(depthMax <= 0xffff);
987 for (i = 0; i < n; i++) {
988 zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax);
989 }
990 }
991 else if (dstType == GL_FLOAT) {
992 /* Nothing to do. depthValues is pointing to dest. */
993 }
994 else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) {
995 GLfloat *zValues = (GLfloat*) dest;
996 GLuint i;
997 for (i = 0; i < n; i++) {
998 zValues[i*2] = depthValues[i];
999 }
1000 }
1001 else {
1002 ASSERT(0);
1003 }
1004
1005 free(depthTemp);
1006 }
1007
1008
1009 /*
1010 * Pack an array of depth values. The values are floats in [0,1].
1011 */
1012 void
1013 _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
1014 GLenum dstType, const GLfloat *depthSpan,
1015 const struct gl_pixelstore_attrib *dstPacking )
1016 {
1017 GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
1018 if (!depthCopy) {
1019 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
1020 return;
1021 }
1022
1023 if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
1024 memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
1025 _mesa_scale_and_bias_depth(ctx, n, depthCopy);
1026 depthSpan = depthCopy;
1027 }
1028
1029 switch (dstType) {
1030 case GL_UNSIGNED_BYTE:
1031 {
1032 GLubyte *dst = (GLubyte *) dest;
1033 GLuint i;
1034 for (i = 0; i < n; i++) {
1035 dst[i] = FLOAT_TO_UBYTE( depthSpan[i] );
1036 }
1037 }
1038 break;
1039 case GL_BYTE:
1040 {
1041 GLbyte *dst = (GLbyte *) dest;
1042 GLuint i;
1043 for (i = 0; i < n; i++) {
1044 dst[i] = FLOAT_TO_BYTE( depthSpan[i] );
1045 }
1046 }
1047 break;
1048 case GL_UNSIGNED_SHORT:
1049 {
1050 GLushort *dst = (GLushort *) dest;
1051 GLuint i;
1052 for (i = 0; i < n; i++) {
1053 CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]);
1054 }
1055 if (dstPacking->SwapBytes) {
1056 _mesa_swap2( (GLushort *) dst, n );
1057 }
1058 }
1059 break;
1060 case GL_SHORT:
1061 {
1062 GLshort *dst = (GLshort *) dest;
1063 GLuint i;
1064 for (i = 0; i < n; i++) {
1065 dst[i] = FLOAT_TO_SHORT( depthSpan[i] );
1066 }
1067 if (dstPacking->SwapBytes) {
1068 _mesa_swap2( (GLushort *) dst, n );
1069 }
1070 }
1071 break;
1072 case GL_UNSIGNED_INT:
1073 {
1074 GLuint *dst = (GLuint *) dest;
1075 GLuint i;
1076 for (i = 0; i < n; i++) {
1077 dst[i] = FLOAT_TO_UINT( depthSpan[i] );
1078 }
1079 if (dstPacking->SwapBytes) {
1080 _mesa_swap4( (GLuint *) dst, n );
1081 }
1082 }
1083 break;
1084 case GL_INT:
1085 {
1086 GLint *dst = (GLint *) dest;
1087 GLuint i;
1088 for (i = 0; i < n; i++) {
1089 dst[i] = FLOAT_TO_INT( depthSpan[i] );
1090 }
1091 if (dstPacking->SwapBytes) {
1092 _mesa_swap4( (GLuint *) dst, n );
1093 }
1094 }
1095 break;
1096 case GL_FLOAT:
1097 {
1098 GLfloat *dst = (GLfloat *) dest;
1099 GLuint i;
1100 for (i = 0; i < n; i++) {
1101 dst[i] = depthSpan[i];
1102 }
1103 if (dstPacking->SwapBytes) {
1104 _mesa_swap4( (GLuint *) dst, n );
1105 }
1106 }
1107 break;
1108 case GL_HALF_FLOAT_ARB:
1109 {
1110 GLhalfARB *dst = (GLhalfARB *) dest;
1111 GLuint i;
1112 for (i = 0; i < n; i++) {
1113 dst[i] = _mesa_float_to_half(depthSpan[i]);
1114 }
1115 if (dstPacking->SwapBytes) {
1116 _mesa_swap2( (GLushort *) dst, n );
1117 }
1118 }
1119 break;
1120 default:
1121 _mesa_problem(ctx, "bad type in _mesa_pack_depth_span");
1122 }
1123
1124 free(depthCopy);
1125 }
1126
1127
1128
1129 /**
1130 * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc)
1131 */
1132 void
1133 _mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
1134 GLenum dstType, GLuint *dest,
1135 const GLfloat *depthVals,
1136 const GLubyte *stencilVals,
1137 const struct gl_pixelstore_attrib *dstPacking)
1138 {
1139 GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
1140 GLubyte *stencilCopy = malloc(n * sizeof(GLubyte));
1141 GLuint i;
1142
1143 if (!depthCopy || !stencilCopy) {
1144 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
1145 free(depthCopy);
1146 free(stencilCopy);
1147 return;
1148 }
1149
1150 if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) {
1151 memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
1152 _mesa_scale_and_bias_depth(ctx, n, depthCopy);
1153 depthVals = depthCopy;
1154 }
1155
1156 if (ctx->Pixel.IndexShift ||
1157 ctx->Pixel.IndexOffset ||
1158 ctx->Pixel.MapStencilFlag) {
1159 memcpy(stencilCopy, stencilVals, n * sizeof(GLubyte));
1160 _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
1161 stencilVals = stencilCopy;
1162 }
1163
1164 switch (dstType) {
1165 case GL_UNSIGNED_INT_24_8:
1166 for (i = 0; i < n; i++) {
1167 GLuint z = (GLuint) (depthVals[i] * 0xffffff);
1168 dest[i] = (z << 8) | (stencilVals[i] & 0xff);
1169 }
1170 break;
1171 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1172 for (i = 0; i < n; i++) {
1173 ((GLfloat*)dest)[i*2] = depthVals[i];
1174 dest[i*2+1] = stencilVals[i] & 0xff;
1175 }
1176 break;
1177 }
1178
1179 if (dstPacking->SwapBytes) {
1180 _mesa_swap4(dest, n);
1181 }
1182
1183 free(depthCopy);
1184 free(stencilCopy);
1185 }
1186
1187
1188
1189 /**
1190 * Unpack image data. Apply byte swapping, byte flipping (bitmap).
1191 * Return all image data in a contiguous block. This is used when we
1192 * compile glDrawPixels, glTexImage, etc into a display list. We
1193 * need a copy of the data in a standard format.
1194 */
1195 void *
1196 _mesa_unpack_image( GLuint dimensions,
1197 GLsizei width, GLsizei height, GLsizei depth,
1198 GLenum format, GLenum type, const GLvoid *pixels,
1199 const struct gl_pixelstore_attrib *unpack )
1200 {
1201 GLint bytesPerRow, compsPerRow;
1202 GLboolean flipBytes, swap2, swap4;
1203
1204 if (!pixels)
1205 return NULL; /* not necessarily an error */
1206
1207 if (width <= 0 || height <= 0 || depth <= 0)
1208 return NULL; /* generate error later */
1209
1210 if (type == GL_BITMAP) {
1211 bytesPerRow = (width + 7) >> 3;
1212 flipBytes = unpack->LsbFirst;
1213 swap2 = swap4 = GL_FALSE;
1214 compsPerRow = 0;
1215 }
1216 else {
1217 const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
1218 GLint components = _mesa_components_in_format(format);
1219 GLint bytesPerComp;
1220
1221 if (_mesa_type_is_packed(type))
1222 components = 1;
1223
1224 if (bytesPerPixel <= 0 || components <= 0)
1225 return NULL; /* bad format or type. generate error later */
1226 bytesPerRow = bytesPerPixel * width;
1227 bytesPerComp = bytesPerPixel / components;
1228 flipBytes = GL_FALSE;
1229 swap2 = (bytesPerComp == 2) && unpack->SwapBytes;
1230 swap4 = (bytesPerComp == 4) && unpack->SwapBytes;
1231 compsPerRow = components * width;
1232 assert(compsPerRow >= width);
1233 }
1234
1235 {
1236 GLubyte *destBuffer
1237 = malloc(bytesPerRow * height * depth);
1238 GLubyte *dst;
1239 GLint img, row;
1240 if (!destBuffer)
1241 return NULL; /* generate GL_OUT_OF_MEMORY later */
1242
1243 dst = destBuffer;
1244 for (img = 0; img < depth; img++) {
1245 for (row = 0; row < height; row++) {
1246 const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels,
1247 width, height, format, type, img, row, 0);
1248
1249 if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) {
1250 GLint i;
1251 flipBytes = GL_FALSE;
1252 if (unpack->LsbFirst) {
1253 GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7);
1254 GLubyte dstMask = 128;
1255 const GLubyte *s = src;
1256 GLubyte *d = dst;
1257 *d = 0;
1258 for (i = 0; i < width; i++) {
1259 if (*s & srcMask) {
1260 *d |= dstMask;
1261 }
1262 if (srcMask == 128) {
1263 srcMask = 1;
1264 s++;
1265 }
1266 else {
1267 srcMask = srcMask << 1;
1268 }
1269 if (dstMask == 1) {
1270 dstMask = 128;
1271 d++;
1272 *d = 0;
1273 }
1274 else {
1275 dstMask = dstMask >> 1;
1276 }
1277 }
1278 }
1279 else {
1280 GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7);
1281 GLubyte dstMask = 128;
1282 const GLubyte *s = src;
1283 GLubyte *d = dst;
1284 *d = 0;
1285 for (i = 0; i < width; i++) {
1286 if (*s & srcMask) {
1287 *d |= dstMask;
1288 }
1289 if (srcMask == 1) {
1290 srcMask = 128;
1291 s++;
1292 }
1293 else {
1294 srcMask = srcMask >> 1;
1295 }
1296 if (dstMask == 1) {
1297 dstMask = 128;
1298 d++;
1299 *d = 0;
1300 }
1301 else {
1302 dstMask = dstMask >> 1;
1303 }
1304 }
1305 }
1306 }
1307 else {
1308 memcpy(dst, src, bytesPerRow);
1309 }
1310
1311 /* byte flipping/swapping */
1312 if (flipBytes) {
1313 flip_bytes((GLubyte *) dst, bytesPerRow);
1314 }
1315 else if (swap2) {
1316 _mesa_swap2((GLushort*) dst, compsPerRow);
1317 }
1318 else if (swap4) {
1319 _mesa_swap4((GLuint*) dst, compsPerRow);
1320 }
1321 dst += bytesPerRow;
1322 }
1323 }
1324 return destBuffer;
1325 }
1326 }
1327
1328
1329
1330 /**
1331 * If we unpack colors from a luminance surface, we'll get pixel colors
1332 * such as (l, l, l, a).
1333 * When we call _mesa_pack_rgba_span_float(format=GL_LUMINANCE), that
1334 * function will compute L=R+G+B before packing. The net effect is we'll
1335 * accidentally store luminance values = 3*l.
1336 * This function compensates for that by converting (aka rebasing) (l,l,l,a)
1337 * to be (l,0,0,a).
1338 * It's a similar story for other formats such as LUMINANCE_ALPHA, ALPHA
1339 * and INTENSITY.
1340 *
1341 * Finally, we also need to do this when the actual surface format does
1342 * not match the logical surface format. For example, suppose the user
1343 * requests a GL_LUMINANCE texture but the driver stores it as RGBA.
1344 * Again, we'll get pixel values like (l,l,l,a).
1345 */
1346 void
1347 _mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat)
1348 {
1349 GLuint i;
1350
1351 switch (baseFormat) {
1352 case GL_ALPHA:
1353 for (i = 0; i < n; i++) {
1354 rgba[i][RCOMP] = 0.0F;
1355 rgba[i][GCOMP] = 0.0F;
1356 rgba[i][BCOMP] = 0.0F;
1357 }
1358 break;
1359 case GL_INTENSITY:
1360 /* fall-through */
1361 case GL_LUMINANCE:
1362 for (i = 0; i < n; i++) {
1363 rgba[i][GCOMP] = 0.0F;
1364 rgba[i][BCOMP] = 0.0F;
1365 rgba[i][ACOMP] = 1.0F;
1366 }
1367 break;
1368 case GL_LUMINANCE_ALPHA:
1369 for (i = 0; i < n; i++) {
1370 rgba[i][GCOMP] = 0.0F;
1371 rgba[i][BCOMP] = 0.0F;
1372 }
1373 break;
1374 case GL_RGB:
1375 for (i = 0; i < n; i++) {
1376 rgba[i][ACOMP] = 1.0F;
1377 }
1378 break;
1379 case GL_RG:
1380 for (i = 0; i < n; i++) {
1381 rgba[i][BCOMP] = 0.0F;
1382 rgba[i][ACOMP] = 1.0F;
1383 }
1384 break;
1385 case GL_RED:
1386 for (i = 0; i < n; i++) {
1387 rgba[i][GCOMP] = 0.0F;
1388 rgba[i][BCOMP] = 0.0F;
1389 rgba[i][ACOMP] = 1.0F;
1390 }
1391 break;
1392
1393 default:
1394 /* no-op */
1395 ;
1396 }
1397 }
1398
1399
1400 /**
1401 * As above, but GLuint components.
1402 */
1403 void
1404 _mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat)
1405 {
1406 GLuint i;
1407
1408 switch (baseFormat) {
1409 case GL_ALPHA:
1410 for (i = 0; i < n; i++) {
1411 rgba[i][RCOMP] = 0;
1412 rgba[i][GCOMP] = 0;
1413 rgba[i][BCOMP] = 0;
1414 }
1415 break;
1416 case GL_INTENSITY:
1417 /* fall-through */
1418 case GL_LUMINANCE:
1419 for (i = 0; i < n; i++) {
1420 rgba[i][GCOMP] = 0;
1421 rgba[i][BCOMP] = 0;
1422 rgba[i][ACOMP] = 1;
1423 }
1424 break;
1425 case GL_LUMINANCE_ALPHA:
1426 for (i = 0; i < n; i++) {
1427 rgba[i][GCOMP] = 0;
1428 rgba[i][BCOMP] = 0;
1429 }
1430 break;
1431 case GL_RGB:
1432 for (i = 0; i < n; i++) {
1433 rgba[i][ACOMP] = 1;
1434 }
1435 break;
1436 case GL_RG:
1437 for (i = 0; i < n; i++) {
1438 rgba[i][BCOMP] = 0;
1439 rgba[i][ACOMP] = 1;
1440 }
1441 break;
1442 case GL_RED:
1443 for (i = 0; i < n; i++) {
1444 rgba[i][GCOMP] = 0;
1445 rgba[i][BCOMP] = 0;
1446 rgba[i][ACOMP] = 1;
1447 }
1448 default:
1449 /* no-op */
1450 ;
1451 }
1452 }
1453
1454 void
1455 _mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4],
1456 GLvoid *dstAddr, GLenum dst_format,
1457 GLbitfield transferOps)
1458 {
1459 int i;
1460 GLfloat *dst = (GLfloat *) dstAddr;
1461
1462 switch (dst_format) {
1463 case GL_LUMINANCE:
1464 if (transferOps & IMAGE_CLAMP_BIT) {
1465 for (i = 0; i < n; i++) {
1466 GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1467 dst[i] = CLAMP(sum, 0.0F, 1.0F);
1468 }
1469 } else {
1470 for (i = 0; i < n; i++) {
1471 dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1472 }
1473 }
1474 return;
1475 case GL_LUMINANCE_ALPHA:
1476 if (transferOps & IMAGE_CLAMP_BIT) {
1477 for (i = 0; i < n; i++) {
1478 GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1479 dst[2*i] = CLAMP(sum, 0.0F, 1.0F);
1480 dst[2*i+1] = rgba[i][ACOMP];
1481 }
1482 } else {
1483 for (i = 0; i < n; i++) {
1484 dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1485 dst[2*i+1] = rgba[i][ACOMP];
1486 }
1487 }
1488 return;
1489 default:
1490 assert(!"Unsupported format");
1491 }
1492 }
1493
1494 static int32_t
1495 clamp_sint64_to_sint32(int64_t src)
1496 {
1497 return CLAMP(src, INT32_MIN, INT32_MAX);
1498 }
1499
1500 static int32_t
1501 clamp_sint64_to_uint32(int64_t src)
1502 {
1503 return CLAMP(src, 0, UINT32_MAX);
1504 }
1505
1506 static int32_t
1507 clamp_uint64_to_uint32(uint64_t src)
1508 {
1509 return MIN2(src, UINT32_MAX);
1510 }
1511
1512 static int32_t
1513 clamp_uint64_to_sint32(uint64_t src)
1514 {
1515 return MIN2(src, INT32_MAX);
1516 }
1517
1518 static int32_t
1519 convert_integer_luminance64(int64_t src64, int bits,
1520 bool dst_is_signed, bool src_is_signed)
1521 {
1522 int32_t src32;
1523
1524 /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need
1525 * any signed<->unsigned conversion too.
1526 */
1527 if (src_is_signed && dst_is_signed)
1528 src32 = clamp_sint64_to_sint32(src64);
1529 else if (src_is_signed && !dst_is_signed)
1530 src32 = clamp_sint64_to_uint32(src64);
1531 else if (!src_is_signed && dst_is_signed)
1532 src32 = clamp_uint64_to_sint32(src64);
1533 else
1534 src32 = clamp_uint64_to_uint32(src64);
1535
1536 /* If the dst type is < 32-bit, we need an extra clamp */
1537 if (bits == 32) {
1538 return src32;
1539 } else {
1540 if (dst_is_signed)
1541 return _mesa_signed_to_signed(src32, bits);
1542 else
1543 return _mesa_unsigned_to_unsigned(src32, bits);
1544 }
1545 }
1546
1547 static int32_t
1548 convert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed)
1549 {
1550 if (src_is_signed && dst_is_signed)
1551 return _mesa_signed_to_signed(src, bits);
1552 else if (src_is_signed && !dst_is_signed)
1553 return _mesa_signed_to_unsigned(src, bits);
1554 else if (!src_is_signed && dst_is_signed)
1555 return _mesa_unsigned_to_signed(src, bits);
1556 else
1557 return _mesa_unsigned_to_unsigned(src, bits);
1558 }
1559
1560 void
1561 _mesa_pack_luminance_from_rgba_integer(GLuint n,
1562 GLuint rgba[][4], bool rgba_is_signed,
1563 GLvoid *dstAddr,
1564 GLenum dst_format,
1565 GLenum dst_type)
1566 {
1567 assert(dst_format == GL_LUMINANCE_INTEGER_EXT ||
1568 dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
1569
1570 int i;
1571 int64_t lum64;
1572 int32_t lum32, alpha;
1573 bool dst_is_signed;
1574 int dst_bits;
1575
1576 /* We first compute luminance values as a 64-bit addition of the
1577 * 32-bit R,G,B components, then we clamp the result to the dst type size.
1578 *
1579 * Notice that this operation involves casting the 32-bit R,G,B components
1580 * to 64-bit before the addition. Since rgba is defined as a GLuint array
1581 * we need to be careful when rgba packs signed data and make sure
1582 * that we cast to a 32-bit signed integer values before casting them to
1583 * 64-bit signed integers.
1584 */
1585 dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT ||
1586 dst_type == GL_INT);
1587
1588 dst_bits = _mesa_sizeof_type(dst_type) * 8;
1589 assert(dst_bits > 0);
1590
1591 switch (dst_format) {
1592 case GL_LUMINANCE_INTEGER_EXT:
1593 for (i = 0; i < n; i++) {
1594 if (!rgba_is_signed) {
1595 lum64 = (uint64_t) rgba[i][RCOMP] +
1596 (uint64_t) rgba[i][GCOMP] +
1597 (uint64_t) rgba[i][BCOMP];
1598 } else {
1599 lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1600 (int64_t) ((int32_t) rgba[i][GCOMP]) +
1601 (int64_t) ((int32_t) rgba[i][BCOMP]);
1602 }
1603 lum32 = convert_integer_luminance64(lum64, dst_bits,
1604 dst_is_signed, rgba_is_signed);
1605 switch (dst_type) {
1606 case GL_BYTE:
1607 case GL_UNSIGNED_BYTE: {
1608 GLbyte *dst = (GLbyte *) dstAddr;
1609 dst[i] = lum32;
1610 }
1611 break;
1612 case GL_SHORT:
1613 case GL_UNSIGNED_SHORT: {
1614 GLshort *dst = (GLshort *) dstAddr;
1615 dst[i] = lum32;
1616 }
1617 break;
1618 case GL_INT:
1619 case GL_UNSIGNED_INT: {
1620 GLint *dst = (GLint *) dstAddr;
1621 dst[i] = lum32;
1622 }
1623 break;
1624 }
1625 }
1626 return;
1627 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
1628 for (i = 0; i < n; i++) {
1629 if (!rgba_is_signed) {
1630 lum64 = (uint64_t) rgba[i][RCOMP] +
1631 (uint64_t) rgba[i][GCOMP] +
1632 (uint64_t) rgba[i][BCOMP];
1633 } else {
1634 lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1635 (int64_t) ((int32_t) rgba[i][GCOMP]) +
1636 (int64_t) ((int32_t) rgba[i][BCOMP]);
1637 }
1638 lum32 = convert_integer_luminance64(lum64, dst_bits,
1639 dst_is_signed, rgba_is_signed);
1640 alpha = convert_integer(rgba[i][ACOMP], dst_bits,
1641 dst_is_signed, rgba_is_signed);
1642 switch (dst_type) {
1643 case GL_BYTE:
1644 case GL_UNSIGNED_BYTE: {
1645 GLbyte *dst = (GLbyte *) dstAddr;
1646 dst[2*i] = lum32;
1647 dst[2*i+1] = alpha;
1648 }
1649 case GL_SHORT:
1650 case GL_UNSIGNED_SHORT: {
1651 GLshort *dst = (GLshort *) dstAddr;
1652 dst[i] = lum32;
1653 dst[2*i+1] = alpha;
1654 }
1655 break;
1656 case GL_INT:
1657 case GL_UNSIGNED_INT: {
1658 GLint *dst = (GLint *) dstAddr;
1659 dst[i] = lum32;
1660 dst[2*i+1] = alpha;
1661 }
1662 break;
1663 }
1664 }
1665 return;
1666 }
1667 }
1668
1669 GLfloat *
1670 _mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
1671 const void *src, GLenum srcFormat, GLenum srcType,
1672 int srcWidth, int srcHeight, int srcDepth,
1673 const struct gl_pixelstore_attrib *srcPacking,
1674 GLbitfield transferOps)
1675 {
1676 int count, img;
1677 GLuint *indexes;
1678 GLfloat *rgba, *dstPtr;
1679
1680 count = srcWidth * srcHeight;
1681 indexes = malloc(count * sizeof(GLuint));
1682 if (!indexes) {
1683 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1684 return NULL;
1685 }
1686
1687 rgba = malloc(4 * count * srcDepth * sizeof(GLfloat));
1688 if (!rgba) {
1689 free(indexes);
1690 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1691 return NULL;
1692 }
1693
1694 /* Convert indexes to RGBA float */
1695 dstPtr = rgba;
1696 for (img = 0; img < srcDepth; img++) {
1697 const GLubyte *srcPtr =
1698 (const GLubyte *) _mesa_image_address(dims, srcPacking, src,
1699 srcWidth, srcHeight,
1700 srcFormat, srcType,
1701 img, 0, 0);
1702
1703 extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking);
1704
1705 if (transferOps & IMAGE_SHIFT_OFFSET_BIT)
1706 _mesa_shift_and_offset_ci(ctx, count, indexes);
1707
1708 _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr);
1709
1710 /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
1711 * with color indexes.
1712 */
1713 transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
1714 _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr);
1715
1716 dstPtr += srcHeight * srcWidth * 4;
1717 }
1718
1719 free(indexes);
1720
1721 return rgba;
1722 }
1723
1724 GLubyte *
1725 _mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims,
1726 const void *src, GLenum srcFormat, GLenum srcType,
1727 int srcWidth, int srcHeight, int srcDepth,
1728 const struct gl_pixelstore_attrib *srcPacking,
1729 GLbitfield transferOps)
1730 {
1731 GLfloat *rgba;
1732 GLubyte *dst;
1733 int count, i;
1734
1735 transferOps |= IMAGE_CLAMP_BIT;
1736 rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims,
1737 src, srcFormat, srcType,
1738 srcWidth, srcHeight, srcDepth,
1739 srcPacking, transferOps);
1740
1741 count = srcWidth * srcHeight * srcDepth;
1742 dst = malloc(count * 4 * sizeof(GLubyte));
1743 for (i = 0; i < count; i++) {
1744 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]);
1745 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]);
1746 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]);
1747 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]);
1748 }
1749
1750 free(rgba);
1751
1752 return dst;
1753 }