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