mesa: Remove _mesa_rebase_rgba_uint and _mesa_rebase_rgba_float
[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 void
1329 _mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4],
1330 GLvoid *dstAddr, GLenum dst_format,
1331 GLbitfield transferOps)
1332 {
1333 int i;
1334 GLfloat *dst = (GLfloat *) dstAddr;
1335
1336 switch (dst_format) {
1337 case GL_LUMINANCE:
1338 if (transferOps & IMAGE_CLAMP_BIT) {
1339 for (i = 0; i < n; i++) {
1340 GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1341 dst[i] = CLAMP(sum, 0.0F, 1.0F);
1342 }
1343 } else {
1344 for (i = 0; i < n; i++) {
1345 dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1346 }
1347 }
1348 return;
1349 case GL_LUMINANCE_ALPHA:
1350 if (transferOps & IMAGE_CLAMP_BIT) {
1351 for (i = 0; i < n; i++) {
1352 GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1353 dst[2*i] = CLAMP(sum, 0.0F, 1.0F);
1354 dst[2*i+1] = rgba[i][ACOMP];
1355 }
1356 } else {
1357 for (i = 0; i < n; i++) {
1358 dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
1359 dst[2*i+1] = rgba[i][ACOMP];
1360 }
1361 }
1362 return;
1363 default:
1364 assert(!"Unsupported format");
1365 }
1366 }
1367
1368 static int32_t
1369 clamp_sint64_to_sint32(int64_t src)
1370 {
1371 return CLAMP(src, INT32_MIN, INT32_MAX);
1372 }
1373
1374 static int32_t
1375 clamp_sint64_to_uint32(int64_t src)
1376 {
1377 return CLAMP(src, 0, UINT32_MAX);
1378 }
1379
1380 static int32_t
1381 clamp_uint64_to_uint32(uint64_t src)
1382 {
1383 return MIN2(src, UINT32_MAX);
1384 }
1385
1386 static int32_t
1387 clamp_uint64_to_sint32(uint64_t src)
1388 {
1389 return MIN2(src, INT32_MAX);
1390 }
1391
1392 static int32_t
1393 convert_integer_luminance64(int64_t src64, int bits,
1394 bool dst_is_signed, bool src_is_signed)
1395 {
1396 int32_t src32;
1397
1398 /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need
1399 * any signed<->unsigned conversion too.
1400 */
1401 if (src_is_signed && dst_is_signed)
1402 src32 = clamp_sint64_to_sint32(src64);
1403 else if (src_is_signed && !dst_is_signed)
1404 src32 = clamp_sint64_to_uint32(src64);
1405 else if (!src_is_signed && dst_is_signed)
1406 src32 = clamp_uint64_to_sint32(src64);
1407 else
1408 src32 = clamp_uint64_to_uint32(src64);
1409
1410 /* If the dst type is < 32-bit, we need an extra clamp */
1411 if (bits == 32) {
1412 return src32;
1413 } else {
1414 if (dst_is_signed)
1415 return _mesa_signed_to_signed(src32, bits);
1416 else
1417 return _mesa_unsigned_to_unsigned(src32, bits);
1418 }
1419 }
1420
1421 static int32_t
1422 convert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed)
1423 {
1424 if (src_is_signed && dst_is_signed)
1425 return _mesa_signed_to_signed(src, bits);
1426 else if (src_is_signed && !dst_is_signed)
1427 return _mesa_signed_to_unsigned(src, bits);
1428 else if (!src_is_signed && dst_is_signed)
1429 return _mesa_unsigned_to_signed(src, bits);
1430 else
1431 return _mesa_unsigned_to_unsigned(src, bits);
1432 }
1433
1434 void
1435 _mesa_pack_luminance_from_rgba_integer(GLuint n,
1436 GLuint rgba[][4], bool rgba_is_signed,
1437 GLvoid *dstAddr,
1438 GLenum dst_format,
1439 GLenum dst_type)
1440 {
1441 assert(dst_format == GL_LUMINANCE_INTEGER_EXT ||
1442 dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT);
1443
1444 int i;
1445 int64_t lum64;
1446 int32_t lum32, alpha;
1447 bool dst_is_signed;
1448 int dst_bits;
1449
1450 /* We first compute luminance values as a 64-bit addition of the
1451 * 32-bit R,G,B components, then we clamp the result to the dst type size.
1452 *
1453 * Notice that this operation involves casting the 32-bit R,G,B components
1454 * to 64-bit before the addition. Since rgba is defined as a GLuint array
1455 * we need to be careful when rgba packs signed data and make sure
1456 * that we cast to a 32-bit signed integer values before casting them to
1457 * 64-bit signed integers.
1458 */
1459 dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT ||
1460 dst_type == GL_INT);
1461
1462 dst_bits = _mesa_sizeof_type(dst_type) * 8;
1463 assert(dst_bits > 0);
1464
1465 switch (dst_format) {
1466 case GL_LUMINANCE_INTEGER_EXT:
1467 for (i = 0; i < n; i++) {
1468 if (!rgba_is_signed) {
1469 lum64 = (uint64_t) rgba[i][RCOMP] +
1470 (uint64_t) rgba[i][GCOMP] +
1471 (uint64_t) rgba[i][BCOMP];
1472 } else {
1473 lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1474 (int64_t) ((int32_t) rgba[i][GCOMP]) +
1475 (int64_t) ((int32_t) rgba[i][BCOMP]);
1476 }
1477 lum32 = convert_integer_luminance64(lum64, dst_bits,
1478 dst_is_signed, rgba_is_signed);
1479 switch (dst_type) {
1480 case GL_BYTE:
1481 case GL_UNSIGNED_BYTE: {
1482 GLbyte *dst = (GLbyte *) dstAddr;
1483 dst[i] = lum32;
1484 }
1485 break;
1486 case GL_SHORT:
1487 case GL_UNSIGNED_SHORT: {
1488 GLshort *dst = (GLshort *) dstAddr;
1489 dst[i] = lum32;
1490 }
1491 break;
1492 case GL_INT:
1493 case GL_UNSIGNED_INT: {
1494 GLint *dst = (GLint *) dstAddr;
1495 dst[i] = lum32;
1496 }
1497 break;
1498 }
1499 }
1500 return;
1501 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
1502 for (i = 0; i < n; i++) {
1503 if (!rgba_is_signed) {
1504 lum64 = (uint64_t) rgba[i][RCOMP] +
1505 (uint64_t) rgba[i][GCOMP] +
1506 (uint64_t) rgba[i][BCOMP];
1507 } else {
1508 lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) +
1509 (int64_t) ((int32_t) rgba[i][GCOMP]) +
1510 (int64_t) ((int32_t) rgba[i][BCOMP]);
1511 }
1512 lum32 = convert_integer_luminance64(lum64, dst_bits,
1513 dst_is_signed, rgba_is_signed);
1514 alpha = convert_integer(rgba[i][ACOMP], dst_bits,
1515 dst_is_signed, rgba_is_signed);
1516 switch (dst_type) {
1517 case GL_BYTE:
1518 case GL_UNSIGNED_BYTE: {
1519 GLbyte *dst = (GLbyte *) dstAddr;
1520 dst[2*i] = lum32;
1521 dst[2*i+1] = alpha;
1522 }
1523 case GL_SHORT:
1524 case GL_UNSIGNED_SHORT: {
1525 GLshort *dst = (GLshort *) dstAddr;
1526 dst[i] = lum32;
1527 dst[2*i+1] = alpha;
1528 }
1529 break;
1530 case GL_INT:
1531 case GL_UNSIGNED_INT: {
1532 GLint *dst = (GLint *) dstAddr;
1533 dst[i] = lum32;
1534 dst[2*i+1] = alpha;
1535 }
1536 break;
1537 }
1538 }
1539 return;
1540 }
1541 }
1542
1543 GLfloat *
1544 _mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
1545 const void *src, GLenum srcFormat, GLenum srcType,
1546 int srcWidth, int srcHeight, int srcDepth,
1547 const struct gl_pixelstore_attrib *srcPacking,
1548 GLbitfield transferOps)
1549 {
1550 int count, img;
1551 GLuint *indexes;
1552 GLfloat *rgba, *dstPtr;
1553
1554 count = srcWidth * srcHeight;
1555 indexes = malloc(count * sizeof(GLuint));
1556 if (!indexes) {
1557 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1558 return NULL;
1559 }
1560
1561 rgba = malloc(4 * count * srcDepth * sizeof(GLfloat));
1562 if (!rgba) {
1563 free(indexes);
1564 _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
1565 return NULL;
1566 }
1567
1568 /* Convert indexes to RGBA float */
1569 dstPtr = rgba;
1570 for (img = 0; img < srcDepth; img++) {
1571 const GLubyte *srcPtr =
1572 (const GLubyte *) _mesa_image_address(dims, srcPacking, src,
1573 srcWidth, srcHeight,
1574 srcFormat, srcType,
1575 img, 0, 0);
1576
1577 extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking);
1578
1579 if (transferOps & IMAGE_SHIFT_OFFSET_BIT)
1580 _mesa_shift_and_offset_ci(ctx, count, indexes);
1581
1582 _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr);
1583
1584 /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
1585 * with color indexes.
1586 */
1587 transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
1588 _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr);
1589
1590 dstPtr += srcHeight * srcWidth * 4;
1591 }
1592
1593 free(indexes);
1594
1595 return rgba;
1596 }
1597
1598 GLubyte *
1599 _mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims,
1600 const void *src, GLenum srcFormat, GLenum srcType,
1601 int srcWidth, int srcHeight, int srcDepth,
1602 const struct gl_pixelstore_attrib *srcPacking,
1603 GLbitfield transferOps)
1604 {
1605 GLfloat *rgba;
1606 GLubyte *dst;
1607 int count, i;
1608
1609 transferOps |= IMAGE_CLAMP_BIT;
1610 rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims,
1611 src, srcFormat, srcType,
1612 srcWidth, srcHeight, srcDepth,
1613 srcPacking, transferOps);
1614
1615 count = srcWidth * srcHeight * srcDepth;
1616 dst = malloc(count * 4 * sizeof(GLubyte));
1617 for (i = 0; i < count; i++) {
1618 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]);
1619 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]);
1620 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]);
1621 CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]);
1622 }
1623
1624 free(rgba);
1625
1626 return dst;
1627 }