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