vc4: Introduce XML-based packet header generation like Intel's.
[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 "enums.h"
47 #include "image.h"
48 #include "imports.h"
49 #include "macros.h"
50 #include "mtypes.h"
51 #include "pack.h"
52 #include "pixeltransfer.h"
53 #include "imports.h"
54 #include "glformats.h"
55 #include "format_utils.h"
56 #include "format_pack.h"
57
58
59 /**
60 * Flip the 8 bits in each byte of the given array.
61 *
62 * \param p array.
63 * \param n number of bytes.
64 *
65 * \todo try this trick to flip bytes someday:
66 * \code
67 * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555);
68 * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333);
69 * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f);
70 * \endcode
71 */
72 static void
73 flip_bytes( GLubyte *p, GLuint n )
74 {
75 GLuint i, a, b;
76 for (i = 0; i < n; i++) {
77 b = (GLuint) p[i]; /* words are often faster than bytes */
78 a = ((b & 0x01) << 7) |
79 ((b & 0x02) << 5) |
80 ((b & 0x04) << 3) |
81 ((b & 0x08) << 1) |
82 ((b & 0x10) >> 1) |
83 ((b & 0x20) >> 3) |
84 ((b & 0x40) >> 5) |
85 ((b & 0x80) >> 7);
86 p[i] = (GLubyte) a;
87 }
88 }
89
90
91
92 /*
93 * Unpack a 32x32 pixel polygon stipple from user memory using the
94 * current pixel unpack settings.
95 */
96 void
97 _mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32],
98 const struct gl_pixelstore_attrib *unpacking )
99 {
100 GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX,
101 GL_BITMAP, pattern, unpacking);
102 if (ptrn) {
103 /* Convert pattern from GLubytes to GLuints and handle big/little
104 * endian differences
105 */
106 GLubyte *p = ptrn;
107 GLint i;
108 for (i = 0; i < 32; i++) {
109 dest[i] = (p[0] << 24)
110 | (p[1] << 16)
111 | (p[2] << 8)
112 | (p[3] );
113 p += 4;
114 }
115 free(ptrn);
116 }
117 }
118
119
120 /*
121 * Pack polygon stipple into user memory given current pixel packing
122 * settings.
123 */
124 void
125 _mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest,
126 const struct gl_pixelstore_attrib *packing )
127 {
128 /* Convert pattern from GLuints to GLubytes to handle big/little
129 * endian differences.
130 */
131 GLubyte ptrn[32*4];
132 GLint i;
133 for (i = 0; i < 32; i++) {
134 ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
135 ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
136 ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
137 ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff);
138 }
139
140 _mesa_pack_bitmap(32, 32, ptrn, dest, packing);
141 }
142
143
144 /*
145 * Pack bitmap data.
146 */
147 void
148 _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
149 GLubyte *dest, const struct gl_pixelstore_attrib *packing )
150 {
151 GLint row, width_in_bytes;
152 const GLubyte *src;
153
154 if (!source)
155 return;
156
157 width_in_bytes = DIV_ROUND_UP( width, 8 );
158 src = source;
159 for (row = 0; row < height; row++) {
160 GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
161 width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
162 if (!dst)
163 return;
164
165 if ((packing->SkipPixels & 7) == 0) {
166 memcpy( dst, src, width_in_bytes );
167 if (packing->LsbFirst) {
168 flip_bytes( dst, width_in_bytes );
169 }
170 }
171 else {
172 /* handling SkipPixels is a bit tricky (no pun intended!) */
173 GLint i;
174 if (packing->LsbFirst) {
175 GLubyte srcMask = 128;
176 GLubyte dstMask = 1 << (packing->SkipPixels & 0x7);
177 const GLubyte *s = src;
178 GLubyte *d = dst;
179 *d = 0;
180 for (i = 0; i < width; i++) {
181 if (*s & srcMask) {
182 *d |= dstMask;
183 }
184 if (srcMask == 1) {
185 srcMask = 128;
186 s++;
187 }
188 else {
189 srcMask = srcMask >> 1;
190 }
191 if (dstMask == 128) {
192 dstMask = 1;
193 d++;
194 *d = 0;
195 }
196 else {
197 dstMask = dstMask << 1;
198 }
199 }
200 }
201 else {
202 GLubyte srcMask = 128;
203 GLubyte dstMask = 128 >> (packing->SkipPixels & 0x7);
204 const GLubyte *s = src;
205 GLubyte *d = dst;
206 *d = 0;
207 for (i = 0; i < width; i++) {
208 if (*s & srcMask) {
209 *d |= dstMask;
210 }
211 if (srcMask == 1) {
212 srcMask = 128;
213 s++;
214 }
215 else {
216 srcMask = srcMask >> 1;
217 }
218 if (dstMask == 1) {
219 dstMask = 128;
220 d++;
221 *d = 0;
222 }
223 else {
224 dstMask = dstMask >> 1;
225 }
226 }
227 }
228 }
229 src += width_in_bytes;
230 }
231 }
232
233
234 #define SWAP2BYTE(VALUE) \
235 { \
236 GLubyte *bytes = (GLubyte *) &(VALUE); \
237 GLubyte tmp = bytes[0]; \
238 bytes[0] = bytes[1]; \
239 bytes[1] = tmp; \
240 }
241
242 #define SWAP4BYTE(VALUE) \
243 { \
244 GLubyte *bytes = (GLubyte *) &(VALUE); \
245 GLubyte tmp = bytes[0]; \
246 bytes[0] = bytes[3]; \
247 bytes[3] = tmp; \
248 tmp = bytes[1]; \
249 bytes[1] = bytes[2]; \
250 bytes[2] = tmp; \
251 }
252
253
254 static void
255 extract_uint_indexes(GLuint n, GLuint indexes[],
256 GLenum srcFormat, GLenum srcType, const GLvoid *src,
257 const struct gl_pixelstore_attrib *unpack )
258 {
259 assert(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX);
260
261 assert(srcType == GL_BITMAP ||
262 srcType == GL_UNSIGNED_BYTE ||
263 srcType == GL_BYTE ||
264 srcType == GL_UNSIGNED_SHORT ||
265 srcType == GL_SHORT ||
266 srcType == GL_UNSIGNED_INT ||
267 srcType == GL_INT ||
268 srcType == GL_UNSIGNED_INT_24_8_EXT ||
269 srcType == GL_HALF_FLOAT_ARB ||
270 srcType == GL_HALF_FLOAT_OES ||
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 case GL_HALF_FLOAT_OES:
411 {
412 GLuint i;
413 const GLhalfARB *s = (const GLhalfARB *) src;
414 if (unpack->SwapBytes) {
415 for (i = 0; i < n; i++) {
416 GLhalfARB value = s[i];
417 SWAP2BYTE(value);
418 indexes[i] = (GLuint) _mesa_half_to_float(value);
419 }
420 }
421 else {
422 for (i = 0; i < n; i++)
423 indexes[i] = (GLuint) _mesa_half_to_float(s[i]);
424 }
425 }
426 break;
427 case GL_UNSIGNED_INT_24_8_EXT:
428 {
429 GLuint i;
430 const GLuint *s = (const GLuint *) src;
431 if (unpack->SwapBytes) {
432 for (i = 0; i < n; i++) {
433 GLuint value = s[i];
434 SWAP4BYTE(value);
435 indexes[i] = value & 0xff; /* lower 8 bits */
436 }
437 }
438 else {
439 for (i = 0; i < n; i++)
440 indexes[i] = s[i] & 0xff; /* lower 8 bits */
441 }
442 }
443 break;
444 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
445 {
446 GLuint i;
447 const GLuint *s = (const GLuint *) src;
448 if (unpack->SwapBytes) {
449 for (i = 0; i < n; i++) {
450 GLuint value = s[i*2+1];
451 SWAP4BYTE(value);
452 indexes[i] = value & 0xff; /* lower 8 bits */
453 }
454 }
455 else {
456 for (i = 0; i < n; i++)
457 indexes[i] = s[i*2+1] & 0xff; /* lower 8 bits */
458 }
459 }
460 break;
461
462 default:
463 unreachable("bad srcType in extract_uint_indexes");
464 }
465 }
466
467
468 /*
469 * Unpack a row of stencil data from a client buffer according to
470 * the pixel unpacking parameters.
471 * This is (or will be) used by glDrawPixels
472 *
473 * Args: ctx - the context
474 * n - number of pixels
475 * dstType - destination data type
476 * dest - destination array
477 * srcType - source pixel type
478 * source - source data pointer
479 * srcPacking - pixel unpacking parameters
480 * transferOps - apply offset/bias/lookup ops?
481 */
482 void
483 _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
484 GLenum dstType, GLvoid *dest,
485 GLenum srcType, const GLvoid *source,
486 const struct gl_pixelstore_attrib *srcPacking,
487 GLbitfield transferOps )
488 {
489 assert(srcType == GL_BITMAP ||
490 srcType == GL_UNSIGNED_BYTE ||
491 srcType == GL_BYTE ||
492 srcType == GL_UNSIGNED_SHORT ||
493 srcType == GL_SHORT ||
494 srcType == GL_UNSIGNED_INT ||
495 srcType == GL_INT ||
496 srcType == GL_UNSIGNED_INT_24_8_EXT ||
497 srcType == GL_HALF_FLOAT_ARB ||
498 srcType == GL_HALF_FLOAT_OES ||
499 srcType == GL_FLOAT ||
500 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
501
502 assert(dstType == GL_UNSIGNED_BYTE ||
503 dstType == GL_UNSIGNED_SHORT ||
504 dstType == GL_UNSIGNED_INT ||
505 dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
506
507 /* only shift and offset apply to stencil */
508 transferOps &= IMAGE_SHIFT_OFFSET_BIT;
509
510 /*
511 * Try simple cases first
512 */
513 if (transferOps == 0 &&
514 !ctx->Pixel.MapStencilFlag &&
515 srcType == GL_UNSIGNED_BYTE &&
516 dstType == GL_UNSIGNED_BYTE) {
517 memcpy(dest, source, n * sizeof(GLubyte));
518 }
519 else if (transferOps == 0 &&
520 !ctx->Pixel.MapStencilFlag &&
521 srcType == GL_UNSIGNED_INT &&
522 dstType == GL_UNSIGNED_INT &&
523 !srcPacking->SwapBytes) {
524 memcpy(dest, source, n * sizeof(GLuint));
525 }
526 else {
527 /*
528 * general solution
529 */
530 GLuint *indexes = malloc(n * sizeof(GLuint));
531
532 if (!indexes) {
533 _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil unpacking");
534 return;
535 }
536
537 extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
538 srcPacking);
539
540 if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
541 /* shift and offset indexes */
542 _mesa_shift_and_offset_ci(ctx, n, indexes);
543 }
544
545 if (ctx->Pixel.MapStencilFlag) {
546 /* Apply stencil lookup table */
547 const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
548 GLuint i;
549 for (i = 0; i < n; i++) {
550 indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
551 }
552 }
553
554 /* convert to dest type */
555 switch (dstType) {
556 case GL_UNSIGNED_BYTE:
557 {
558 GLubyte *dst = (GLubyte *) dest;
559 GLuint i;
560 for (i = 0; i < n; i++) {
561 dst[i] = (GLubyte) (indexes[i] & 0xff);
562 }
563 }
564 break;
565 case GL_UNSIGNED_SHORT:
566 {
567 GLuint *dst = (GLuint *) dest;
568 GLuint i;
569 for (i = 0; i < n; i++) {
570 dst[i] = (GLushort) (indexes[i] & 0xffff);
571 }
572 }
573 break;
574 case GL_UNSIGNED_INT:
575 memcpy(dest, indexes, n * sizeof(GLuint));
576 break;
577 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
578 {
579 GLuint *dst = (GLuint *) dest;
580 GLuint i;
581 for (i = 0; i < n; i++) {
582 dst[i*2+1] = indexes[i] & 0xff; /* lower 8 bits */
583 }
584 }
585 break;
586 default:
587 unreachable("bad dstType in _mesa_unpack_stencil_span");
588 }
589
590 free(indexes);
591 }
592 }
593
594
595 void
596 _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n,
597 GLenum dstType, GLvoid *dest, const GLubyte *source,
598 const struct gl_pixelstore_attrib *dstPacking )
599 {
600 GLubyte *stencil = malloc(n * sizeof(GLubyte));
601
602 if (!stencil) {
603 _mesa_error(ctx, GL_OUT_OF_MEMORY, "stencil packing");
604 return;
605 }
606
607 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
608 ctx->Pixel.MapStencilFlag) {
609 /* make a copy of input */
610 memcpy(stencil, source, n * sizeof(GLubyte));
611 _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
612 source = stencil;
613 }
614
615 switch (dstType) {
616 case GL_UNSIGNED_BYTE:
617 memcpy(dest, source, n);
618 break;
619 case GL_BYTE:
620 {
621 GLbyte *dst = (GLbyte *) dest;
622 GLuint i;
623 for (i=0;i<n;i++) {
624 dst[i] = (GLbyte) (source[i] & 0x7f);
625 }
626 }
627 break;
628 case GL_UNSIGNED_SHORT:
629 {
630 GLushort *dst = (GLushort *) dest;
631 GLuint i;
632 for (i=0;i<n;i++) {
633 dst[i] = (GLushort) source[i];
634 }
635 if (dstPacking->SwapBytes) {
636 _mesa_swap2( (GLushort *) dst, n );
637 }
638 }
639 break;
640 case GL_SHORT:
641 {
642 GLshort *dst = (GLshort *) dest;
643 GLuint i;
644 for (i=0;i<n;i++) {
645 dst[i] = (GLshort) source[i];
646 }
647 if (dstPacking->SwapBytes) {
648 _mesa_swap2( (GLushort *) dst, n );
649 }
650 }
651 break;
652 case GL_UNSIGNED_INT:
653 {
654 GLuint *dst = (GLuint *) dest;
655 GLuint i;
656 for (i=0;i<n;i++) {
657 dst[i] = (GLuint) source[i];
658 }
659 if (dstPacking->SwapBytes) {
660 _mesa_swap4( (GLuint *) dst, n );
661 }
662 }
663 break;
664 case GL_INT:
665 {
666 GLint *dst = (GLint *) dest;
667 GLuint i;
668 for (i=0;i<n;i++) {
669 dst[i] = (GLint) source[i];
670 }
671 if (dstPacking->SwapBytes) {
672 _mesa_swap4( (GLuint *) dst, n );
673 }
674 }
675 break;
676 case GL_FLOAT:
677 {
678 GLfloat *dst = (GLfloat *) dest;
679 GLuint i;
680 for (i=0;i<n;i++) {
681 dst[i] = (GLfloat) source[i];
682 }
683 if (dstPacking->SwapBytes) {
684 _mesa_swap4( (GLuint *) dst, n );
685 }
686 }
687 break;
688 case GL_HALF_FLOAT_ARB:
689 case GL_HALF_FLOAT_OES:
690 {
691 GLhalfARB *dst = (GLhalfARB *) dest;
692 GLuint i;
693 for (i=0;i<n;i++) {
694 dst[i] = _mesa_float_to_half( (float) source[i] );
695 }
696 if (dstPacking->SwapBytes) {
697 _mesa_swap2( (GLushort *) dst, n );
698 }
699 }
700 break;
701 case GL_BITMAP:
702 if (dstPacking->LsbFirst) {
703 GLubyte *dst = (GLubyte *) dest;
704 GLint shift = 0;
705 GLuint i;
706 for (i = 0; i < n; i++) {
707 if (shift == 0)
708 *dst = 0;
709 *dst |= ((source[i] != 0) << shift);
710 shift++;
711 if (shift == 8) {
712 shift = 0;
713 dst++;
714 }
715 }
716 }
717 else {
718 GLubyte *dst = (GLubyte *) dest;
719 GLint shift = 7;
720 GLuint i;
721 for (i = 0; i < n; i++) {
722 if (shift == 7)
723 *dst = 0;
724 *dst |= ((source[i] != 0) << shift);
725 shift--;
726 if (shift < 0) {
727 shift = 7;
728 dst++;
729 }
730 }
731 }
732 break;
733 default:
734 unreachable("bad type in _mesa_pack_index_span");
735 }
736
737 free(stencil);
738 }
739
740 #define DEPTH_VALUES(GLTYPE, GLTYPE2FLOAT) \
741 do { \
742 GLuint i; \
743 const GLTYPE *src = (const GLTYPE *)source; \
744 for (i = 0; i < n; i++) { \
745 GLTYPE value = src[i]; \
746 if (srcPacking->SwapBytes) { \
747 if (sizeof(GLTYPE) == 2) { \
748 SWAP2BYTE(value); \
749 } else if (sizeof(GLTYPE) == 4) { \
750 SWAP4BYTE(value); \
751 } \
752 } \
753 depthValues[i] = GLTYPE2FLOAT(value); \
754 } \
755 } while (0)
756
757
758 /**
759 * Unpack a row of depth/z values from memory, returning GLushort, GLuint
760 * or GLfloat values.
761 * The glPixelTransfer (scale/bias) params will be applied.
762 *
763 * \param dstType one of GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_FLOAT
764 * \param depthMax max value for returned GLushort or GLuint values
765 * (ignored for GLfloat).
766 */
767 void
768 _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
769 GLenum dstType, GLvoid *dest, GLuint depthMax,
770 GLenum srcType, const GLvoid *source,
771 const struct gl_pixelstore_attrib *srcPacking )
772 {
773 GLfloat *depthTemp = NULL, *depthValues;
774 GLboolean needClamp = GL_FALSE;
775
776 /* Look for special cases first.
777 * Not only are these faster, they're less prone to numeric conversion
778 * problems. Otherwise, converting from an int type to a float then
779 * back to an int type can introduce errors that will show up as
780 * artifacts in things like depth peeling which uses glCopyTexImage.
781 */
782 if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F) {
783 if (srcType == GL_UNSIGNED_INT && dstType == GL_UNSIGNED_SHORT) {
784 const GLuint *src = (const GLuint *) source;
785 GLushort *dst = (GLushort *) dest;
786 GLuint i;
787 for (i = 0; i < n; i++) {
788 dst[i] = src[i] >> 16;
789 }
790 return;
791 }
792 if (srcType == GL_UNSIGNED_SHORT
793 && dstType == GL_UNSIGNED_INT
794 && depthMax == 0xffffffff) {
795 const GLushort *src = (const GLushort *) source;
796 GLuint *dst = (GLuint *) dest;
797 GLuint i;
798 for (i = 0; i < n; i++) {
799 dst[i] = src[i] | (src[i] << 16);
800 }
801 return;
802 }
803 if (srcType == GL_UNSIGNED_INT_24_8
804 && dstType == GL_UNSIGNED_INT
805 && depthMax == 0xffffff) {
806 const GLuint *src = (const GLuint *) source;
807 GLuint *dst = (GLuint *) dest;
808 GLuint i;
809 for (i = 0; i < n; i++) {
810 dst[i] = src[i] >> 8;
811 }
812 return;
813 }
814 /* XXX may want to add additional cases here someday */
815 }
816
817 /* general case path follows */
818
819 if (dstType == GL_FLOAT) {
820 depthValues = (GLfloat *) dest;
821 }
822 else {
823 depthTemp = malloc(n * sizeof(GLfloat));
824 if (!depthTemp) {
825 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
826 return;
827 }
828
829 depthValues = depthTemp;
830 }
831
832 /* Convert incoming values to GLfloat. Some conversions will require
833 * clamping, below.
834 */
835 switch (srcType) {
836 case GL_BYTE:
837 DEPTH_VALUES(GLbyte, BYTE_TO_FLOATZ);
838 needClamp = GL_TRUE;
839 break;
840 case GL_UNSIGNED_BYTE:
841 DEPTH_VALUES(GLubyte, UBYTE_TO_FLOAT);
842 break;
843 case GL_SHORT:
844 DEPTH_VALUES(GLshort, SHORT_TO_FLOATZ);
845 needClamp = GL_TRUE;
846 break;
847 case GL_UNSIGNED_SHORT:
848 DEPTH_VALUES(GLushort, USHORT_TO_FLOAT);
849 break;
850 case GL_INT:
851 DEPTH_VALUES(GLint, INT_TO_FLOAT);
852 needClamp = GL_TRUE;
853 break;
854 case GL_UNSIGNED_INT:
855 DEPTH_VALUES(GLuint, UINT_TO_FLOAT);
856 break;
857 case GL_UNSIGNED_INT_24_8_EXT: /* GL_EXT_packed_depth_stencil */
858 if (dstType == GL_UNSIGNED_INT_24_8_EXT &&
859 depthMax == 0xffffff &&
860 ctx->Pixel.DepthScale == 1.0F &&
861 ctx->Pixel.DepthBias == 0.0F) {
862 const GLuint *src = (const GLuint *) source;
863 GLuint *zValues = (GLuint *) dest;
864 GLuint i;
865 for (i = 0; i < n; i++) {
866 GLuint value = src[i];
867 if (srcPacking->SwapBytes) {
868 SWAP4BYTE(value);
869 }
870 zValues[i] = value & 0xffffff00;
871 }
872 free(depthTemp);
873 return;
874 }
875 else {
876 const GLuint *src = (const GLuint *) source;
877 const GLfloat scale = 1.0f / 0xffffff;
878 GLuint i;
879 for (i = 0; i < n; i++) {
880 GLuint value = src[i];
881 if (srcPacking->SwapBytes) {
882 SWAP4BYTE(value);
883 }
884 depthValues[i] = (value >> 8) * scale;
885 }
886 }
887 break;
888 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
889 {
890 GLuint i;
891 const GLfloat *src = (const GLfloat *)source;
892 for (i = 0; i < n; i++) {
893 GLfloat value = src[i * 2];
894 if (srcPacking->SwapBytes) {
895 SWAP4BYTE(value);
896 }
897 depthValues[i] = value;
898 }
899 needClamp = GL_TRUE;
900 }
901 break;
902 case GL_FLOAT:
903 DEPTH_VALUES(GLfloat, 1*);
904 needClamp = GL_TRUE;
905 break;
906 case GL_HALF_FLOAT_ARB:
907 case GL_HALF_FLOAT_OES:
908 {
909 GLuint i;
910 const GLhalfARB *src = (const GLhalfARB *) source;
911 for (i = 0; i < n; i++) {
912 GLhalfARB value = src[i];
913 if (srcPacking->SwapBytes) {
914 SWAP2BYTE(value);
915 }
916 depthValues[i] = _mesa_half_to_float(value);
917 }
918 needClamp = GL_TRUE;
919 }
920 break;
921 default:
922 _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()");
923 free(depthTemp);
924 return;
925 }
926
927 /* apply depth scale and bias */
928 {
929 const GLfloat scale = ctx->Pixel.DepthScale;
930 const GLfloat bias = ctx->Pixel.DepthBias;
931 if (scale != 1.0F || bias != 0.0F) {
932 GLuint i;
933 for (i = 0; i < n; i++) {
934 depthValues[i] = depthValues[i] * scale + bias;
935 }
936 needClamp = GL_TRUE;
937 }
938 }
939
940 /* clamp to [0, 1] */
941 if (needClamp) {
942 GLuint i;
943 for (i = 0; i < n; i++) {
944 depthValues[i] = CLAMP(depthValues[i], 0.0F, 1.0F);
945 }
946 }
947
948 /*
949 * Convert values to dstType
950 */
951 if (dstType == GL_UNSIGNED_INT) {
952 GLuint *zValues = (GLuint *) dest;
953 GLuint i;
954 if (depthMax <= 0xffffff) {
955 /* no overflow worries */
956 for (i = 0; i < n; i++) {
957 zValues[i] = (GLuint) (depthValues[i] * (GLfloat) depthMax);
958 }
959 }
960 else {
961 /* need to use double precision to prevent overflow problems */
962 for (i = 0; i < n; i++) {
963 GLdouble z = depthValues[i] * (GLdouble) depthMax;
964 if (z >= (GLdouble) 0xffffffff)
965 zValues[i] = 0xffffffff;
966 else
967 zValues[i] = (GLuint) z;
968 }
969 }
970 }
971 else if (dstType == GL_UNSIGNED_SHORT) {
972 GLushort *zValues = (GLushort *) dest;
973 GLuint i;
974 assert(depthMax <= 0xffff);
975 for (i = 0; i < n; i++) {
976 zValues[i] = (GLushort) (depthValues[i] * (GLfloat) depthMax);
977 }
978 }
979 else if (dstType == GL_FLOAT) {
980 /* Nothing to do. depthValues is pointing to dest. */
981 }
982 else if (dstType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) {
983 GLfloat *zValues = (GLfloat*) dest;
984 GLuint i;
985 for (i = 0; i < n; i++) {
986 zValues[i*2] = depthValues[i];
987 }
988 }
989 else {
990 assert(0);
991 }
992
993 free(depthTemp);
994 }
995
996
997 /*
998 * Pack an array of depth values. The values are floats in [0,1].
999 */
1000 void
1001 _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
1002 GLenum dstType, const GLfloat *depthSpan,
1003 const struct gl_pixelstore_attrib *dstPacking )
1004 {
1005 GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
1006 if (!depthCopy) {
1007 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
1008 return;
1009 }
1010
1011 if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) {
1012 memcpy(depthCopy, depthSpan, n * sizeof(GLfloat));
1013 _mesa_scale_and_bias_depth(ctx, n, depthCopy);
1014 depthSpan = depthCopy;
1015 }
1016
1017 switch (dstType) {
1018 case GL_UNSIGNED_BYTE:
1019 {
1020 GLubyte *dst = (GLubyte *) dest;
1021 GLuint i;
1022 for (i = 0; i < n; i++) {
1023 dst[i] = FLOAT_TO_UBYTE( depthSpan[i] );
1024 }
1025 }
1026 break;
1027 case GL_BYTE:
1028 {
1029 GLbyte *dst = (GLbyte *) dest;
1030 GLuint i;
1031 for (i = 0; i < n; i++) {
1032 dst[i] = FLOAT_TO_BYTE( depthSpan[i] );
1033 }
1034 }
1035 break;
1036 case GL_UNSIGNED_SHORT:
1037 {
1038 GLushort *dst = (GLushort *) dest;
1039 GLuint i;
1040 for (i = 0; i < n; i++) {
1041 CLAMPED_FLOAT_TO_USHORT(dst[i], depthSpan[i]);
1042 }
1043 if (dstPacking->SwapBytes) {
1044 _mesa_swap2( (GLushort *) dst, n );
1045 }
1046 }
1047 break;
1048 case GL_SHORT:
1049 {
1050 GLshort *dst = (GLshort *) dest;
1051 GLuint i;
1052 for (i = 0; i < n; i++) {
1053 dst[i] = FLOAT_TO_SHORT( depthSpan[i] );
1054 }
1055 if (dstPacking->SwapBytes) {
1056 _mesa_swap2( (GLushort *) dst, n );
1057 }
1058 }
1059 break;
1060 case GL_UNSIGNED_INT_24_8:
1061 {
1062 const GLdouble scale = (GLdouble) 0xffffff;
1063 GLuint *dst = (GLuint *) dest;
1064 GLuint i;
1065 for (i = 0; i < n; i++) {
1066 GLuint z = (GLuint) (depthSpan[i] * scale);
1067 assert(z <= 0xffffff);
1068 dst[i] = (z << 8);
1069 }
1070 if (dstPacking->SwapBytes) {
1071 _mesa_swap4( (GLuint *) dst, n );
1072 }
1073 break;
1074 }
1075 case GL_UNSIGNED_INT:
1076 {
1077 GLuint *dst = (GLuint *) dest;
1078 GLuint i;
1079 for (i = 0; i < n; i++) {
1080 dst[i] = FLOAT_TO_UINT( depthSpan[i] );
1081 }
1082 if (dstPacking->SwapBytes) {
1083 _mesa_swap4( (GLuint *) dst, n );
1084 }
1085 }
1086 break;
1087 case GL_INT:
1088 {
1089 GLint *dst = (GLint *) dest;
1090 GLuint i;
1091 for (i = 0; i < n; i++) {
1092 dst[i] = FLOAT_TO_INT( depthSpan[i] );
1093 }
1094 if (dstPacking->SwapBytes) {
1095 _mesa_swap4( (GLuint *) dst, n );
1096 }
1097 }
1098 break;
1099 case GL_FLOAT:
1100 {
1101 GLfloat *dst = (GLfloat *) dest;
1102 GLuint i;
1103 for (i = 0; i < n; i++) {
1104 dst[i] = depthSpan[i];
1105 }
1106 if (dstPacking->SwapBytes) {
1107 _mesa_swap4( (GLuint *) dst, n );
1108 }
1109 }
1110 break;
1111 case GL_HALF_FLOAT_ARB:
1112 case GL_HALF_FLOAT_OES:
1113 {
1114 GLhalfARB *dst = (GLhalfARB *) dest;
1115 GLuint i;
1116 for (i = 0; i < n; i++) {
1117 dst[i] = _mesa_float_to_half(depthSpan[i]);
1118 }
1119 if (dstPacking->SwapBytes) {
1120 _mesa_swap2( (GLushort *) dst, n );
1121 }
1122 }
1123 break;
1124 default:
1125 unreachable("bad type in _mesa_pack_depth_span()");
1126 }
1127
1128 free(depthCopy);
1129 }
1130
1131
1132
1133 /**
1134 * Pack depth and stencil values as GL_DEPTH_STENCIL (GL_UNSIGNED_INT_24_8 etc)
1135 */
1136 void
1137 _mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n,
1138 GLenum dstType, GLuint *dest,
1139 const GLfloat *depthVals,
1140 const GLubyte *stencilVals,
1141 const struct gl_pixelstore_attrib *dstPacking)
1142 {
1143 GLfloat *depthCopy = malloc(n * sizeof(GLfloat));
1144 GLubyte *stencilCopy = malloc(n * sizeof(GLubyte));
1145 GLuint i;
1146
1147 if (!depthCopy || !stencilCopy) {
1148 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing");
1149 free(depthCopy);
1150 free(stencilCopy);
1151 return;
1152 }
1153
1154 if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) {
1155 memcpy(depthCopy, depthVals, n * sizeof(GLfloat));
1156 _mesa_scale_and_bias_depth(ctx, n, depthCopy);
1157 depthVals = depthCopy;
1158 }
1159
1160 if (ctx->Pixel.IndexShift ||
1161 ctx->Pixel.IndexOffset ||
1162 ctx->Pixel.MapStencilFlag) {
1163 memcpy(stencilCopy, stencilVals, n * sizeof(GLubyte));
1164 _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
1165 stencilVals = stencilCopy;
1166 }
1167
1168 switch (dstType) {
1169 case GL_UNSIGNED_INT_24_8:
1170 for (i = 0; i < n; i++) {
1171 GLuint z = (GLuint) (depthVals[i] * 0xffffff);
1172 dest[i] = (z << 8) | (stencilVals[i] & 0xff);
1173 }
1174 break;
1175 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1176 for (i = 0; i < n; i++) {
1177 ((GLfloat*)dest)[i*2] = depthVals[i];
1178 dest[i*2+1] = stencilVals[i] & 0xff;
1179 }
1180 break;
1181 }
1182
1183 if (dstPacking->SwapBytes) {
1184 _mesa_swap4(dest, n);
1185 }
1186
1187 free(depthCopy);
1188 free(stencilCopy);
1189 }
1190
1191
1192
1193 /**
1194 * Unpack image data. Apply byte swapping, byte flipping (bitmap).
1195 * Return all image data in a contiguous block. This is used when we
1196 * compile glDrawPixels, glTexImage, etc into a display list. We
1197 * need a copy of the data in a standard format.
1198 */
1199 void *
1200 _mesa_unpack_image( GLuint dimensions,
1201 GLsizei width, GLsizei height, GLsizei depth,
1202 GLenum format, GLenum type, const GLvoid *pixels,
1203 const struct gl_pixelstore_attrib *unpack )
1204 {
1205 GLint bytesPerRow, compsPerRow;
1206 GLboolean flipBytes, swap2, swap4;
1207
1208 if (!pixels)
1209 return NULL; /* not necessarily an error */
1210
1211 if (width <= 0 || height <= 0 || depth <= 0)
1212 return NULL; /* generate error later */
1213
1214 if (type == GL_BITMAP) {
1215 bytesPerRow = (width + 7) >> 3;
1216 flipBytes = unpack->LsbFirst;
1217 swap2 = swap4 = GL_FALSE;
1218 compsPerRow = 0;
1219 }
1220 else {
1221 const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type);
1222 GLint components = _mesa_components_in_format(format);
1223 GLint bytesPerComp;
1224
1225 if (_mesa_type_is_packed(type))
1226 components = 1;
1227
1228 if (bytesPerPixel <= 0 || components <= 0)
1229 return NULL; /* bad format or type. generate error later */
1230 bytesPerRow = bytesPerPixel * width;
1231 bytesPerComp = bytesPerPixel / components;
1232 flipBytes = GL_FALSE;
1233 swap2 = (bytesPerComp == 2) && unpack->SwapBytes;
1234 swap4 = (bytesPerComp == 4) && unpack->SwapBytes;
1235 compsPerRow = components * width;
1236 assert(compsPerRow >= width);
1237 }
1238
1239 {
1240 GLubyte *destBuffer
1241 = malloc(bytesPerRow * height * depth);
1242 GLubyte *dst;
1243 GLint img, row;
1244 if (!destBuffer)
1245 return NULL; /* generate GL_OUT_OF_MEMORY later */
1246
1247 dst = destBuffer;
1248 for (img = 0; img < depth; img++) {
1249 for (row = 0; row < height; row++) {
1250 const GLvoid *src = _mesa_image_address(dimensions, unpack, pixels,
1251 width, height, format, type, img, row, 0);
1252
1253 if ((type == GL_BITMAP) && (unpack->SkipPixels & 0x7)) {
1254 GLint i;
1255 flipBytes = GL_FALSE;
1256 if (unpack->LsbFirst) {
1257 GLubyte srcMask = 1 << (unpack->SkipPixels & 0x7);
1258 GLubyte dstMask = 128;
1259 const GLubyte *s = src;
1260 GLubyte *d = dst;
1261 *d = 0;
1262 for (i = 0; i < width; i++) {
1263 if (*s & srcMask) {
1264 *d |= dstMask;
1265 }
1266 if (srcMask == 128) {
1267 srcMask = 1;
1268 s++;
1269 }
1270 else {
1271 srcMask = srcMask << 1;
1272 }
1273 if (dstMask == 1) {
1274 dstMask = 128;
1275 d++;
1276 *d = 0;
1277 }
1278 else {
1279 dstMask = dstMask >> 1;
1280 }
1281 }
1282 }
1283 else {
1284 GLubyte srcMask = 128 >> (unpack->SkipPixels & 0x7);
1285 GLubyte dstMask = 128;
1286 const GLubyte *s = src;
1287 GLubyte *d = dst;
1288 *d = 0;
1289 for (i = 0; i < width; i++) {
1290 if (*s & srcMask) {
1291 *d |= dstMask;
1292 }
1293 if (srcMask == 1) {
1294 srcMask = 128;
1295 s++;
1296 }
1297 else {
1298 srcMask = srcMask >> 1;
1299 }
1300 if (dstMask == 1) {
1301 dstMask = 128;
1302 d++;
1303 *d = 0;
1304 }
1305 else {
1306 dstMask = dstMask >> 1;
1307 }
1308 }
1309 }
1310 }
1311 else {
1312 memcpy(dst, src, bytesPerRow);
1313 }
1314
1315 /* byte flipping/swapping */
1316 if (flipBytes) {
1317 flip_bytes((GLubyte *) dst, bytesPerRow);
1318 }
1319 else if (swap2) {
1320 _mesa_swap2((GLushort*) dst, compsPerRow);
1321 }
1322 else if (swap4) {
1323 _mesa_swap4((GLuint*) dst, compsPerRow);
1324 }
1325 dst += bytesPerRow;
1326 }
1327 }
1328 return destBuffer;
1329 }
1330 }
1331
1332 void
1333 _mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4],
1334 GLvoid *dstAddr, GLenum dst_format,
1335 GLbitfield transferOps)
1336 {
1337 int i;
1338 GLfloat *dst = (GLfloat *) dstAddr;
1339
1340 switch (dst_format) {
1341 case GL_LUMINANCE:
1342 if (transferOps & IMAGE_CLAMP_BIT) {
1343 for (i = 0; i < n; i++) {
1344 GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1345 dst[i] = CLAMP(sum, 0.0F, 1.0F);
1346 }
1347 } else {
1348 for (i = 0; i < n; i++) {
1349 dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1350 }
1351 }
1352 return;
1353 case GL_LUMINANCE_ALPHA:
1354 if (transferOps & IMAGE_CLAMP_BIT) {
1355 for (i = 0; i < n; i++) {
1356 GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1357 dst[2*i] = CLAMP(sum, 0.0F, 1.0F);
1358 dst[2*i+1] = rgba[i][ACOMP];
1359 }
1360 } else {
1361 for (i = 0; i < n; i++) {
1362 dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1363 dst[2*i+1] = rgba[i][ACOMP];
1364 }
1365 }
1366 return;
1367 default:
1368 assert(!"Unsupported format");
1369 }
1370 }
1371
1372 static int32_t
1373 clamp_sint64_to_sint32(int64_t src)
1374 {
1375 return CLAMP(src, INT32_MIN, INT32_MAX);
1376 }
1377
1378 static int32_t
1379 clamp_sint64_to_uint32(int64_t src)
1380 {
1381 return CLAMP(src, 0, UINT32_MAX);
1382 }
1383
1384 static int32_t
1385 clamp_uint64_to_uint32(uint64_t src)
1386 {
1387 return MIN2(src, UINT32_MAX);
1388 }
1389
1390 static int32_t
1391 clamp_uint64_to_sint32(uint64_t src)
1392 {
1393 return MIN2(src, INT32_MAX);
1394 }
1395
1396 static int32_t
1397 convert_integer_luminance64(int64_t src64, int bits,
1398 bool dst_is_signed, bool src_is_signed)
1399 {
1400 int32_t src32;
1401
1402 /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need
1403 * any signed<->unsigned conversion too.
1404 */
1405 if (src_is_signed && dst_is_signed)
1406 src32 = clamp_sint64_to_sint32(src64);
1407 else if (src_is_signed && !dst_is_signed)
1408 src32 = clamp_sint64_to_uint32(src64);
1409 else if (!src_is_signed && dst_is_signed)
1410 src32 = clamp_uint64_to_sint32(src64);
1411 else
1412 src32 = clamp_uint64_to_uint32(src64);
1413
1414 /* If the dst type is < 32-bit, we need an extra clamp */
1415 if (bits == 32) {
1416 return src32;
1417 } else {
1418 if (dst_is_signed)
1419 return _mesa_signed_to_signed(src32, bits);
1420 else
1421 return _mesa_unsigned_to_unsigned(src32, bits);
1422 }
1423 }
1424
1425 static int32_t
1426 convert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed)
1427 {
1428 if (src_is_signed && dst_is_signed)
1429 return _mesa_signed_to_signed(src, bits);
1430 else if (src_is_signed && !dst_is_signed)
1431 return _mesa_signed_to_unsigned(src, bits);
1432 else if (!src_is_signed && dst_is_signed)
1433 return _mesa_unsigned_to_signed(src, bits);
1434 else
1435 return _mesa_unsigned_to_unsigned(src, bits);
1436 }
1437
1438 void
1439 _mesa_pack_luminance_from_rgba_integer(GLuint n,
1440 GLuint rgba[][4], bool rgba_is_signed,
1441 GLvoid *dstAddr,
1442 GLenum dst_format,
1443 GLenum dst_type)
1444 {
1445 int i;
1446 int64_t lum64;
1447 int32_t lum32, alpha;
1448 bool dst_is_signed;
1449 int dst_bits;
1450
1451 assert(dst_format == GL_LUMINANCE_INTEGER_EXT ||
1452 dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
1453
1454 /* We first compute luminance values as a 64-bit addition of the
1455 * 32-bit R,G,B components, then we clamp the result to the dst type size.
1456 *
1457 * Notice that this operation involves casting the 32-bit R,G,B components
1458 * to 64-bit before the addition. Since rgba is defined as a GLuint array
1459 * we need to be careful when rgba packs signed data and make sure
1460 * that we cast to a 32-bit signed integer values before casting them to
1461 * 64-bit signed integers.
1462 */
1463 dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT ||
1464 dst_type == GL_INT);
1465
1466 dst_bits = _mesa_sizeof_type(dst_type) * 8;
1467 assert(dst_bits > 0);
1468
1469 switch (dst_format) {
1470 case GL_LUMINANCE_INTEGER_EXT:
1471 for (i = 0; i < n; i++) {
1472 if (!rgba_is_signed) {
1473 lum64 = (uint64_t) rgba[i][RCOMP] +
1474 (uint64_t) rgba[i][GCOMP] +
1475 (uint64_t) rgba[i][BCOMP];
1476 } else {
1477 lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1478 (int64_t) ((int32_t) rgba[i][GCOMP]) +
1479 (int64_t) ((int32_t) rgba[i][BCOMP]);
1480 }
1481 lum32 = convert_integer_luminance64(lum64, dst_bits,
1482 dst_is_signed, rgba_is_signed);
1483 switch (dst_type) {
1484 case GL_BYTE:
1485 case GL_UNSIGNED_BYTE: {
1486 GLbyte *dst = (GLbyte *) dstAddr;
1487 dst[i] = lum32;
1488 break;
1489 }
1490 case GL_SHORT:
1491 case GL_UNSIGNED_SHORT: {
1492 GLshort *dst = (GLshort *) dstAddr;
1493 dst[i] = lum32;
1494 break;
1495 }
1496 case GL_INT:
1497 case GL_UNSIGNED_INT: {
1498 GLint *dst = (GLint *) dstAddr;
1499 dst[i] = lum32;
1500 break;
1501 }
1502 }
1503 }
1504 return;
1505 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
1506 for (i = 0; i < n; i++) {
1507 if (!rgba_is_signed) {
1508 lum64 = (uint64_t) rgba[i][RCOMP] +
1509 (uint64_t) rgba[i][GCOMP] +
1510 (uint64_t) rgba[i][BCOMP];
1511 } else {
1512 lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1513 (int64_t) ((int32_t) rgba[i][GCOMP]) +
1514 (int64_t) ((int32_t) rgba[i][BCOMP]);
1515 }
1516 lum32 = convert_integer_luminance64(lum64, dst_bits,
1517 dst_is_signed, rgba_is_signed);
1518 alpha = convert_integer(rgba[i][ACOMP], dst_bits,
1519 dst_is_signed, rgba_is_signed);
1520 switch (dst_type) {
1521 case GL_BYTE:
1522 case GL_UNSIGNED_BYTE: {
1523 GLbyte *dst = (GLbyte *) dstAddr;
1524 dst[2*i] = lum32;
1525 dst[2*i+1] = alpha;
1526 break;
1527 }
1528 case GL_SHORT:
1529 case GL_UNSIGNED_SHORT: {
1530 GLshort *dst = (GLshort *) dstAddr;
1531 dst[i] = lum32;
1532 dst[2*i+1] = alpha;
1533 break;
1534 }
1535 case GL_INT:
1536 case GL_UNSIGNED_INT: {
1537 GLint *dst = (GLint *) dstAddr;
1538 dst[i] = lum32;
1539 dst[2*i+1] = alpha;
1540 break;
1541 }
1542 }
1543 }
1544 return;
1545 }
1546 }
1547
1548 GLfloat *
1549 _mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
1550 const void *src, GLenum srcFormat, GLenum srcType,
1551 int srcWidth, int srcHeight, int srcDepth,
1552 const struct gl_pixelstore_attrib *srcPacking,
1553 GLbitfield transferOps)
1554 {
1555 int count, img;
1556 GLuint *indexes;
1557 GLfloat *rgba, *dstPtr;
1558
1559 count = srcWidth * srcHeight;
1560 indexes = malloc(count * sizeof(GLuint));
1561 if (!indexes) {
1562 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1563 return NULL;
1564 }
1565
1566 rgba = malloc(4 * count * srcDepth * sizeof(GLfloat));
1567 if (!rgba) {
1568 free(indexes);
1569 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1570 return NULL;
1571 }
1572
1573 /* Convert indexes to RGBA float */
1574 dstPtr = rgba;
1575 for (img = 0; img < srcDepth; img++) {
1576 const GLubyte *srcPtr =
1577 (const GLubyte *) _mesa_image_address(dims, srcPacking, src,
1578 srcWidth, srcHeight,
1579 srcFormat, srcType,
1580 img, 0, 0);
1581
1582 extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking);
1583
1584 if (transferOps & IMAGE_SHIFT_OFFSET_BIT)
1585 _mesa_shift_and_offset_ci(ctx, count, indexes);
1586
1587 _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr);
1588
1589 /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
1590 * with color indexes.
1591 */
1592 transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
1593 _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr);
1594
1595 dstPtr += srcHeight * srcWidth * 4;
1596 }
1597
1598 free(indexes);
1599
1600 return rgba;
1601 }
1602
1603 GLubyte *
1604 _mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims,
1605 const void *src, GLenum srcFormat, GLenum srcType,
1606 int srcWidth, int srcHeight, int srcDepth,
1607 const struct gl_pixelstore_attrib *srcPacking,
1608 GLbitfield transferOps)
1609 {
1610 GLfloat *rgba;
1611 GLubyte *dst;
1612 int count, i;
1613
1614 transferOps |= IMAGE_CLAMP_BIT;
1615 rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims,
1616 src, srcFormat, srcType,
1617 srcWidth, srcHeight, srcDepth,
1618 srcPacking, transferOps);
1619
1620 count = srcWidth * srcHeight * srcDepth;
1621 dst = malloc(count * 4 * sizeof(GLubyte));
1622 for (i = 0; i < count; i++) {
1623 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]);
1624 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]);
1625 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]);
1626 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]);
1627 }
1628
1629 free(rgba);
1630
1631 return dst;
1632 }