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