Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
  3.  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice including the dates of first publication and
  13.  * either this permission notice or a reference to
  14.  * http://oss.sgi.com/projects/FreeB/
  15.  * shall be included 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.  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21.  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  22.  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Except as contained in this notice, the name of Silicon Graphics, Inc.
  26.  * shall not be used in advertising or otherwise to promote the sale, use or
  27.  * other dealings in this Software without prior written authorization from
  28.  * Silicon Graphics, Inc.
  29.  */
  30.  
  31. #include "gluos.h"
  32. #include <assert.h>
  33. #include <GL/glu.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <limits.h>             /* UINT_MAX */
  38. #include <math.h>
  39.  
  40. typedef union {
  41.     unsigned char ub[4];
  42.     unsigned short us[2];
  43.     unsigned int ui;
  44.     char b[4];
  45.     short s[2];
  46.     int i;
  47.     float f;
  48. } Type_Widget;
  49.  
  50. /* Pixel storage modes */
  51. typedef struct {
  52.    GLint pack_alignment;
  53.    GLint pack_row_length;
  54.    GLint pack_skip_rows;
  55.    GLint pack_skip_pixels;
  56.    GLint pack_lsb_first;
  57.    GLint pack_swap_bytes;
  58.    GLint pack_skip_images;
  59.    GLint pack_image_height;
  60.  
  61.    GLint unpack_alignment;
  62.    GLint unpack_row_length;
  63.    GLint unpack_skip_rows;
  64.    GLint unpack_skip_pixels;
  65.    GLint unpack_lsb_first;
  66.    GLint unpack_swap_bytes;
  67.    GLint unpack_skip_images;
  68.    GLint unpack_image_height;
  69. } PixelStorageModes;
  70.  
  71. static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
  72.                                       GLsizei,
  73.                                       GLsizei,
  74.                                       GLenum, GLenum, GLint, GLint, GLint,
  75.                                       const void *);
  76. static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
  77.                                       GLsizei, GLsizei,
  78.                                       GLsizei, GLsizei,
  79.                                       GLenum, GLenum, GLint, GLint, GLint,
  80.                                       const void *);
  81. static int gluBuild3DMipmapLevelsCore(GLenum, GLint,
  82.                                       GLsizei, GLsizei, GLsizei,
  83.                                       GLsizei, GLsizei, GLsizei,
  84.                                       GLenum, GLenum, GLint, GLint, GLint,
  85.                                       const void *);
  86.  
  87. /*
  88.  * internal function declarations
  89.  */
  90. static GLfloat bytes_per_element(GLenum type);
  91. static GLint elements_per_group(GLenum format, GLenum type);
  92. static GLint is_index(GLenum format);
  93. static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
  94. static void fill_image(const PixelStorageModes *,
  95.                        GLint width, GLint height, GLenum format,
  96.                        GLenum type, GLboolean index_format,
  97.                        const void *userdata, GLushort *newimage);
  98. static void empty_image(const PixelStorageModes *,
  99.                         GLint width, GLint height, GLenum format,
  100.                         GLenum type, GLboolean index_format,
  101.                         const GLushort *oldimage, void *userdata);
  102. static void scale_internal(GLint components, GLint widthin, GLint heightin,
  103.                            const GLushort *datain,
  104.                            GLint widthout, GLint heightout,
  105.                            GLushort *dataout);
  106.  
  107. static void scale_internal_ubyte(GLint components, GLint widthin,
  108.                            GLint heightin, const GLubyte *datain,
  109.                            GLint widthout, GLint heightout,
  110.                            GLubyte *dataout, GLint element_size,
  111.                            GLint ysize, GLint group_size);
  112. static void scale_internal_byte(GLint components, GLint widthin,
  113.                            GLint heightin, const GLbyte *datain,
  114.                            GLint widthout, GLint heightout,
  115.                            GLbyte *dataout, GLint element_size,
  116.                            GLint ysize, GLint group_size);
  117. static void scale_internal_ushort(GLint components, GLint widthin,
  118.                            GLint heightin, const GLushort *datain,
  119.                            GLint widthout, GLint heightout,
  120.                            GLushort *dataout, GLint element_size,
  121.                            GLint ysize, GLint group_size,
  122.                            GLint myswap_bytes);
  123. static void scale_internal_short(GLint components, GLint widthin,
  124.                            GLint heightin, const GLshort *datain,
  125.                            GLint widthout, GLint heightout,
  126.                            GLshort *dataout, GLint element_size,
  127.                            GLint ysize, GLint group_size,
  128.                            GLint myswap_bytes);
  129. static void scale_internal_uint(GLint components, GLint widthin,
  130.                            GLint heightin, const GLuint *datain,
  131.                            GLint widthout, GLint heightout,
  132.                            GLuint *dataout, GLint element_size,
  133.                            GLint ysize, GLint group_size,
  134.                            GLint myswap_bytes);
  135. static void scale_internal_int(GLint components, GLint widthin,
  136.                            GLint heightin, const GLint *datain,
  137.                            GLint widthout, GLint heightout,
  138.                            GLint *dataout, GLint element_size,
  139.                            GLint ysize, GLint group_size,
  140.                            GLint myswap_bytes);
  141. static void scale_internal_float(GLint components, GLint widthin,
  142.                            GLint heightin, const GLfloat *datain,
  143.                            GLint widthout, GLint heightout,
  144.                            GLfloat *dataout, GLint element_size,
  145.                            GLint ysize, GLint group_size,
  146.                            GLint myswap_bytes);
  147.  
  148. static int checkMipmapArgs(GLenum, GLenum, GLenum);
  149. static GLboolean legalFormat(GLenum);
  150. static GLboolean legalType(GLenum);
  151. static GLboolean isTypePackedPixel(GLenum);
  152. static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
  153. static GLboolean isLegalLevels(GLint, GLint, GLint, GLint);
  154. static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
  155.                        GLint *, GLint *);
  156.  
  157. /* all extract/shove routines must return double to handle unsigned ints */
  158. static GLdouble extractUbyte(int, const void *);
  159. static void shoveUbyte(GLdouble, int, void *);
  160. static GLdouble extractSbyte(int, const void *);
  161. static void shoveSbyte(GLdouble, int, void *);
  162. static GLdouble extractUshort(int, const void *);
  163. static void shoveUshort(GLdouble, int, void *);
  164. static GLdouble extractSshort(int, const void *);
  165. static void shoveSshort(GLdouble, int, void *);
  166. static GLdouble extractUint(int, const void *);
  167. static void shoveUint(GLdouble, int, void *);
  168. static GLdouble extractSint(int, const void *);
  169. static void shoveSint(GLdouble, int, void *);
  170. static GLdouble extractFloat(int, const void *);
  171. static void shoveFloat(GLdouble, int, void *);
  172. static void halveImageSlice(int, GLdouble (*)(int, const void *),
  173.                             void (*)(GLdouble, int, void *),
  174.                             GLint, GLint, GLint,
  175.                             const void *, void *,
  176.                             GLint, GLint, GLint, GLint, GLint);
  177. static void halveImage3D(int, GLdouble (*)(int, const void *),
  178.                          void (*)(GLdouble, int, void *),
  179.                          GLint, GLint, GLint,
  180.                          const void *, void *,
  181.                          GLint, GLint, GLint, GLint, GLint);
  182.  
  183. /* packedpixel type scale routines */
  184. static void extract332(int,const void *, GLfloat []);
  185. static void shove332(const GLfloat [],int ,void *);
  186. static void extract233rev(int,const void *, GLfloat []);
  187. static void shove233rev(const GLfloat [],int ,void *);
  188. static void extract565(int,const void *, GLfloat []);
  189. static void shove565(const GLfloat [],int ,void *);
  190. static void extract565rev(int,const void *, GLfloat []);
  191. static void shove565rev(const GLfloat [],int ,void *);
  192. static void extract4444(int,const void *, GLfloat []);
  193. static void shove4444(const GLfloat [],int ,void *);
  194. static void extract4444rev(int,const void *, GLfloat []);
  195. static void shove4444rev(const GLfloat [],int ,void *);
  196. static void extract5551(int,const void *, GLfloat []);
  197. static void shove5551(const GLfloat [],int ,void *);
  198. static void extract1555rev(int,const void *, GLfloat []);
  199. static void shove1555rev(const GLfloat [],int ,void *);
  200. static void extract8888(int,const void *, GLfloat []);
  201. static void shove8888(const GLfloat [],int ,void *);
  202. static void extract8888rev(int,const void *, GLfloat []);
  203. static void shove8888rev(const GLfloat [],int ,void *);
  204. static void extract1010102(int,const void *, GLfloat []);
  205. static void shove1010102(const GLfloat [],int ,void *);
  206. static void extract2101010rev(int,const void *, GLfloat []);
  207. static void shove2101010rev(const GLfloat [],int ,void *);
  208. static void scaleInternalPackedPixel(int,
  209.                                      void (*)(int, const void *,GLfloat []),
  210.                                      void (*)(const GLfloat [],int, void *),
  211.                                      GLint,GLint, const void *,
  212.                                      GLint,GLint,void *,GLint,GLint,GLint);
  213. static void halveImagePackedPixel(int,
  214.                                   void (*)(int, const void *,GLfloat []),
  215.                                   void (*)(const GLfloat [],int, void *),
  216.                                   GLint, GLint, const void *,
  217.                                   void *, GLint, GLint, GLint);
  218. static void halve1DimagePackedPixel(int,
  219.                                     void (*)(int, const void *,GLfloat []),
  220.                                     void (*)(const GLfloat [],int, void *),
  221.                                     GLint, GLint, const void *,
  222.                                     void *, GLint, GLint, GLint);
  223.  
  224. static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
  225.                                GLubyte *, GLint, GLint, GLint);
  226. static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
  227.                               GLint, GLint, GLint);
  228. static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
  229.                                 GLushort *, GLint, GLint, GLint, GLint);
  230. static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
  231.                                GLint, GLint, GLint, GLint);
  232. static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
  233.                               GLint, GLint, GLint, GLint);
  234. static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
  235.                              GLint, GLint, GLint, GLint);
  236. static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
  237.                                GLint, GLint, GLint, GLint);
  238.  
  239. static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum);
  240. static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
  241.                         GLenum, GLboolean, const void *, GLushort *);
  242. static void emptyImage3D(const PixelStorageModes *,
  243.                          GLint, GLint, GLint, GLenum,
  244.                          GLenum, GLboolean,
  245.                          const GLushort *, void *);
  246. static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
  247.                             GLint, GLint, GLint, GLushort *);
  248.  
  249. static void retrieveStoreModes(PixelStorageModes *psm)
  250. {
  251.     glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
  252.     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
  253.     glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
  254.     glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
  255.     glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
  256.     glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
  257.  
  258.     glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
  259.     glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
  260.     glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
  261.     glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
  262.     glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
  263.     glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
  264. }
  265.  
  266. static void retrieveStoreModes3D(PixelStorageModes *psm)
  267. {
  268.     glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
  269.     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
  270.     glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
  271.     glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
  272.     glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
  273.     glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
  274.     glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images);
  275.     glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height);
  276.  
  277.     glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
  278.     glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
  279.     glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
  280.     glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
  281.     glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
  282.     glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
  283.     glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
  284.     glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
  285. }
  286.  
  287. static int computeLog(GLuint value)
  288. {
  289.     int i;
  290.  
  291.     i = 0;
  292.  
  293.     /* Error! */
  294.     if (value == 0) return -1;
  295.  
  296.     for (;;) {
  297.         if (value & 1) {
  298.             /* Error ! */
  299.             if (value != 1) return -1;
  300.             return i;
  301.         }
  302.         value = value >> 1;
  303.         i++;
  304.     }
  305. }
  306.  
  307. /*
  308. ** Compute the nearest power of 2 number.  This algorithm is a little
  309. ** strange, but it works quite well.
  310. */
  311. static int nearestPower(GLuint value)
  312. {
  313.     int i;
  314.  
  315.     i = 1;
  316.  
  317.     /* Error! */
  318.     if (value == 0) return -1;
  319.  
  320.     for (;;) {
  321.         if (value == 1) {
  322.             return i;
  323.         } else if (value == 3) {
  324.             return i*4;
  325.         }
  326.         value = value >> 1;
  327.         i *= 2;
  328.     }
  329. }
  330.  
  331. #define __GLU_SWAP_2_BYTES(s)\
  332. (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
  333.  
  334. #define __GLU_SWAP_4_BYTES(s)\
  335. (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
  336.         ((GLuint)((const GLubyte*)(s))[2])<<16 | \
  337.         ((GLuint)((const GLubyte*)(s))[1])<<8  | ((const GLubyte*)(s))[0])
  338.  
  339. static void halveImage(GLint components, GLuint width, GLuint height,
  340.                        const GLushort *datain, GLushort *dataout)
  341. {
  342.     int i, j, k;
  343.     int newwidth, newheight;
  344.     int delta;
  345.     GLushort *s;
  346.     const GLushort *t;
  347.  
  348.     newwidth = width / 2;
  349.     newheight = height / 2;
  350.     delta = width * components;
  351.     s = dataout;
  352.     t = datain;
  353.  
  354.     /* Piece o' cake! */
  355.     for (i = 0; i < newheight; i++) {
  356.         for (j = 0; j < newwidth; j++) {
  357.             for (k = 0; k < components; k++) {
  358.                 s[0] = (t[0] + t[components] + t[delta] +
  359.                         t[delta+components] + 2) / 4;
  360.                 s++; t++;
  361.             }
  362.             t += components;
  363.         }
  364.         t += delta;
  365.     }
  366. }
  367.  
  368. static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
  369.                         const GLubyte *datain, GLubyte *dataout,
  370.                         GLint element_size, GLint ysize, GLint group_size)
  371. {
  372.     int i, j, k;
  373.     int newwidth, newheight;
  374.     int padBytes;
  375.     GLubyte *s;
  376.     const char *t;
  377.  
  378.     /* handle case where there is only 1 column/row */
  379.     if (width == 1 || height == 1) {
  380.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  381.        halve1Dimage_ubyte(components,width,height,datain,dataout,
  382.                           element_size,ysize,group_size);
  383.        return;
  384.     }
  385.  
  386.     newwidth = width / 2;
  387.     newheight = height / 2;
  388.     padBytes = ysize - (width*group_size);
  389.     s = dataout;
  390.     t = (const char *)datain;
  391.  
  392.     /* Piece o' cake! */
  393.     for (i = 0; i < newheight; i++) {
  394.         for (j = 0; j < newwidth; j++) {
  395.             for (k = 0; k < components; k++) {
  396.                 s[0] = (*(const GLubyte*)t +
  397.                         *(const GLubyte*)(t+group_size) +
  398.                         *(const GLubyte*)(t+ysize) +
  399.                         *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
  400.                 s++; t += element_size;
  401.             }
  402.             t += group_size;
  403.         }
  404.         t += padBytes;
  405.         t += ysize;
  406.     }
  407. }
  408.  
  409. /* */
  410. static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
  411.                                const GLubyte *dataIn, GLubyte *dataOut,
  412.                                GLint element_size, GLint ysize,
  413.                                GLint group_size)
  414. {
  415.    GLint halfWidth= width / 2;
  416.    GLint halfHeight= height / 2;
  417.    const char *src= (const char *) dataIn;
  418.    GLubyte *dest= dataOut;
  419.    int jj;
  420.  
  421.    assert(width == 1 || height == 1); /* must be 1D */
  422.    assert(width != height);     /* can't be square */
  423.  
  424.    if (height == 1) {           /* 1 row */
  425.       assert(width != 1);       /* widthxheight can't be 1x1 */
  426.       halfHeight= 1;
  427.  
  428.       for (jj= 0; jj< halfWidth; jj++) {
  429.          int kk;
  430.          for (kk= 0; kk< components; kk++) {
  431.             *dest= (*(const GLubyte*)src +
  432.                  *(const GLubyte*)(src+group_size)) / 2;
  433.  
  434.             src+= element_size;
  435.             dest++;
  436.          }
  437.          src+= group_size;      /* skip to next 2 */
  438.       }
  439.       {
  440.          int padBytes= ysize - (width*group_size);
  441.          src+= padBytes;        /* for assertion only */
  442.       }
  443.    }
  444.    else if (width == 1) {       /* 1 column */
  445.       int padBytes= ysize - (width * group_size);
  446.       assert(height != 1);      /* widthxheight can't be 1x1 */
  447.       halfWidth= 1;
  448.       /* one vertical column with possible pad bytes per row */
  449.       /* average two at a time */
  450.  
  451.       for (jj= 0; jj< halfHeight; jj++) {
  452.          int kk;
  453.          for (kk= 0; kk< components; kk++) {
  454.             *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
  455.  
  456.             src+= element_size;
  457.             dest++;
  458.          }
  459.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  460.          src+= ysize;
  461.       }
  462.    }
  463.  
  464.    assert(src == &((const char *)dataIn)[ysize*height]);
  465.    assert((char *)dest == &((char *)dataOut)
  466.           [components * element_size * halfWidth * halfHeight]);
  467. } /* halve1Dimage_ubyte() */
  468.  
  469. static void halveImage_byte(GLint components, GLuint width, GLuint height,
  470.                         const GLbyte *datain, GLbyte *dataout,
  471.                         GLint element_size,
  472.                         GLint ysize, GLint group_size)
  473. {
  474.     int i, j, k;
  475.     int newwidth, newheight;
  476.     int padBytes;
  477.     GLbyte *s;
  478.     const char *t;
  479.  
  480.     /* handle case where there is only 1 column/row */
  481.     if (width == 1 || height == 1) {
  482.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  483.        halve1Dimage_byte(components,width,height,datain,dataout,
  484.                          element_size,ysize,group_size);
  485.        return;
  486.     }
  487.  
  488.     newwidth = width / 2;
  489.     newheight = height / 2;
  490.     padBytes = ysize - (width*group_size);
  491.     s = dataout;
  492.     t = (const char *)datain;
  493.  
  494.     /* Piece o' cake! */
  495.     for (i = 0; i < newheight; i++) {
  496.         for (j = 0; j < newwidth; j++) {
  497.             for (k = 0; k < components; k++) {
  498.                 s[0] = (*(const GLbyte*)t +
  499.                         *(const GLbyte*)(t+group_size) +
  500.                         *(const GLbyte*)(t+ysize) +
  501.                         *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
  502.                 s++; t += element_size;
  503.             }
  504.             t += group_size;
  505.         }
  506.         t += padBytes;
  507.         t += ysize;
  508.     }
  509. }
  510.  
  511. static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
  512.                               const GLbyte *dataIn, GLbyte *dataOut,
  513.                               GLint element_size,GLint ysize, GLint group_size)
  514. {
  515.    GLint halfWidth= width / 2;
  516.    GLint halfHeight= height / 2;
  517.    const char *src= (const char *) dataIn;
  518.    GLbyte *dest= dataOut;
  519.    int jj;
  520.  
  521.    assert(width == 1 || height == 1); /* must be 1D */
  522.    assert(width != height);     /* can't be square */
  523.  
  524.    if (height == 1) {           /* 1 row */
  525.       assert(width != 1);       /* widthxheight can't be 1x1 */
  526.       halfHeight= 1;
  527.  
  528.       for (jj= 0; jj< halfWidth; jj++) {
  529.          int kk;
  530.          for (kk= 0; kk< components; kk++) {
  531.             *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
  532.  
  533.             src+= element_size;
  534.             dest++;
  535.          }
  536.          src+= group_size;      /* skip to next 2 */
  537.       }
  538.       {
  539.          int padBytes= ysize - (width*group_size);
  540.          src+= padBytes;        /* for assertion only */
  541.       }
  542.    }
  543.    else if (width == 1) {       /* 1 column */
  544.       int padBytes= ysize - (width * group_size);
  545.       assert(height != 1);      /* widthxheight can't be 1x1 */
  546.       halfWidth= 1;
  547.       /* one vertical column with possible pad bytes per row */
  548.       /* average two at a time */
  549.  
  550.       for (jj= 0; jj< halfHeight; jj++) {
  551.          int kk;
  552.          for (kk= 0; kk< components; kk++) {
  553.             *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
  554.  
  555.             src+= element_size;
  556.             dest++;
  557.          }
  558.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  559.          src+= ysize;
  560.       }
  561.  
  562.       assert(src == &((const char *)dataIn)[ysize*height]);
  563.    }
  564.  
  565.    assert((char *)dest == &((char *)dataOut)
  566.           [components * element_size * halfWidth * halfHeight]);
  567. } /* halve1Dimage_byte() */
  568.  
  569. static void halveImage_ushort(GLint components, GLuint width, GLuint height,
  570.                         const GLushort *datain, GLushort *dataout,
  571.                         GLint element_size, GLint ysize, GLint group_size,
  572.                         GLint myswap_bytes)
  573. {
  574.     int i, j, k;
  575.     int newwidth, newheight;
  576.     int padBytes;
  577.     GLushort *s;
  578.     const char *t;
  579.  
  580.     /* handle case where there is only 1 column/row */
  581.     if (width == 1 || height == 1) {
  582.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  583.        halve1Dimage_ushort(components,width,height,datain,dataout,
  584.                            element_size,ysize,group_size, myswap_bytes);
  585.        return;
  586.     }
  587.  
  588.     newwidth = width / 2;
  589.     newheight = height / 2;
  590.     padBytes = ysize - (width*group_size);
  591.     s = dataout;
  592.     t = (const char *)datain;
  593.  
  594.     /* Piece o' cake! */
  595.     if (!myswap_bytes)
  596.     for (i = 0; i < newheight; i++) {
  597.         for (j = 0; j < newwidth; j++) {
  598.             for (k = 0; k < components; k++) {
  599.                 s[0] = (*(const GLushort*)t +
  600.                         *(const GLushort*)(t+group_size) +
  601.                         *(const GLushort*)(t+ysize) +
  602.                         *(const GLushort*)(t+ysize+group_size) + 2) / 4;
  603.                 s++; t += element_size;
  604.             }
  605.             t += group_size;
  606.         }
  607.         t += padBytes;
  608.         t += ysize;
  609.     }
  610.     else
  611.     for (i = 0; i < newheight; i++) {
  612.         for (j = 0; j < newwidth; j++) {
  613.             for (k = 0; k < components; k++) {
  614.                 s[0] = (__GLU_SWAP_2_BYTES(t) +
  615.                         __GLU_SWAP_2_BYTES(t+group_size) +
  616.                         __GLU_SWAP_2_BYTES(t+ysize) +
  617.                         __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
  618.                 s++; t += element_size;
  619.             }
  620.             t += group_size;
  621.         }
  622.         t += padBytes;
  623.         t += ysize;
  624.     }
  625. }
  626.  
  627. static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
  628.                                 const GLushort *dataIn, GLushort *dataOut,
  629.                                 GLint element_size, GLint ysize,
  630.                                 GLint group_size, GLint myswap_bytes)
  631. {
  632.    GLint halfWidth= width / 2;
  633.    GLint halfHeight= height / 2;
  634.    const char *src= (const char *) dataIn;
  635.    GLushort *dest= dataOut;
  636.    int jj;
  637.  
  638.    assert(width == 1 || height == 1); /* must be 1D */
  639.    assert(width != height);     /* can't be square */
  640.  
  641.    if (height == 1) {           /* 1 row */
  642.       assert(width != 1);       /* widthxheight can't be 1x1 */
  643.       halfHeight= 1;
  644.  
  645.       for (jj= 0; jj< halfWidth; jj++) {
  646.          int kk;
  647.          for (kk= 0; kk< components; kk++) {
  648. #define BOX2 2
  649.             GLushort ushort[BOX2];
  650.             if (myswap_bytes) {
  651.                ushort[0]= __GLU_SWAP_2_BYTES(src);
  652.                ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
  653.             }
  654.             else {
  655.                ushort[0]= *(const GLushort*)src;
  656.                ushort[1]= *(const GLushort*)(src+group_size);
  657.             }
  658.  
  659.             *dest= (ushort[0] + ushort[1]) / 2;
  660.             src+= element_size;
  661.             dest++;
  662.          }
  663.          src+= group_size;      /* skip to next 2 */
  664.       }
  665.       {
  666.          int padBytes= ysize - (width*group_size);
  667.          src+= padBytes;        /* for assertion only */
  668.       }
  669.    }
  670.    else if (width == 1) {       /* 1 column */
  671.       int padBytes= ysize - (width * group_size);
  672.       assert(height != 1);      /* widthxheight can't be 1x1 */
  673.       halfWidth= 1;
  674.       /* one vertical column with possible pad bytes per row */
  675.       /* average two at a time */
  676.  
  677.       for (jj= 0; jj< halfHeight; jj++) {
  678.          int kk;
  679.          for (kk= 0; kk< components; kk++) {
  680. #define BOX2 2
  681.             GLushort ushort[BOX2];
  682.             if (myswap_bytes) {
  683.                ushort[0]= __GLU_SWAP_2_BYTES(src);
  684.                ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
  685.             }
  686.             else {
  687.                ushort[0]= *(const GLushort*)src;
  688.                ushort[1]= *(const GLushort*)(src+ysize);
  689.             }
  690.             *dest= (ushort[0] + ushort[1]) / 2;
  691.  
  692.             src+= element_size;
  693.             dest++;
  694.          }
  695.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  696.          src+= ysize;
  697.       }
  698.  
  699.       assert(src == &((const char *)dataIn)[ysize*height]);
  700.    }
  701.  
  702.    assert((char *)dest == &((char *)dataOut)
  703.           [components * element_size * halfWidth * halfHeight]);
  704.  
  705. } /* halve1Dimage_ushort() */
  706.  
  707.  
  708. static void halveImage_short(GLint components, GLuint width, GLuint height,
  709.                         const GLshort *datain, GLshort *dataout,
  710.                         GLint element_size, GLint ysize, GLint group_size,
  711.                         GLint myswap_bytes)
  712. {
  713.     int i, j, k;
  714.     int newwidth, newheight;
  715.     int padBytes;
  716.     GLshort *s;
  717.     const char *t;
  718.  
  719.     /* handle case where there is only 1 column/row */
  720.     if (width == 1 || height == 1) {
  721.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  722.        halve1Dimage_short(components,width,height,datain,dataout,
  723.                           element_size,ysize,group_size, myswap_bytes);
  724.        return;
  725.     }
  726.  
  727.     newwidth = width / 2;
  728.     newheight = height / 2;
  729.     padBytes = ysize - (width*group_size);
  730.     s = dataout;
  731.     t = (const char *)datain;
  732.  
  733.     /* Piece o' cake! */
  734.     if (!myswap_bytes)
  735.     for (i = 0; i < newheight; i++) {
  736.         for (j = 0; j < newwidth; j++) {
  737.             for (k = 0; k < components; k++) {
  738.                 s[0] = (*(const GLshort*)t +
  739.                         *(const GLshort*)(t+group_size) +
  740.                         *(const GLshort*)(t+ysize) +
  741.                         *(const GLshort*)(t+ysize+group_size) + 2) / 4;
  742.                 s++; t += element_size;
  743.             }
  744.             t += group_size;
  745.         }
  746.         t += padBytes;
  747.         t += ysize;
  748.     }
  749.     else
  750.     for (i = 0; i < newheight; i++) {
  751.         for (j = 0; j < newwidth; j++) {
  752.             for (k = 0; k < components; k++) {
  753.                 GLushort b;
  754.                 GLint buf;
  755.                 b = __GLU_SWAP_2_BYTES(t);
  756.                 buf = *(const GLshort*)&b;
  757.                 b = __GLU_SWAP_2_BYTES(t+group_size);
  758.                 buf += *(const GLshort*)&b;
  759.                 b = __GLU_SWAP_2_BYTES(t+ysize);
  760.                 buf += *(const GLshort*)&b;
  761.                 b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
  762.                 buf += *(const GLshort*)&b;
  763.                 s[0] = (GLshort)((buf+2)/4);
  764.                 s++; t += element_size;
  765.             }
  766.             t += group_size;
  767.         }
  768.         t += padBytes;
  769.         t += ysize;
  770.     }
  771. }
  772.  
  773. static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
  774.                                 const GLshort *dataIn, GLshort *dataOut,
  775.                                 GLint element_size, GLint ysize,
  776.                                 GLint group_size, GLint myswap_bytes)
  777. {
  778.    GLint halfWidth= width / 2;
  779.    GLint halfHeight= height / 2;
  780.    const char *src= (const char *) dataIn;
  781.    GLshort *dest= dataOut;
  782.    int jj;
  783.  
  784.    assert(width == 1 || height == 1); /* must be 1D */
  785.    assert(width != height);     /* can't be square */
  786.  
  787.    if (height == 1) {           /* 1 row */
  788.       assert(width != 1);       /* widthxheight can't be 1x1 */
  789.       halfHeight= 1;
  790.  
  791.       for (jj= 0; jj< halfWidth; jj++) {
  792.          int kk;
  793.          for (kk= 0; kk< components; kk++) {
  794. #define BOX2 2
  795.             GLshort sshort[BOX2];
  796.             if (myswap_bytes) {
  797.                sshort[0]= __GLU_SWAP_2_BYTES(src);
  798.                sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
  799.             }
  800.             else {
  801.                sshort[0]= *(const GLshort*)src;
  802.                sshort[1]= *(const GLshort*)(src+group_size);
  803.             }
  804.  
  805.             *dest= (sshort[0] + sshort[1]) / 2;
  806.             src+= element_size;
  807.             dest++;
  808.          }
  809.          src+= group_size;      /* skip to next 2 */
  810.       }
  811.       {
  812.          int padBytes= ysize - (width*group_size);
  813.          src+= padBytes;        /* for assertion only */
  814.       }
  815.    }
  816.    else if (width == 1) {       /* 1 column */
  817.       int padBytes= ysize - (width * group_size);
  818.       assert(height != 1);      /* widthxheight can't be 1x1 */
  819.       halfWidth= 1;
  820.       /* one vertical column with possible pad bytes per row */
  821.       /* average two at a time */
  822.  
  823.       for (jj= 0; jj< halfHeight; jj++) {
  824.          int kk;
  825.          for (kk= 0; kk< components; kk++) {
  826. #define BOX2 2
  827.             GLshort sshort[BOX2];
  828.             if (myswap_bytes) {
  829.                sshort[0]= __GLU_SWAP_2_BYTES(src);
  830.                sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
  831.             }
  832.             else {
  833.                sshort[0]= *(const GLshort*)src;
  834.                sshort[1]= *(const GLshort*)(src+ysize);
  835.             }
  836.             *dest= (sshort[0] + sshort[1]) / 2;
  837.  
  838.             src+= element_size;
  839.             dest++;
  840.          }
  841.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  842.          src+= ysize;
  843.       }
  844.  
  845.       assert(src == &((const char *)dataIn)[ysize*height]);
  846.    }
  847.  
  848.    assert((char *)dest == &((char *)dataOut)
  849.           [components * element_size * halfWidth * halfHeight]);
  850.  
  851. } /* halve1Dimage_short() */
  852.  
  853.  
  854. static void halveImage_uint(GLint components, GLuint width, GLuint height,
  855.                         const GLuint *datain, GLuint *dataout,
  856.                         GLint element_size, GLint ysize, GLint group_size,
  857.                         GLint myswap_bytes)
  858. {
  859.     int i, j, k;
  860.     int newwidth, newheight;
  861.     int padBytes;
  862.     GLuint *s;
  863.     const char *t;
  864.  
  865.     /* handle case where there is only 1 column/row */
  866.     if (width == 1 || height == 1) {
  867.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  868.        halve1Dimage_uint(components,width,height,datain,dataout,
  869.                          element_size,ysize,group_size, myswap_bytes);
  870.        return;
  871.     }
  872.  
  873.     newwidth = width / 2;
  874.     newheight = height / 2;
  875.     padBytes = ysize - (width*group_size);
  876.     s = dataout;
  877.     t = (const char *)datain;
  878.  
  879.     /* Piece o' cake! */
  880.     if (!myswap_bytes)
  881.     for (i = 0; i < newheight; i++) {
  882.         for (j = 0; j < newwidth; j++) {
  883.             for (k = 0; k < components; k++) {
  884.                 /* need to cast to double to hold large unsigned ints */
  885.                 s[0] = ((double)*(const GLuint*)t +
  886.                         (double)*(const GLuint*)(t+group_size) +
  887.                         (double)*(const GLuint*)(t+ysize) +
  888.                         (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
  889.                 s++; t += element_size;
  890.  
  891.             }
  892.             t += group_size;
  893.         }
  894.         t += padBytes;
  895.         t += ysize;
  896.     }
  897.     else
  898.     for (i = 0; i < newheight; i++) {
  899.         for (j = 0; j < newwidth; j++) {
  900.             for (k = 0; k < components; k++) {
  901.                 /* need to cast to double to hold large unsigned ints */
  902.                 GLdouble buf;
  903.                 buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
  904.                       (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
  905.                       (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
  906.                       (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
  907.                 s[0] = (GLuint)(buf/4 + 0.5);
  908.  
  909.                 s++; t += element_size;
  910.             }
  911.             t += group_size;
  912.         }
  913.         t += padBytes;
  914.         t += ysize;
  915.     }
  916. }
  917.  
  918. /* */
  919. static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
  920.                               const GLuint *dataIn, GLuint *dataOut,
  921.                               GLint element_size, GLint ysize,
  922.                               GLint group_size, GLint myswap_bytes)
  923. {
  924.    GLint halfWidth= width / 2;
  925.    GLint halfHeight= height / 2;
  926.    const char *src= (const char *) dataIn;
  927.    GLuint *dest= dataOut;
  928.    int jj;
  929.  
  930.    assert(width == 1 || height == 1); /* must be 1D */
  931.    assert(width != height);     /* can't be square */
  932.  
  933.    if (height == 1) {           /* 1 row */
  934.       assert(width != 1);       /* widthxheight can't be 1x1 */
  935.       halfHeight= 1;
  936.  
  937.       for (jj= 0; jj< halfWidth; jj++) {
  938.          int kk;
  939.          for (kk= 0; kk< components; kk++) {
  940. #define BOX2 2
  941.             GLuint uint[BOX2];
  942.             if (myswap_bytes) {
  943.                uint[0]= __GLU_SWAP_4_BYTES(src);
  944.                uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
  945.             }
  946.             else {
  947.                uint[0]= *(const GLuint*)src;
  948.                uint[1]= *(const GLuint*)(src+group_size);
  949.             }
  950.             *dest= ((double)uint[0]+(double)uint[1])/2.0;
  951.  
  952.             src+= element_size;
  953.             dest++;
  954.          }
  955.          src+= group_size;      /* skip to next 2 */
  956.       }
  957.       {
  958.          int padBytes= ysize - (width*group_size);
  959.          src+= padBytes;        /* for assertion only */
  960.       }
  961.    }
  962.    else if (width == 1) {       /* 1 column */
  963.       int padBytes= ysize - (width * group_size);
  964.       assert(height != 1);      /* widthxheight can't be 1x1 */
  965.       halfWidth= 1;
  966.       /* one vertical column with possible pad bytes per row */
  967.       /* average two at a time */
  968.  
  969.       for (jj= 0; jj< halfHeight; jj++) {
  970.          int kk;
  971.          for (kk= 0; kk< components; kk++) {
  972. #define BOX2 2
  973.             GLuint uint[BOX2];
  974.             if (myswap_bytes) {
  975.                uint[0]= __GLU_SWAP_4_BYTES(src);
  976.                uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
  977.             }
  978.             else {
  979.                uint[0]= *(const GLuint*)src;
  980.                uint[1]= *(const GLuint*)(src+ysize);
  981.             }
  982.             *dest= ((double)uint[0]+(double)uint[1])/2.0;
  983.  
  984.             src+= element_size;
  985.             dest++;
  986.          }
  987.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  988.          src+= ysize;
  989.       }
  990.  
  991.       assert(src == &((const char *)dataIn)[ysize*height]);
  992.    }
  993.  
  994.    assert((char *)dest == &((char *)dataOut)
  995.           [components * element_size * halfWidth * halfHeight]);
  996.  
  997. } /* halve1Dimage_uint() */
  998.  
  999. static void halveImage_int(GLint components, GLuint width, GLuint height,
  1000.                         const GLint *datain, GLint *dataout, GLint element_size,
  1001.                         GLint ysize, GLint group_size, GLint myswap_bytes)
  1002. {
  1003.     int i, j, k;
  1004.     int newwidth, newheight;
  1005.     int padBytes;
  1006.     GLint *s;
  1007.     const char *t;
  1008.  
  1009.     /* handle case where there is only 1 column/row */
  1010.     if (width == 1 || height == 1) {
  1011.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  1012.        halve1Dimage_int(components,width,height,datain,dataout,
  1013.                         element_size,ysize,group_size, myswap_bytes);
  1014.        return;
  1015.     }
  1016.  
  1017.     newwidth = width / 2;
  1018.     newheight = height / 2;
  1019.     padBytes = ysize - (width*group_size);
  1020.     s = dataout;
  1021.     t = (const char *)datain;
  1022.  
  1023.     /* Piece o' cake! */
  1024.     if (!myswap_bytes)
  1025.     for (i = 0; i < newheight; i++) {
  1026.         for (j = 0; j < newwidth; j++) {
  1027.             for (k = 0; k < components; k++) {
  1028.                 s[0] = ((float)*(const GLint*)t +
  1029.                         (float)*(const GLint*)(t+group_size) +
  1030.                         (float)*(const GLint*)(t+ysize) +
  1031.                         (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
  1032.                 s++; t += element_size;
  1033.             }
  1034.             t += group_size;
  1035.         }
  1036.         t += padBytes;
  1037.         t += ysize;
  1038.     }
  1039.     else
  1040.     for (i = 0; i < newheight; i++) {
  1041.         for (j = 0; j < newwidth; j++) {
  1042.             for (k = 0; k < components; k++) {
  1043.                 GLuint b;
  1044.                 GLfloat buf;
  1045.                 b = __GLU_SWAP_4_BYTES(t);
  1046.                 buf = *(GLint*)&b;
  1047.                 b = __GLU_SWAP_4_BYTES(t+group_size);
  1048.                 buf += *(GLint*)&b;
  1049.                 b = __GLU_SWAP_4_BYTES(t+ysize);
  1050.                 buf += *(GLint*)&b;
  1051.                 b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
  1052.                 buf += *(GLint*)&b;
  1053.                 s[0] = (GLint)(buf/4 + 0.5);
  1054.  
  1055.                 s++; t += element_size;
  1056.             }
  1057.             t += group_size;
  1058.         }
  1059.         t += padBytes;
  1060.         t += ysize;
  1061.     }
  1062. }
  1063.  
  1064. /* */
  1065. static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
  1066.                              const GLint *dataIn, GLint *dataOut,
  1067.                              GLint element_size, GLint ysize,
  1068.                              GLint group_size, GLint myswap_bytes)
  1069. {
  1070.    GLint halfWidth= width / 2;
  1071.    GLint halfHeight= height / 2;
  1072.    const char *src= (const char *) dataIn;
  1073.    GLint *dest= dataOut;
  1074.    int jj;
  1075.  
  1076.    assert(width == 1 || height == 1); /* must be 1D */
  1077.    assert(width != height);     /* can't be square */
  1078.  
  1079.    if (height == 1) {           /* 1 row */
  1080.       assert(width != 1);       /* widthxheight can't be 1x1 */
  1081.       halfHeight= 1;
  1082.  
  1083.       for (jj= 0; jj< halfWidth; jj++) {
  1084.          int kk;
  1085.          for (kk= 0; kk< components; kk++) {
  1086. #define BOX2 2
  1087.             GLuint uint[BOX2];
  1088.             if (myswap_bytes) {
  1089.                uint[0]= __GLU_SWAP_4_BYTES(src);
  1090.                uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
  1091.             }
  1092.             else {
  1093.                uint[0]= *(const GLuint*)src;
  1094.                uint[1]= *(const GLuint*)(src+group_size);
  1095.             }
  1096.             *dest= ((float)uint[0]+(float)uint[1])/2.0;
  1097.  
  1098.             src+= element_size;
  1099.             dest++;
  1100.          }
  1101.          src+= group_size;      /* skip to next 2 */
  1102.       }
  1103.       {
  1104.          int padBytes= ysize - (width*group_size);
  1105.          src+= padBytes;        /* for assertion only */
  1106.       }
  1107.    }
  1108.    else if (width == 1) {       /* 1 column */
  1109.       int padBytes= ysize - (width * group_size);
  1110.       assert(height != 1);      /* widthxheight can't be 1x1 */
  1111.       halfWidth= 1;
  1112.       /* one vertical column with possible pad bytes per row */
  1113.       /* average two at a time */
  1114.  
  1115.       for (jj= 0; jj< halfHeight; jj++) {
  1116.          int kk;
  1117.          for (kk= 0; kk< components; kk++) {
  1118. #define BOX2 2
  1119.             GLuint uint[BOX2];
  1120.             if (myswap_bytes) {
  1121.                uint[0]= __GLU_SWAP_4_BYTES(src);
  1122.                uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
  1123.             }
  1124.             else {
  1125.                uint[0]= *(const GLuint*)src;
  1126.                uint[1]= *(const GLuint*)(src+ysize);
  1127.             }
  1128.             *dest= ((float)uint[0]+(float)uint[1])/2.0;
  1129.  
  1130.             src+= element_size;
  1131.             dest++;
  1132.          }
  1133.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  1134.          src+= ysize;
  1135.       }
  1136.  
  1137.       assert(src == &((const char *)dataIn)[ysize*height]);
  1138.    }
  1139.  
  1140.    assert((char *)dest == &((char *)dataOut)
  1141.           [components * element_size * halfWidth * halfHeight]);
  1142.  
  1143. } /* halve1Dimage_int() */
  1144.  
  1145.  
  1146. static void halveImage_float(GLint components, GLuint width, GLuint height,
  1147.                         const GLfloat *datain, GLfloat *dataout,
  1148.                         GLint element_size, GLint ysize, GLint group_size,
  1149.                         GLint myswap_bytes)
  1150. {
  1151.     int i, j, k;
  1152.     int newwidth, newheight;
  1153.     int padBytes;
  1154.     GLfloat *s;
  1155.     const char *t;
  1156.  
  1157.     /* handle case where there is only 1 column/row */
  1158.     if (width == 1 || height == 1) {
  1159.        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
  1160.        halve1Dimage_float(components,width,height,datain,dataout,
  1161.                           element_size,ysize,group_size, myswap_bytes);
  1162.        return;
  1163.     }
  1164.  
  1165.     newwidth = width / 2;
  1166.     newheight = height / 2;
  1167.     padBytes = ysize - (width*group_size);
  1168.     s = dataout;
  1169.     t = (const char *)datain;
  1170.  
  1171.     /* Piece o' cake! */
  1172.     if (!myswap_bytes)
  1173.     for (i = 0; i < newheight; i++) {
  1174.         for (j = 0; j < newwidth; j++) {
  1175.             for (k = 0; k < components; k++) {
  1176.                 s[0] = (*(const GLfloat*)t +
  1177.                         *(const GLfloat*)(t+group_size) +
  1178.                         *(const GLfloat*)(t+ysize) +
  1179.                         *(const GLfloat*)(t+ysize+group_size)) / 4;
  1180.                 s++; t += element_size;
  1181.             }
  1182.             t += group_size;
  1183.         }
  1184.         t += padBytes;
  1185.         t += ysize;
  1186.     }
  1187.     else
  1188.     for (i = 0; i < newheight; i++) {
  1189.         for (j = 0; j < newwidth; j++) {
  1190.             for (k = 0; k < components; k++) {
  1191.                 union { GLuint b; GLfloat f; } swapbuf;
  1192.                 swapbuf.b = __GLU_SWAP_4_BYTES(t);
  1193.                 s[0] = swapbuf.f;
  1194.                 swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
  1195.                 s[0] += swapbuf.f;
  1196.                 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
  1197.                 s[0] += swapbuf.f;
  1198.                 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
  1199.                 s[0] += swapbuf.f;
  1200.                 s[0] /= 4;
  1201.                 s++; t += element_size;
  1202.             }
  1203.             t += group_size;
  1204.         }
  1205.         t += padBytes;
  1206.         t += ysize;
  1207.     }
  1208. }
  1209.  
  1210. /* */
  1211. static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
  1212.                                const GLfloat *dataIn, GLfloat *dataOut,
  1213.                                GLint element_size, GLint ysize,
  1214.                                GLint group_size, GLint myswap_bytes)
  1215. {
  1216.    GLint halfWidth= width / 2;
  1217.    GLint halfHeight= height / 2;
  1218.    const char *src= (const char *) dataIn;
  1219.    GLfloat *dest= dataOut;
  1220.    int jj;
  1221.  
  1222.    assert(width == 1 || height == 1); /* must be 1D */
  1223.    assert(width != height);     /* can't be square */
  1224.  
  1225.    if (height == 1) {           /* 1 row */
  1226.       assert(width != 1);       /* widthxheight can't be 1x1 */
  1227.       halfHeight= 1;
  1228.  
  1229.       for (jj= 0; jj< halfWidth; jj++) {
  1230.          int kk;
  1231.          for (kk= 0; kk< components; kk++) {
  1232. #define BOX2 2
  1233.             GLfloat sfloat[BOX2];
  1234.             if (myswap_bytes) {
  1235.                sfloat[0]= __GLU_SWAP_4_BYTES(src);
  1236.                sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
  1237.             }
  1238.             else {
  1239.                sfloat[0]= *(const GLfloat*)src;
  1240.                sfloat[1]= *(const GLfloat*)(src+group_size);
  1241.             }
  1242.  
  1243.             *dest= (sfloat[0] + sfloat[1]) / 2.0;
  1244.             src+= element_size;
  1245.             dest++;
  1246.          }
  1247.          src+= group_size;      /* skip to next 2 */
  1248.       }
  1249.       {
  1250.          int padBytes= ysize - (width*group_size);
  1251.          src+= padBytes;        /* for assertion only */
  1252.       }
  1253.    }
  1254.    else if (width == 1) {       /* 1 column */
  1255.       int padBytes= ysize - (width * group_size);
  1256.       assert(height != 1);      /* widthxheight can't be 1x1 */
  1257.       halfWidth= 1;
  1258.       /* one vertical column with possible pad bytes per row */
  1259.       /* average two at a time */
  1260.  
  1261.       for (jj= 0; jj< halfHeight; jj++) {
  1262.          int kk;
  1263.          for (kk= 0; kk< components; kk++) {
  1264. #define BOX2 2
  1265.             GLfloat sfloat[BOX2];
  1266.             if (myswap_bytes) {
  1267.                sfloat[0]= __GLU_SWAP_4_BYTES(src);
  1268.                sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
  1269.             }
  1270.             else {
  1271.                sfloat[0]= *(const GLfloat*)src;
  1272.                sfloat[1]= *(const GLfloat*)(src+ysize);
  1273.             }
  1274.             *dest= (sfloat[0] + sfloat[1]) / 2.0;
  1275.  
  1276.             src+= element_size;
  1277.             dest++;
  1278.          }
  1279.          src+= padBytes; /* add pad bytes, if any, to get to end to row */
  1280.          src+= ysize;           /* skip to odd row */
  1281.       }
  1282.    }
  1283.  
  1284.    assert(src == &((const char *)dataIn)[ysize*height]);
  1285.    assert((char *)dest == &((char *)dataOut)
  1286.           [components * element_size * halfWidth * halfHeight]);
  1287. } /* halve1Dimage_float() */
  1288.  
  1289. static void scale_internal(GLint components, GLint widthin, GLint heightin,
  1290.                            const GLushort *datain,
  1291.                            GLint widthout, GLint heightout,
  1292.                            GLushort *dataout)
  1293. {
  1294.     float x, lowx, highx, convx, halfconvx;
  1295.     float y, lowy, highy, convy, halfconvy;
  1296.     float xpercent,ypercent;
  1297.     float percent;
  1298.     /* Max components in a format is 4, so... */
  1299.     float totals[4];
  1300.     float area;
  1301.     int i,j,k,yint,xint,xindex,yindex;
  1302.     int temp;
  1303.  
  1304.     if (widthin == widthout*2 && heightin == heightout*2) {
  1305.         halveImage(components, widthin, heightin, datain, dataout);
  1306.         return;
  1307.     }
  1308.     convy = (float) heightin/heightout;
  1309.     convx = (float) widthin/widthout;
  1310.     halfconvx = convx/2;
  1311.     halfconvy = convy/2;
  1312.     for (i = 0; i < heightout; i++) {
  1313.         y = convy * (i+0.5);
  1314.         if (heightin > heightout) {
  1315.             highy = y + halfconvy;
  1316.             lowy = y - halfconvy;
  1317.         } else {
  1318.             highy = y + 0.5;
  1319.             lowy = y - 0.5;
  1320.         }
  1321.         for (j = 0; j < widthout; j++) {
  1322.             x = convx * (j+0.5);
  1323.             if (widthin > widthout) {
  1324.                 highx = x + halfconvx;
  1325.                 lowx = x - halfconvx;
  1326.             } else {
  1327.                 highx = x + 0.5;
  1328.                 lowx = x - 0.5;
  1329.             }
  1330.  
  1331.             /*
  1332.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  1333.             ** to (highx, highy) on input data into this pixel on output
  1334.             ** data.
  1335.             */
  1336.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  1337.             area = 0.0;
  1338.  
  1339.             y = lowy;
  1340.             yint = floor(y);
  1341.             while (y < highy) {
  1342.                 yindex = (yint + heightin) % heightin;
  1343.                 if (highy < yint+1) {
  1344.                     ypercent = highy - y;
  1345.                 } else {
  1346.                     ypercent = yint+1 - y;
  1347.                 }
  1348.  
  1349.                 x = lowx;
  1350.                 xint = floor(x);
  1351.  
  1352.                 while (x < highx) {
  1353.                     xindex = (xint + widthin) % widthin;
  1354.                     if (highx < xint+1) {
  1355.                         xpercent = highx - x;
  1356.                     } else {
  1357.                         xpercent = xint+1 - x;
  1358.                     }
  1359.  
  1360.                     percent = xpercent * ypercent;
  1361.                     area += percent;
  1362.                     temp = (xindex + (yindex * widthin)) * components;
  1363.                     for (k = 0; k < components; k++) {
  1364.                         totals[k] += datain[temp + k] * percent;
  1365.                     }
  1366.  
  1367.                     xint++;
  1368.                     x = xint;
  1369.                 }
  1370.                 yint++;
  1371.                 y = yint;
  1372.             }
  1373.  
  1374.             temp = (j + (i * widthout)) * components;
  1375.             for (k = 0; k < components; k++) {
  1376.                 /* totals[] should be rounded in the case of enlarging an RGB
  1377.                  * ramp when the type is 332 or 4444
  1378.                  */
  1379.                 dataout[temp + k] = (totals[k]+0.5)/area;
  1380.             }
  1381.         }
  1382.     }
  1383. }
  1384.  
  1385. static void scale_internal_ubyte(GLint components, GLint widthin,
  1386.                            GLint heightin, const GLubyte *datain,
  1387.                            GLint widthout, GLint heightout,
  1388.                            GLubyte *dataout, GLint element_size,
  1389.                            GLint ysize, GLint group_size)
  1390. {
  1391.     float convx;
  1392.     float convy;
  1393.     float percent;
  1394.     /* Max components in a format is 4, so... */
  1395.     float totals[4];
  1396.     float area;
  1397.     int i,j,k,xindex;
  1398.  
  1399.     const char *temp, *temp0;
  1400.     const char *temp_index;
  1401.     int outindex;
  1402.  
  1403.     int lowx_int, highx_int, lowy_int, highy_int;
  1404.     float x_percent, y_percent;
  1405.     float lowx_float, highx_float, lowy_float, highy_float;
  1406.     float convy_float, convx_float;
  1407.     int convy_int, convx_int;
  1408.     int l, m;
  1409.     const char *left, *right;
  1410.  
  1411.     if (widthin == widthout*2 && heightin == heightout*2) {
  1412.         halveImage_ubyte(components, widthin, heightin,
  1413.         (const GLubyte *)datain, (GLubyte *)dataout,
  1414.         element_size, ysize, group_size);
  1415.         return;
  1416.     }
  1417.     convy = (float) heightin/heightout;
  1418.     convx = (float) widthin/widthout;
  1419.     convy_int = floor(convy);
  1420.     convy_float = convy - convy_int;
  1421.     convx_int = floor(convx);
  1422.     convx_float = convx - convx_int;
  1423.  
  1424.     area = convx * convy;
  1425.  
  1426.     lowy_int = 0;
  1427.     lowy_float = 0;
  1428.     highy_int = convy_int;
  1429.     highy_float = convy_float;
  1430.  
  1431.     for (i = 0; i < heightout; i++) {
  1432.         /* Clamp here to be sure we don't read beyond input buffer. */
  1433.         if (highy_int >= heightin)
  1434.             highy_int = heightin - 1;
  1435.         lowx_int = 0;
  1436.         lowx_float = 0;
  1437.         highx_int = convx_int;
  1438.         highx_float = convx_float;
  1439.  
  1440.         for (j = 0; j < widthout; j++) {
  1441.  
  1442.             /*
  1443.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  1444.             ** to (highx, highy) on input data into this pixel on output
  1445.             ** data.
  1446.             */
  1447.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  1448.  
  1449.             /* calculate the value for pixels in the 1st row */
  1450.             xindex = lowx_int*group_size;
  1451.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  1452.  
  1453.                 y_percent = 1-lowy_float;
  1454.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  1455.                 percent = y_percent * (1-lowx_float);
  1456.                 for (k = 0, temp_index = temp; k < components;
  1457.                      k++, temp_index += element_size) {
  1458.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1459.                 }
  1460.                 left = temp;
  1461.                 for(l = lowx_int+1; l < highx_int; l++) {
  1462.                     temp += group_size;
  1463.                     for (k = 0, temp_index = temp; k < components;
  1464.                          k++, temp_index += element_size) {
  1465.                         totals[k] += (GLubyte)(*(temp_index)) * y_percent;
  1466.                     }
  1467.                 }
  1468.                 temp += group_size;
  1469.                 right = temp;
  1470.                 percent = y_percent * highx_float;
  1471.                 for (k = 0, temp_index = temp; k < components;
  1472.                      k++, temp_index += element_size) {
  1473.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1474.                 }
  1475.  
  1476.                 /* calculate the value for pixels in the last row */
  1477.                 y_percent = highy_float;
  1478.                 percent = y_percent * (1-lowx_float);
  1479.                 temp = (const char *)datain + xindex + highy_int * ysize;
  1480.                 for (k = 0, temp_index = temp; k < components;
  1481.                      k++, temp_index += element_size) {
  1482.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1483.                 }
  1484.                 for(l = lowx_int+1; l < highx_int; l++) {
  1485.                     temp += group_size;
  1486.                     for (k = 0, temp_index = temp; k < components;
  1487.                          k++, temp_index += element_size) {
  1488.                         totals[k] += (GLubyte)(*(temp_index)) * y_percent;
  1489.                     }
  1490.                 }
  1491.                 temp += group_size;
  1492.                 percent = y_percent * highx_float;
  1493.                 for (k = 0, temp_index = temp; k < components;
  1494.                      k++, temp_index += element_size) {
  1495.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1496.                 }
  1497.  
  1498.  
  1499.                 /* calculate the value for pixels in the 1st and last column */
  1500.                 for(m = lowy_int+1; m < highy_int; m++) {
  1501.                     left += ysize;
  1502.                     right += ysize;
  1503.                     for (k = 0; k < components;
  1504.                          k++, left += element_size, right += element_size) {
  1505.                         totals[k] += (GLubyte)(*(left))*(1-lowx_float)
  1506.                                 +(GLubyte)(*(right))*highx_float;
  1507.                     }
  1508.                 }
  1509.             } else if (highy_int > lowy_int) {
  1510.                 x_percent = highx_float - lowx_float;
  1511.                 percent = (1-lowy_float)*x_percent;
  1512.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  1513.                 for (k = 0, temp_index = temp; k < components;
  1514.                      k++, temp_index += element_size) {
  1515.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1516.                 }
  1517.                 for(m = lowy_int+1; m < highy_int; m++) {
  1518.                     temp += ysize;
  1519.                     for (k = 0, temp_index = temp; k < components;
  1520.                          k++, temp_index += element_size) {
  1521.                         totals[k] += (GLubyte)(*(temp_index)) * x_percent;
  1522.                     }
  1523.                 }
  1524.                 percent = x_percent * highy_float;
  1525.                 temp += ysize;
  1526.                 for (k = 0, temp_index = temp; k < components;
  1527.                      k++, temp_index += element_size) {
  1528.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1529.                 }
  1530.             } else if (highx_int > lowx_int) {
  1531.                 y_percent = highy_float - lowy_float;
  1532.                 percent = (1-lowx_float)*y_percent;
  1533.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  1534.                 for (k = 0, temp_index = temp; k < components;
  1535.                      k++, temp_index += element_size) {
  1536.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1537.                 }
  1538.                 for (l = lowx_int+1; l < highx_int; l++) {
  1539.                     temp += group_size;
  1540.                     for (k = 0, temp_index = temp; k < components;
  1541.                          k++, temp_index += element_size) {
  1542.                         totals[k] += (GLubyte)(*(temp_index)) * y_percent;
  1543.                     }
  1544.                 }
  1545.                 temp += group_size;
  1546.                 percent = y_percent * highx_float;
  1547.                 for (k = 0, temp_index = temp; k < components;
  1548.                      k++, temp_index += element_size) {
  1549.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1550.                 }
  1551.             } else {
  1552.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  1553.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  1554.                 for (k = 0, temp_index = temp; k < components;
  1555.                      k++, temp_index += element_size) {
  1556.                         totals[k] += (GLubyte)(*(temp_index)) * percent;
  1557.                 }
  1558.             }
  1559.  
  1560.  
  1561.  
  1562.             /* this is for the pixels in the body */
  1563.             temp0 = (const char *)datain + xindex + group_size +
  1564.                  (lowy_int+1)*ysize;
  1565.             for (m = lowy_int+1; m < highy_int; m++) {
  1566.                 temp = temp0;
  1567.                 for(l = lowx_int+1; l < highx_int; l++) {
  1568.                     for (k = 0, temp_index = temp; k < components;
  1569.                          k++, temp_index += element_size) {
  1570.                         totals[k] += (GLubyte)(*(temp_index));
  1571.                     }
  1572.                     temp += group_size;
  1573.                 }
  1574.                 temp0 += ysize;
  1575.             }
  1576.  
  1577.             outindex = (j + (i * widthout)) * components;
  1578.             for (k = 0; k < components; k++) {
  1579.                 dataout[outindex + k] = totals[k]/area;
  1580.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  1581.             }
  1582.             lowx_int = highx_int;
  1583.             lowx_float = highx_float;
  1584.             highx_int += convx_int;
  1585.             highx_float += convx_float;
  1586.             if(highx_float > 1) {
  1587.                 highx_float -= 1.0;
  1588.                 highx_int++;
  1589.             }
  1590.         }
  1591.         lowy_int = highy_int;
  1592.         lowy_float = highy_float;
  1593.         highy_int += convy_int;
  1594.         highy_float += convy_float;
  1595.         if(highy_float > 1) {
  1596.             highy_float -= 1.0;
  1597.             highy_int++;
  1598.         }
  1599.     }
  1600. }
  1601.  
  1602. static void scale_internal_byte(GLint components, GLint widthin,
  1603.                            GLint heightin, const GLbyte *datain,
  1604.                            GLint widthout, GLint heightout,
  1605.                            GLbyte *dataout, GLint element_size,
  1606.                            GLint ysize, GLint group_size)
  1607. {
  1608.     float convx;
  1609.     float convy;
  1610.     float percent;
  1611.     /* Max components in a format is 4, so... */
  1612.     float totals[4];
  1613.     float area;
  1614.     int i,j,k,xindex;
  1615.  
  1616.     const char *temp, *temp0;
  1617.     const char *temp_index;
  1618.     int outindex;
  1619.  
  1620.     int lowx_int, highx_int, lowy_int, highy_int;
  1621.     float x_percent, y_percent;
  1622.     float lowx_float, highx_float, lowy_float, highy_float;
  1623.     float convy_float, convx_float;
  1624.     int convy_int, convx_int;
  1625.     int l, m;
  1626.     const char *left, *right;
  1627.  
  1628.     if (widthin == widthout*2 && heightin == heightout*2) {
  1629.         halveImage_byte(components, widthin, heightin,
  1630.         (const GLbyte *)datain, (GLbyte *)dataout,
  1631.         element_size, ysize, group_size);
  1632.         return;
  1633.     }
  1634.     convy = (float) heightin/heightout;
  1635.     convx = (float) widthin/widthout;
  1636.     convy_int = floor(convy);
  1637.     convy_float = convy - convy_int;
  1638.     convx_int = floor(convx);
  1639.     convx_float = convx - convx_int;
  1640.  
  1641.     area = convx * convy;
  1642.  
  1643.     lowy_int = 0;
  1644.     lowy_float = 0;
  1645.     highy_int = convy_int;
  1646.     highy_float = convy_float;
  1647.  
  1648.     for (i = 0; i < heightout; i++) {
  1649.         /* Clamp here to be sure we don't read beyond input buffer. */
  1650.         if (highy_int >= heightin)
  1651.             highy_int = heightin - 1;
  1652.         lowx_int = 0;
  1653.         lowx_float = 0;
  1654.         highx_int = convx_int;
  1655.         highx_float = convx_float;
  1656.  
  1657.         for (j = 0; j < widthout; j++) {
  1658.  
  1659.             /*
  1660.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  1661.             ** to (highx, highy) on input data into this pixel on output
  1662.             ** data.
  1663.             */
  1664.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  1665.  
  1666.             /* calculate the value for pixels in the 1st row */
  1667.             xindex = lowx_int*group_size;
  1668.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  1669.  
  1670.                 y_percent = 1-lowy_float;
  1671.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  1672.                 percent = y_percent * (1-lowx_float);
  1673.                 for (k = 0, temp_index = temp; k < components;
  1674.                      k++, temp_index += element_size) {
  1675.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1676.                 }
  1677.                 left = temp;
  1678.                 for(l = lowx_int+1; l < highx_int; l++) {
  1679.                     temp += group_size;
  1680.                     for (k = 0, temp_index = temp; k < components;
  1681.                      k++, temp_index += element_size) {
  1682.                         totals[k] += (GLbyte)(*(temp_index)) * y_percent;
  1683.                     }
  1684.                 }
  1685.                 temp += group_size;
  1686.                 right = temp;
  1687.                 percent = y_percent * highx_float;
  1688.                 for (k = 0, temp_index = temp; k < components;
  1689.                      k++, temp_index += element_size) {
  1690.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1691.                 }
  1692.  
  1693.                 /* calculate the value for pixels in the last row */           
  1694.                 y_percent = highy_float;
  1695.                 percent = y_percent * (1-lowx_float);
  1696.                 temp = (const char *)datain + xindex + highy_int * ysize;
  1697.                 for (k = 0, temp_index = temp; k < components;
  1698.                      k++, temp_index += element_size) {
  1699.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1700.                 }
  1701.                 for(l = lowx_int+1; l < highx_int; l++) {
  1702.                     temp += group_size;
  1703.                     for (k = 0, temp_index = temp; k < components;
  1704.                          k++, temp_index += element_size) {
  1705.                         totals[k] += (GLbyte)(*(temp_index)) * y_percent;
  1706.                     }
  1707.                 }
  1708.                 temp += group_size;
  1709.                 percent = y_percent * highx_float;
  1710.                 for (k = 0, temp_index = temp; k < components;
  1711.                      k++, temp_index += element_size) {
  1712.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1713.                 }
  1714.  
  1715.  
  1716.                 /* calculate the value for pixels in the 1st and last column */
  1717.                 for(m = lowy_int+1; m < highy_int; m++) {
  1718.                     left += ysize;
  1719.                     right += ysize;
  1720.                     for (k = 0; k < components;
  1721.                          k++, left += element_size, right += element_size) {
  1722.                         totals[k] += (GLbyte)(*(left))*(1-lowx_float)
  1723.                                 +(GLbyte)(*(right))*highx_float;
  1724.                     }
  1725.                 }
  1726.             } else if (highy_int > lowy_int) {
  1727.                 x_percent = highx_float - lowx_float;
  1728.                 percent = (1-lowy_float)*x_percent;
  1729.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  1730.                 for (k = 0, temp_index = temp; k < components;
  1731.                      k++, temp_index += element_size) {
  1732.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1733.                 }
  1734.                 for(m = lowy_int+1; m < highy_int; m++) {
  1735.                     temp += ysize;
  1736.                     for (k = 0, temp_index = temp; k < components;
  1737.                          k++, temp_index += element_size) {
  1738.                         totals[k] += (GLbyte)(*(temp_index)) * x_percent;
  1739.                     }
  1740.                 }
  1741.                 percent = x_percent * highy_float;
  1742.                 temp += ysize;
  1743.                 for (k = 0, temp_index = temp; k < components;
  1744.                      k++, temp_index += element_size) {
  1745.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1746.                 }
  1747.             } else if (highx_int > lowx_int) {
  1748.                 y_percent = highy_float - lowy_float;
  1749.                 percent = (1-lowx_float)*y_percent;
  1750.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  1751.                 for (k = 0, temp_index = temp; k < components;
  1752.                      k++, temp_index += element_size) {
  1753.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1754.                 }
  1755.                 for (l = lowx_int+1; l < highx_int; l++) {
  1756.                     temp += group_size;
  1757.                     for (k = 0, temp_index = temp; k < components;
  1758.                          k++, temp_index += element_size) {
  1759.                         totals[k] += (GLbyte)(*(temp_index)) * y_percent;
  1760.                     }
  1761.                 }
  1762.                 temp += group_size;
  1763.                 percent = y_percent * highx_float;
  1764.                 for (k = 0, temp_index = temp; k < components;
  1765.                      k++, temp_index += element_size) {
  1766.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1767.                 }
  1768.             } else {
  1769.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  1770.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  1771.                 for (k = 0, temp_index = temp; k < components;
  1772.                      k++, temp_index += element_size) {
  1773.                         totals[k] += (GLbyte)(*(temp_index)) * percent;
  1774.                 }
  1775.             }
  1776.  
  1777.  
  1778.  
  1779.             /* this is for the pixels in the body */
  1780.             temp0 = (const char *)datain + xindex + group_size +
  1781.                 (lowy_int+1)*ysize;
  1782.             for (m = lowy_int+1; m < highy_int; m++) {
  1783.                 temp = temp0;
  1784.                 for(l = lowx_int+1; l < highx_int; l++) {
  1785.                     for (k = 0, temp_index = temp; k < components;
  1786.                      k++, temp_index += element_size) {
  1787.                         totals[k] += (GLbyte)(*(temp_index));
  1788.                     }
  1789.                     temp += group_size;
  1790.                 }
  1791.                 temp0 += ysize;
  1792.             }
  1793.  
  1794.             outindex = (j + (i * widthout)) * components;
  1795.             for (k = 0; k < components; k++) {
  1796.                 dataout[outindex + k] = totals[k]/area;
  1797.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  1798.             }
  1799.             lowx_int = highx_int;
  1800.             lowx_float = highx_float;
  1801.             highx_int += convx_int;
  1802.             highx_float += convx_float;
  1803.             if(highx_float > 1) {
  1804.                 highx_float -= 1.0;
  1805.                 highx_int++;
  1806.             }
  1807.         }
  1808.         lowy_int = highy_int;
  1809.         lowy_float = highy_float;
  1810.         highy_int += convy_int;
  1811.         highy_float += convy_float;
  1812.         if(highy_float > 1) {
  1813.             highy_float -= 1.0;
  1814.             highy_int++;
  1815.         }
  1816.     }
  1817. }
  1818.  
  1819. static void scale_internal_ushort(GLint components, GLint widthin,
  1820.                            GLint heightin, const GLushort *datain,
  1821.                            GLint widthout, GLint heightout,
  1822.                            GLushort *dataout, GLint element_size,
  1823.                            GLint ysize, GLint group_size,
  1824.                            GLint myswap_bytes)
  1825. {
  1826.     float convx;
  1827.     float convy;
  1828.     float percent;
  1829.     /* Max components in a format is 4, so... */
  1830.     float totals[4];
  1831.     float area;
  1832.     int i,j,k,xindex;
  1833.  
  1834.     const char *temp, *temp0;
  1835.     const char *temp_index;
  1836.     int outindex;
  1837.  
  1838.     int lowx_int, highx_int, lowy_int, highy_int;
  1839.     float x_percent, y_percent;
  1840.     float lowx_float, highx_float, lowy_float, highy_float;
  1841.     float convy_float, convx_float;
  1842.     int convy_int, convx_int;
  1843.     int l, m;
  1844.     const char *left, *right;
  1845.  
  1846.     if (widthin == widthout*2 && heightin == heightout*2) {
  1847.         halveImage_ushort(components, widthin, heightin,
  1848.         (const GLushort *)datain, (GLushort *)dataout,
  1849.         element_size, ysize, group_size, myswap_bytes);
  1850.         return;
  1851.     }
  1852.     convy = (float) heightin/heightout;
  1853.     convx = (float) widthin/widthout;
  1854.     convy_int = floor(convy);
  1855.     convy_float = convy - convy_int;
  1856.     convx_int = floor(convx);
  1857.     convx_float = convx - convx_int;
  1858.  
  1859.     area = convx * convy;
  1860.  
  1861.     lowy_int = 0;
  1862.     lowy_float = 0;
  1863.     highy_int = convy_int;
  1864.     highy_float = convy_float;
  1865.  
  1866.     for (i = 0; i < heightout; i++) {
  1867.         /* Clamp here to be sure we don't read beyond input buffer. */
  1868.         if (highy_int >= heightin)
  1869.             highy_int = heightin - 1;
  1870.         lowx_int = 0;
  1871.         lowx_float = 0;
  1872.         highx_int = convx_int;
  1873.         highx_float = convx_float;
  1874.  
  1875.         for (j = 0; j < widthout; j++) {
  1876.             /*
  1877.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  1878.             ** to (highx, highy) on input data into this pixel on output
  1879.             ** data.
  1880.             */
  1881.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  1882.  
  1883.             /* calculate the value for pixels in the 1st row */
  1884.             xindex = lowx_int*group_size;
  1885.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  1886.  
  1887.                 y_percent = 1-lowy_float;
  1888.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  1889.                 percent = y_percent * (1-lowx_float);
  1890.                 for (k = 0, temp_index = temp; k < components;
  1891.                      k++, temp_index += element_size) {
  1892.                     if (myswap_bytes) {
  1893.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  1894.                     } else {
  1895.                         totals[k] += *(const GLushort*)temp_index * percent;
  1896.                     }
  1897.                 }
  1898.                 left = temp;
  1899.                 for(l = lowx_int+1; l < highx_int; l++) {
  1900.                     temp += group_size;
  1901.                     for (k = 0, temp_index = temp; k < components;
  1902.                          k++, temp_index += element_size) {
  1903.                         if (myswap_bytes) {
  1904.                             totals[k] +=
  1905.                                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
  1906.                         } else {
  1907.                             totals[k] += *(const GLushort*)temp_index * y_percent;
  1908.                         }
  1909.                     }
  1910.                 }
  1911.                 temp += group_size;
  1912.                 right = temp;
  1913.                 percent = y_percent * highx_float;
  1914.                 for (k = 0, temp_index = temp; k < components;
  1915.                      k++, temp_index += element_size) {
  1916.                     if (myswap_bytes) {
  1917.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  1918.                     } else {
  1919.                         totals[k] += *(const GLushort*)temp_index * percent;
  1920.                     }
  1921.                 }
  1922.  
  1923.                 /* calculate the value for pixels in the last row */           
  1924.                 y_percent = highy_float;
  1925.                 percent = y_percent * (1-lowx_float);
  1926.                 temp = (const char *)datain + xindex + highy_int * ysize;
  1927.                 for (k = 0, temp_index = temp; k < components;
  1928.                      k++, temp_index += element_size) {
  1929.                     if (myswap_bytes) {
  1930.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  1931.                     } else {
  1932.                         totals[k] += *(const GLushort*)temp_index * percent;
  1933.                     }
  1934.                 }
  1935.                 for(l = lowx_int+1; l < highx_int; l++) {
  1936.                     temp += group_size;
  1937.                     for (k = 0, temp_index = temp; k < components;
  1938.                          k++, temp_index += element_size) {
  1939.                         if (myswap_bytes) {
  1940.                             totals[k] +=
  1941.                                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
  1942.                         } else {
  1943.                             totals[k] += *(const GLushort*)temp_index * y_percent;
  1944.                         }
  1945.                     }
  1946.                 }
  1947.                 temp += group_size;
  1948.                 percent = y_percent * highx_float;
  1949.                 for (k = 0, temp_index = temp; k < components;
  1950.                      k++, temp_index += element_size) {
  1951.                     if (myswap_bytes) {
  1952.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  1953.                     } else {
  1954.                         totals[k] += *(const GLushort*)temp_index * percent;
  1955.                     }
  1956.                 }
  1957.  
  1958.                 /* calculate the value for pixels in the 1st and last column */
  1959.                 for(m = lowy_int+1; m < highy_int; m++) {
  1960.                     left += ysize;
  1961.                     right += ysize;
  1962.                     for (k = 0; k < components;
  1963.                          k++, left += element_size, right += element_size) {
  1964.                         if (myswap_bytes) {
  1965.                             totals[k] +=
  1966.                                 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
  1967.                                 __GLU_SWAP_2_BYTES(right) * highx_float;
  1968.                         } else {
  1969.                             totals[k] += *(const GLushort*)left * (1-lowx_float)
  1970.                                        + *(const GLushort*)right * highx_float;
  1971.                         }
  1972.                     }
  1973.                 }
  1974.             } else if (highy_int > lowy_int) {
  1975.                 x_percent = highx_float - lowx_float;
  1976.                 percent = (1-lowy_float)*x_percent;
  1977.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  1978.                 for (k = 0, temp_index = temp; k < components;
  1979.                      k++, temp_index += element_size) {
  1980.                     if (myswap_bytes) {
  1981.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  1982.                     } else {
  1983.                         totals[k] += *(const GLushort*)temp_index * percent;
  1984.                     }
  1985.                 }
  1986.                 for(m = lowy_int+1; m < highy_int; m++) {
  1987.                     temp += ysize;
  1988.                     for (k = 0, temp_index = temp; k < components;
  1989.                          k++, temp_index += element_size) {
  1990.                         if (myswap_bytes) {
  1991.                             totals[k] +=
  1992.                                 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
  1993.                         } else {
  1994.                             totals[k] += *(const GLushort*)temp_index * x_percent;
  1995.                         }
  1996.                     }
  1997.                 }
  1998.                 percent = x_percent * highy_float;
  1999.                 temp += ysize;
  2000.                 for (k = 0, temp_index = temp; k < components;
  2001.                      k++, temp_index += element_size) {
  2002.                     if (myswap_bytes) {
  2003.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  2004.                     } else {
  2005.                         totals[k] += *(const GLushort*)temp_index * percent;
  2006.                     }
  2007.                 }
  2008.             } else if (highx_int > lowx_int) {
  2009.                 y_percent = highy_float - lowy_float;
  2010.                 percent = (1-lowx_float)*y_percent;
  2011.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  2012.                 for (k = 0, temp_index = temp; k < components;
  2013.                      k++, temp_index += element_size) {
  2014.                     if (myswap_bytes) {
  2015.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  2016.                     } else {
  2017.                         totals[k] += *(const GLushort*)temp_index * percent;
  2018.                     }
  2019.                 }
  2020.                 for (l = lowx_int+1; l < highx_int; l++) {
  2021.                     temp += group_size;
  2022.                     for (k = 0, temp_index = temp; k < components;
  2023.                          k++, temp_index += element_size) {
  2024.                         if (myswap_bytes) {
  2025.                             totals[k] +=
  2026.                                 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
  2027.                         } else {
  2028.                             totals[k] += *(const GLushort*)temp_index * y_percent;
  2029.                         }
  2030.                     }
  2031.                 }
  2032.                 temp += group_size;
  2033.                 percent = y_percent * highx_float;
  2034.                 for (k = 0, temp_index = temp; k < components;
  2035.                      k++, temp_index += element_size) {
  2036.                     if (myswap_bytes) {
  2037.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  2038.                     } else {
  2039.                         totals[k] += *(const GLushort*)temp_index * percent;
  2040.                     }
  2041.                 }
  2042.             } else {
  2043.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  2044.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2045.                 for (k = 0, temp_index = temp; k < components;
  2046.                      k++, temp_index += element_size) {
  2047.                     if (myswap_bytes) {
  2048.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  2049.                     } else {
  2050.                         totals[k] += *(const GLushort*)temp_index * percent;
  2051.                     }
  2052.                 }
  2053.             }
  2054.  
  2055.             /* this is for the pixels in the body */
  2056.             temp0 = (const char *)datain + xindex + group_size +
  2057.                  (lowy_int+1)*ysize;
  2058.             for (m = lowy_int+1; m < highy_int; m++) {
  2059.                 temp = temp0;
  2060.                 for(l = lowx_int+1; l < highx_int; l++) {
  2061.                     for (k = 0, temp_index = temp; k < components;
  2062.                          k++, temp_index += element_size) {
  2063.                         if (myswap_bytes) {
  2064.                             totals[k] += __GLU_SWAP_2_BYTES(temp_index);
  2065.                         } else {
  2066.                             totals[k] += *(const GLushort*)temp_index;
  2067.                         }
  2068.                     }
  2069.                     temp += group_size;
  2070.                 }
  2071.                 temp0 += ysize;
  2072.             }
  2073.  
  2074.             outindex = (j + (i * widthout)) * components;
  2075.             for (k = 0; k < components; k++) {
  2076.                 dataout[outindex + k] = totals[k]/area;
  2077.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  2078.             }
  2079.             lowx_int = highx_int;
  2080.             lowx_float = highx_float;
  2081.             highx_int += convx_int;
  2082.             highx_float += convx_float;
  2083.             if(highx_float > 1) {
  2084.                 highx_float -= 1.0;
  2085.                 highx_int++;
  2086.             }
  2087.         }
  2088.         lowy_int = highy_int;
  2089.         lowy_float = highy_float;
  2090.         highy_int += convy_int;
  2091.         highy_float += convy_float;
  2092.         if(highy_float > 1) {
  2093.             highy_float -= 1.0;
  2094.             highy_int++;
  2095.         }
  2096.     }
  2097. }
  2098.  
  2099. static void scale_internal_short(GLint components, GLint widthin,
  2100.                            GLint heightin, const GLshort *datain,
  2101.                            GLint widthout, GLint heightout,
  2102.                            GLshort *dataout, GLint element_size,
  2103.                            GLint ysize, GLint group_size,
  2104.                            GLint myswap_bytes)
  2105. {
  2106.     float convx;
  2107.     float convy;
  2108.     float percent;
  2109.     /* Max components in a format is 4, so... */
  2110.     float totals[4];
  2111.     float area;
  2112.     int i,j,k,xindex;
  2113.  
  2114.     const char *temp, *temp0;
  2115.     const char *temp_index;
  2116.     int outindex;
  2117.  
  2118.     int lowx_int, highx_int, lowy_int, highy_int;
  2119.     float x_percent, y_percent;
  2120.     float lowx_float, highx_float, lowy_float, highy_float;
  2121.     float convy_float, convx_float;
  2122.     int convy_int, convx_int;
  2123.     int l, m;
  2124.     const char *left, *right;
  2125.  
  2126.     GLushort swapbuf;   /* unsigned buffer */
  2127.  
  2128.     if (widthin == widthout*2 && heightin == heightout*2) {
  2129.         halveImage_short(components, widthin, heightin,
  2130.         (const GLshort *)datain, (GLshort *)dataout,
  2131.         element_size, ysize, group_size, myswap_bytes);
  2132.         return;
  2133.     }
  2134.     convy = (float) heightin/heightout;
  2135.     convx = (float) widthin/widthout;
  2136.     convy_int = floor(convy);
  2137.     convy_float = convy - convy_int;
  2138.     convx_int = floor(convx);
  2139.     convx_float = convx - convx_int;
  2140.  
  2141.     area = convx * convy;
  2142.  
  2143.     lowy_int = 0;
  2144.     lowy_float = 0;
  2145.     highy_int = convy_int;
  2146.     highy_float = convy_float;
  2147.  
  2148.     for (i = 0; i < heightout; i++) {
  2149.         /* Clamp here to be sure we don't read beyond input buffer. */
  2150.         if (highy_int >= heightin)
  2151.             highy_int = heightin - 1;
  2152.         lowx_int = 0;
  2153.         lowx_float = 0;
  2154.         highx_int = convx_int;
  2155.         highx_float = convx_float;
  2156.  
  2157.         for (j = 0; j < widthout; j++) {
  2158.             /*
  2159.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  2160.             ** to (highx, highy) on input data into this pixel on output
  2161.             ** data.
  2162.             */
  2163.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  2164.  
  2165.             /* calculate the value for pixels in the 1st row */
  2166.             xindex = lowx_int*group_size;
  2167.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  2168.  
  2169.                 y_percent = 1-lowy_float;
  2170.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2171.                 percent = y_percent * (1-lowx_float);
  2172.                 for (k = 0, temp_index = temp; k < components;
  2173.                      k++, temp_index += element_size) {
  2174.                     if (myswap_bytes) {
  2175.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2176.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2177.                     } else {
  2178.                         totals[k] += *(const GLshort*)temp_index * percent;
  2179.                     }
  2180.                 }
  2181.                 left = temp;
  2182.                 for(l = lowx_int+1; l < highx_int; l++) {
  2183.                     temp += group_size;
  2184.                     for (k = 0, temp_index = temp; k < components;
  2185.                          k++, temp_index += element_size) {
  2186.                         if (myswap_bytes) {
  2187.                             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2188.                             totals[k] += *(const GLshort*)&swapbuf * y_percent;
  2189.                         } else {
  2190.                             totals[k] += *(const GLshort*)temp_index * y_percent;
  2191.                         }
  2192.                     }
  2193.                 }
  2194.                 temp += group_size;
  2195.                 right = temp;
  2196.                 percent = y_percent * highx_float;
  2197.                 for (k = 0, temp_index = temp; k < components;
  2198.                      k++, temp_index += element_size) {
  2199.                     if (myswap_bytes) {
  2200.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2201.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2202.                     } else {
  2203.                         totals[k] += *(const GLshort*)temp_index * percent;
  2204.                     }
  2205.                 }
  2206.  
  2207.                 /* calculate the value for pixels in the last row */
  2208.                 y_percent = highy_float;
  2209.                 percent = y_percent * (1-lowx_float);
  2210.                 temp = (const char *)datain + xindex + highy_int * ysize;
  2211.                 for (k = 0, temp_index = temp; k < components;
  2212.                      k++, temp_index += element_size) {
  2213.                     if (myswap_bytes) {
  2214.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2215.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2216.                     } else {
  2217.                         totals[k] += *(const GLshort*)temp_index * percent;
  2218.                     }
  2219.                 }
  2220.                 for(l = lowx_int+1; l < highx_int; l++) {
  2221.                     temp += group_size;
  2222.                     for (k = 0, temp_index = temp; k < components;
  2223.                          k++, temp_index += element_size) {
  2224.                         if (myswap_bytes) {
  2225.                             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2226.                             totals[k] += *(const GLshort*)&swapbuf * y_percent;
  2227.                         } else {
  2228.                             totals[k] += *(const GLshort*)temp_index * y_percent;
  2229.                         }
  2230.                     }
  2231.                 }
  2232.                 temp += group_size;
  2233.                 percent = y_percent * highx_float;
  2234.                 for (k = 0, temp_index = temp; k < components;
  2235.                      k++, temp_index += element_size) {
  2236.                     if (myswap_bytes) {
  2237.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2238.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2239.                     } else {
  2240.                         totals[k] += *(const GLshort*)temp_index * percent;
  2241.                     }
  2242.                 }
  2243.  
  2244.                 /* calculate the value for pixels in the 1st and last column */
  2245.                 for(m = lowy_int+1; m < highy_int; m++) {
  2246.                     left += ysize;
  2247.                     right += ysize;
  2248.                     for (k = 0; k < components;
  2249.                          k++, left += element_size, right += element_size) {
  2250.                         if (myswap_bytes) {
  2251.                             swapbuf = __GLU_SWAP_2_BYTES(left);
  2252.                             totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
  2253.                             swapbuf = __GLU_SWAP_2_BYTES(right);
  2254.                             totals[k] += *(const GLshort*)&swapbuf * highx_float;
  2255.                         } else {
  2256.                             totals[k] += *(const GLshort*)left * (1-lowx_float)
  2257.                                        + *(const GLshort*)right * highx_float;
  2258.                         }
  2259.                     }
  2260.                 }
  2261.             } else if (highy_int > lowy_int) {
  2262.                 x_percent = highx_float - lowx_float;
  2263.                 percent = (1-lowy_float)*x_percent;
  2264.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  2265.                 for (k = 0, temp_index = temp; k < components;
  2266.                      k++, temp_index += element_size) {
  2267.                     if (myswap_bytes) {
  2268.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2269.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2270.                     } else {
  2271.                         totals[k] += *(const GLshort*)temp_index * percent;
  2272.                     }
  2273.                 }
  2274.                 for(m = lowy_int+1; m < highy_int; m++) {
  2275.                     temp += ysize;
  2276.                     for (k = 0, temp_index = temp; k < components;
  2277.                          k++, temp_index += element_size) {
  2278.                         if (myswap_bytes) {
  2279.                             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2280.                             totals[k] += *(const GLshort*)&swapbuf * x_percent;
  2281.                         } else {
  2282.                             totals[k] += *(const GLshort*)temp_index * x_percent;
  2283.                         }
  2284.                     }
  2285.                 }
  2286.                 percent = x_percent * highy_float;
  2287.                 temp += ysize;
  2288.                 for (k = 0, temp_index = temp; k < components;
  2289.                      k++, temp_index += element_size) {
  2290.                     if (myswap_bytes) {
  2291.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2292.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2293.                     } else {
  2294.                         totals[k] += *(const GLshort*)temp_index * percent;
  2295.                     }
  2296.                 }
  2297.             } else if (highx_int > lowx_int) {
  2298.                 y_percent = highy_float - lowy_float;
  2299.                 percent = (1-lowx_float)*y_percent;
  2300.  
  2301.              temp = (const char *)datain + xindex + lowy_int*ysize;
  2302.                 for (k = 0, temp_index = temp; k < components;
  2303.                      k++, temp_index += element_size) {
  2304.                     if (myswap_bytes) {
  2305.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2306.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2307.                     } else {
  2308.                         totals[k] += *(const GLshort*)temp_index * percent;
  2309.                     }
  2310.                 }
  2311.                 for (l = lowx_int+1; l < highx_int; l++) {
  2312.                     temp += group_size;
  2313.                     for (k = 0, temp_index = temp; k < components;
  2314.                          k++, temp_index += element_size) {
  2315.                         if (myswap_bytes) {
  2316.                             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2317.                             totals[k] += *(const GLshort*)&swapbuf * y_percent;
  2318.                         } else {
  2319.                             totals[k] += *(const GLshort*)temp_index * y_percent;
  2320.                         }
  2321.                     }
  2322.                 }
  2323.                 temp += group_size;
  2324.                 percent = y_percent * highx_float;
  2325.                 for (k = 0, temp_index = temp; k < components;
  2326.                      k++, temp_index += element_size) {
  2327.                     if (myswap_bytes) {
  2328.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2329.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2330.                     } else {
  2331.                         totals[k] += *(const GLshort*)temp_index * percent;
  2332.                     }
  2333.                 }
  2334.             } else {
  2335.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  2336.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2337.                 for (k = 0, temp_index = temp; k < components;
  2338.                      k++, temp_index += element_size) {
  2339.                     if (myswap_bytes) {
  2340.                         swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2341.                         totals[k] += *(const GLshort*)&swapbuf * percent;
  2342.                     } else {
  2343.                         totals[k] += *(const GLshort*)temp_index * percent;
  2344.                     }
  2345.                 }
  2346.             }
  2347.  
  2348.             /* this is for the pixels in the body */
  2349.             temp0 = (const char *)datain + xindex + group_size +
  2350.                  (lowy_int+1)*ysize;
  2351.             for (m = lowy_int+1; m < highy_int; m++) {
  2352.                 temp = temp0;
  2353.                 for(l = lowx_int+1; l < highx_int; l++) {
  2354.                     for (k = 0, temp_index = temp; k < components;
  2355.                          k++, temp_index += element_size) {
  2356.                         if (myswap_bytes) {
  2357.                             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
  2358.                             totals[k] += *(const GLshort*)&swapbuf;
  2359.                         } else {
  2360.                             totals[k] += *(const GLshort*)temp_index;
  2361.                         }
  2362.                     }
  2363.                     temp += group_size;
  2364.                 }
  2365.                 temp0 += ysize;
  2366.             }
  2367.  
  2368.             outindex = (j + (i * widthout)) * components;
  2369.             for (k = 0; k < components; k++) {
  2370.                 dataout[outindex + k] = totals[k]/area;
  2371.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  2372.             }
  2373.             lowx_int = highx_int;
  2374.             lowx_float = highx_float;
  2375.             highx_int += convx_int;
  2376.             highx_float += convx_float;
  2377.             if(highx_float > 1) {
  2378.                 highx_float -= 1.0;
  2379.                 highx_int++;
  2380.             }
  2381.         }
  2382.         lowy_int = highy_int;
  2383.         lowy_float = highy_float;
  2384.         highy_int += convy_int;
  2385.         highy_float += convy_float;
  2386.         if(highy_float > 1) {
  2387.             highy_float -= 1.0;
  2388.             highy_int++;
  2389.         }
  2390.     }
  2391. }
  2392.  
  2393. static void scale_internal_uint(GLint components, GLint widthin,
  2394.                            GLint heightin, const GLuint *datain,
  2395.                            GLint widthout, GLint heightout,
  2396.                            GLuint *dataout, GLint element_size,
  2397.                            GLint ysize, GLint group_size,
  2398.                            GLint myswap_bytes)
  2399. {
  2400.     float convx;
  2401.     float convy;
  2402.     float percent;
  2403.     /* Max components in a format is 4, so... */
  2404.     float totals[4];
  2405.     float area;
  2406.     int i,j,k,xindex;
  2407.  
  2408.     const char *temp, *temp0;
  2409.     const char *temp_index;
  2410.     int outindex;
  2411.  
  2412.     int lowx_int, highx_int, lowy_int, highy_int;
  2413.     float x_percent, y_percent;
  2414.     float lowx_float, highx_float, lowy_float, highy_float;
  2415.     float convy_float, convx_float;
  2416.     int convy_int, convx_int;
  2417.     int l, m;
  2418.     const char *left, *right;
  2419.  
  2420.     if (widthin == widthout*2 && heightin == heightout*2) {
  2421.         halveImage_uint(components, widthin, heightin,
  2422.         (const GLuint *)datain, (GLuint *)dataout,
  2423.         element_size, ysize, group_size, myswap_bytes);
  2424.         return;
  2425.     }
  2426.     convy = (float) heightin/heightout;
  2427.     convx = (float) widthin/widthout;
  2428.     convy_int = floor(convy);
  2429.     convy_float = convy - convy_int;
  2430.     convx_int = floor(convx);
  2431.     convx_float = convx - convx_int;
  2432.  
  2433.     area = convx * convy;
  2434.  
  2435.     lowy_int = 0;
  2436.     lowy_float = 0;
  2437.     highy_int = convy_int;
  2438.     highy_float = convy_float;
  2439.  
  2440.     for (i = 0; i < heightout; i++) {
  2441.         /* Clamp here to be sure we don't read beyond input buffer. */
  2442.         if (highy_int >= heightin)
  2443.             highy_int = heightin - 1;
  2444.         lowx_int = 0;
  2445.         lowx_float = 0;
  2446.         highx_int = convx_int;
  2447.         highx_float = convx_float;
  2448.  
  2449.         for (j = 0; j < widthout; j++) {
  2450.             /*
  2451.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  2452.             ** to (highx, highy) on input data into this pixel on output
  2453.             ** data.
  2454.             */
  2455.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  2456.  
  2457.             /* calculate the value for pixels in the 1st row */
  2458.             xindex = lowx_int*group_size;
  2459.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  2460.  
  2461.                 y_percent = 1-lowy_float;
  2462.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2463.                 percent = y_percent * (1-lowx_float);
  2464.                 for (k = 0, temp_index = temp; k < components;
  2465.                      k++, temp_index += element_size) {
  2466.                     if (myswap_bytes) {
  2467.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2468.                     } else {
  2469.                         totals[k] += *(const GLuint*)temp_index * percent;
  2470.                     }
  2471.                 }
  2472.                 left = temp;
  2473.                 for(l = lowx_int+1; l < highx_int; l++) {
  2474.                     temp += group_size;
  2475.                     for (k = 0, temp_index = temp; k < components;
  2476.                          k++, temp_index += element_size) {
  2477.                         if (myswap_bytes) {
  2478.                             totals[k] +=
  2479.                                  __GLU_SWAP_4_BYTES(temp_index) * y_percent;
  2480.                         } else {
  2481.                             totals[k] += *(const GLuint*)temp_index * y_percent;
  2482.                         }
  2483.                     }
  2484.                 }
  2485.                 temp += group_size;
  2486.                 right = temp;
  2487.                 percent = y_percent * highx_float;
  2488.                 for (k = 0, temp_index = temp; k < components;
  2489.                      k++, temp_index += element_size) {
  2490.                     if (myswap_bytes) {
  2491.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2492.                     } else {
  2493.                         totals[k] += *(const GLuint*)temp_index * percent;
  2494.                     }
  2495.                 }
  2496.  
  2497.                 /* calculate the value for pixels in the last row */
  2498.                 y_percent = highy_float;
  2499.                 percent = y_percent * (1-lowx_float);
  2500.                 temp = (const char *)datain + xindex + highy_int * ysize;
  2501.                 for (k = 0, temp_index = temp; k < components;
  2502.                      k++, temp_index += element_size) {
  2503.                     if (myswap_bytes) {
  2504.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2505.                     } else {
  2506.                         totals[k] += *(const GLuint*)temp_index * percent;
  2507.                     }
  2508.                 }
  2509.                 for(l = lowx_int+1; l < highx_int; l++) {
  2510.                     temp += group_size;
  2511.                     for (k = 0, temp_index = temp; k < components;
  2512.                          k++, temp_index += element_size) {
  2513.                         if (myswap_bytes) {
  2514.                             totals[k] +=
  2515.                                  __GLU_SWAP_4_BYTES(temp_index) * y_percent;
  2516.                         } else {
  2517.                             totals[k] += *(const GLuint*)temp_index * y_percent;
  2518.                         }
  2519.                     }
  2520.                 }
  2521.                 temp += group_size;
  2522.                 percent = y_percent * highx_float;
  2523.                 for (k = 0, temp_index = temp; k < components;
  2524.                      k++, temp_index += element_size) {
  2525.                     if (myswap_bytes) {
  2526.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2527.                     } else {
  2528.                         totals[k] += *(const GLuint*)temp_index * percent;
  2529.                     }
  2530.                 }
  2531.  
  2532.                 /* calculate the value for pixels in the 1st and last column */
  2533.                 for(m = lowy_int+1; m < highy_int; m++) {
  2534.                     left += ysize;
  2535.                     right += ysize;
  2536.                     for (k = 0; k < components;
  2537.                          k++, left += element_size, right += element_size) {
  2538.                         if (myswap_bytes) {
  2539.                             totals[k] +=
  2540.                                 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
  2541.                               + __GLU_SWAP_4_BYTES(right) * highx_float;
  2542.                         } else {
  2543.                             totals[k] += *(const GLuint*)left * (1-lowx_float)
  2544.                                        + *(const GLuint*)right * highx_float;
  2545.                         }
  2546.                     }
  2547.                 }
  2548.             } else if (highy_int > lowy_int) {
  2549.                 x_percent = highx_float - lowx_float;
  2550.                 percent = (1-lowy_float)*x_percent;
  2551.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  2552.                 for (k = 0, temp_index = temp; k < components;
  2553.                      k++, temp_index += element_size) {
  2554.                     if (myswap_bytes) {
  2555.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2556.                     } else {
  2557.                         totals[k] += *(const GLuint*)temp_index * percent;
  2558.                     }
  2559.                 }
  2560.                 for(m = lowy_int+1; m < highy_int; m++) {
  2561.                     temp += ysize;
  2562.                     for (k = 0, temp_index = temp; k < components;
  2563.                          k++, temp_index += element_size) {
  2564.                         if (myswap_bytes) {
  2565.                             totals[k] +=
  2566.                                  __GLU_SWAP_4_BYTES(temp_index) * x_percent;
  2567.                         } else {
  2568.                             totals[k] += *(const GLuint*)temp_index * x_percent;
  2569.                         }
  2570.                     }
  2571.                 }
  2572.                 percent = x_percent * highy_float;
  2573.                 temp += ysize;
  2574.                 for (k = 0, temp_index = temp; k < components;
  2575.                      k++, temp_index += element_size) {
  2576.                     if (myswap_bytes) {
  2577.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2578.                     } else {
  2579.                         totals[k] += *(const GLuint*)temp_index * percent;
  2580.                     }
  2581.                 }
  2582.             } else if (highx_int > lowx_int) {
  2583.                 y_percent = highy_float - lowy_float;
  2584.                 percent = (1-lowx_float)*y_percent;
  2585.  
  2586.              temp = (const char *)datain + xindex + lowy_int*ysize;
  2587.                 for (k = 0, temp_index = temp; k < components;
  2588.                      k++, temp_index += element_size) {
  2589.                     if (myswap_bytes) {
  2590.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2591.                     } else {
  2592.                         totals[k] += *(const GLuint*)temp_index * percent;
  2593.                     }
  2594.                 }
  2595.                 for (l = lowx_int+1; l < highx_int; l++) {
  2596.                     temp += group_size;
  2597.                     for (k = 0, temp_index = temp; k < components;
  2598.                          k++, temp_index += element_size) {
  2599.                         if (myswap_bytes) {
  2600.                             totals[k] +=
  2601.                                  __GLU_SWAP_4_BYTES(temp_index) * y_percent;
  2602.                         } else {
  2603.                             totals[k] += *(const GLuint*)temp_index * y_percent;
  2604.                         }
  2605.                     }
  2606.                 }
  2607.                 temp += group_size;
  2608.                 percent = y_percent * highx_float;
  2609.                 for (k = 0, temp_index = temp; k < components;
  2610.                      k++, temp_index += element_size) {
  2611.                     if (myswap_bytes) {
  2612.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2613.                     } else {
  2614.                         totals[k] += *(const GLuint*)temp_index * percent;
  2615.                     }
  2616.                 }
  2617.             } else {
  2618.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  2619.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2620.                 for (k = 0, temp_index = temp; k < components;
  2621.                      k++, temp_index += element_size) {
  2622.                     if (myswap_bytes) {
  2623.                         totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
  2624.                     } else {
  2625.                         totals[k] += *(const GLuint*)temp_index * percent;
  2626.                     }
  2627.                 }
  2628.             }
  2629.  
  2630.             /* this is for the pixels in the body */
  2631.             temp0 = (const char *)datain + xindex + group_size +
  2632.                  (lowy_int+1)*ysize;
  2633.             for (m = lowy_int+1; m < highy_int; m++) {
  2634.                 temp = temp0;
  2635.                 for(l = lowx_int+1; l < highx_int; l++) {
  2636.                     for (k = 0, temp_index = temp; k < components;
  2637.                          k++, temp_index += element_size) {
  2638.                         if (myswap_bytes) {
  2639.                             totals[k] += __GLU_SWAP_4_BYTES(temp_index);
  2640.                         } else {
  2641.                             totals[k] += *(const GLuint*)temp_index;
  2642.                         }
  2643.                     }
  2644.                     temp += group_size;
  2645.                 }
  2646.                 temp0 += ysize;
  2647.             }
  2648.  
  2649.             outindex = (j + (i * widthout)) * components;
  2650.             for (k = 0; k < components; k++) {
  2651.                 /* clamp at UINT_MAX */
  2652.                 float value= totals[k]/area;
  2653.                 if (value >= (float) UINT_MAX) {        /* need '=' */
  2654.                   dataout[outindex + k] = UINT_MAX;
  2655.                 }
  2656.                 else dataout[outindex + k] = value;
  2657.             }
  2658.             lowx_int = highx_int;
  2659.             lowx_float = highx_float;
  2660.             highx_int += convx_int;
  2661.             highx_float += convx_float;
  2662.             if(highx_float > 1) {
  2663.                 highx_float -= 1.0;
  2664.                 highx_int++;
  2665.             }
  2666.         }
  2667.         lowy_int = highy_int;
  2668.         lowy_float = highy_float;
  2669.         highy_int += convy_int;
  2670.         highy_float += convy_float;
  2671.         if(highy_float > 1) {
  2672.             highy_float -= 1.0;
  2673.             highy_int++;
  2674.         }
  2675.     }
  2676. }
  2677.  
  2678.  
  2679.  
  2680. static void scale_internal_int(GLint components, GLint widthin,
  2681.                            GLint heightin, const GLint *datain,
  2682.                            GLint widthout, GLint heightout,
  2683.                            GLint *dataout, GLint element_size,
  2684.                            GLint ysize, GLint group_size,
  2685.                            GLint myswap_bytes)
  2686. {
  2687.     float convx;
  2688.     float convy;
  2689.     float percent;
  2690.     /* Max components in a format is 4, so... */
  2691.     float totals[4];
  2692.     float area;
  2693.     int i,j,k,xindex;
  2694.  
  2695.     const char *temp, *temp0;
  2696.     const char *temp_index;
  2697.     int outindex;
  2698.  
  2699.     int lowx_int, highx_int, lowy_int, highy_int;
  2700.     float x_percent, y_percent;
  2701.     float lowx_float, highx_float, lowy_float, highy_float;
  2702.     float convy_float, convx_float;
  2703.     int convy_int, convx_int;
  2704.     int l, m;
  2705.     const char *left, *right;
  2706.  
  2707.     GLuint swapbuf;     /* unsigned buffer */
  2708.  
  2709.     if (widthin == widthout*2 && heightin == heightout*2) {
  2710.         halveImage_int(components, widthin, heightin,
  2711.         (const GLint *)datain, (GLint *)dataout,
  2712.         element_size, ysize, group_size, myswap_bytes);
  2713.         return;
  2714.     }
  2715.     convy = (float) heightin/heightout;
  2716.     convx = (float) widthin/widthout;
  2717.     convy_int = floor(convy);
  2718.     convy_float = convy - convy_int;
  2719.     convx_int = floor(convx);
  2720.     convx_float = convx - convx_int;
  2721.  
  2722.     area = convx * convy;
  2723.  
  2724.     lowy_int = 0;
  2725.     lowy_float = 0;
  2726.     highy_int = convy_int;
  2727.     highy_float = convy_float;
  2728.  
  2729.     for (i = 0; i < heightout; i++) {
  2730.         /* Clamp here to be sure we don't read beyond input buffer. */
  2731.         if (highy_int >= heightin)
  2732.             highy_int = heightin - 1;
  2733.         lowx_int = 0;
  2734.         lowx_float = 0;
  2735.         highx_int = convx_int;
  2736.         highx_float = convx_float;
  2737.  
  2738.         for (j = 0; j < widthout; j++) {
  2739.             /*
  2740.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  2741.             ** to (highx, highy) on input data into this pixel on output
  2742.             ** data.
  2743.             */
  2744.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  2745.  
  2746.             /* calculate the value for pixels in the 1st row */
  2747.             xindex = lowx_int*group_size;
  2748.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  2749.  
  2750.                 y_percent = 1-lowy_float;
  2751.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2752.                 percent = y_percent * (1-lowx_float);
  2753.                 for (k = 0, temp_index = temp; k < components;
  2754.                      k++, temp_index += element_size) {
  2755.                     if (myswap_bytes) {
  2756.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2757.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2758.                     } else {
  2759.                         totals[k] += *(const GLint*)temp_index * percent;
  2760.                     }
  2761.                 }
  2762.                 left = temp;
  2763.                 for(l = lowx_int+1; l < highx_int; l++) {
  2764.                     temp += group_size;
  2765.                     for (k = 0, temp_index = temp; k < components;
  2766.                          k++, temp_index += element_size) {
  2767.                         if (myswap_bytes) {
  2768.                             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2769.                             totals[k] += *(const GLint*)&swapbuf * y_percent;
  2770.                         } else {
  2771.                             totals[k] += *(const GLint*)temp_index * y_percent;
  2772.                         }
  2773.                     }
  2774.                 }
  2775.                 temp += group_size;
  2776.                 right = temp;
  2777.                 percent = y_percent * highx_float;
  2778.                 for (k = 0, temp_index = temp; k < components;
  2779.                      k++, temp_index += element_size) {
  2780.                     if (myswap_bytes) {
  2781.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2782.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2783.                     } else {
  2784.                         totals[k] += *(const GLint*)temp_index * percent;
  2785.                     }
  2786.                 }
  2787.  
  2788.                 /* calculate the value for pixels in the last row */
  2789.                 y_percent = highy_float;
  2790.                 percent = y_percent * (1-lowx_float);
  2791.                 temp = (const char *)datain + xindex + highy_int * ysize;
  2792.                 for (k = 0, temp_index = temp; k < components;
  2793.                      k++, temp_index += element_size) {
  2794.                     if (myswap_bytes) {
  2795.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2796.                         totals[k] += *(const GLint*)&swapbuf  * percent;
  2797.                     } else {
  2798.                         totals[k] += *(const GLint*)temp_index * percent;
  2799.                     }
  2800.                 }
  2801.                 for(l = lowx_int+1; l < highx_int; l++) {
  2802.                     temp += group_size;
  2803.                     for (k = 0, temp_index = temp; k < components;
  2804.                          k++, temp_index += element_size) {
  2805.                         if (myswap_bytes) {
  2806.                             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2807.                             totals[k] += *(const GLint*)&swapbuf * y_percent;
  2808.                         } else {
  2809.                             totals[k] += *(const GLint*)temp_index * y_percent;
  2810.                         }
  2811.                     }
  2812.                 }
  2813.                 temp += group_size;
  2814.                 percent = y_percent * highx_float;
  2815.                 for (k = 0, temp_index = temp; k < components;
  2816.                      k++, temp_index += element_size) {
  2817.                     if (myswap_bytes) {
  2818.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2819.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2820.                     } else {
  2821.                         totals[k] += *(const GLint*)temp_index * percent;
  2822.                     }
  2823.                 }
  2824.  
  2825.                 /* calculate the value for pixels in the 1st and last column */
  2826.                 for(m = lowy_int+1; m < highy_int; m++) {
  2827.                     left += ysize;
  2828.                     right += ysize;
  2829.                     for (k = 0; k < components;
  2830.                          k++, left += element_size, right += element_size) {
  2831.                         if (myswap_bytes) {
  2832.                             swapbuf = __GLU_SWAP_4_BYTES(left);
  2833.                             totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
  2834.                             swapbuf = __GLU_SWAP_4_BYTES(right);
  2835.                             totals[k] += *(const GLint*)&swapbuf * highx_float;
  2836.                         } else {
  2837.                             totals[k] += *(const GLint*)left * (1-lowx_float)
  2838.                                        + *(const GLint*)right * highx_float;
  2839.                         }
  2840.                     }
  2841.                 }
  2842.             } else if (highy_int > lowy_int) {
  2843.                 x_percent = highx_float - lowx_float;
  2844.                 percent = (1-lowy_float)*x_percent;
  2845.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  2846.                 for (k = 0, temp_index = temp; k < components;
  2847.                      k++, temp_index += element_size) {
  2848.                     if (myswap_bytes) {
  2849.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2850.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2851.                     } else {
  2852.                         totals[k] += *(const GLint*)temp_index * percent;
  2853.                     }
  2854.                 }
  2855.                 for(m = lowy_int+1; m < highy_int; m++) {
  2856.                     temp += ysize;
  2857.                     for (k = 0, temp_index = temp; k < components;
  2858.                          k++, temp_index += element_size) {
  2859.                         if (myswap_bytes) {
  2860.                             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2861.                             totals[k] += *(const GLint*)&swapbuf * x_percent;
  2862.                         } else {
  2863.                             totals[k] += *(const GLint*)temp_index * x_percent;
  2864.                         }
  2865.                     }
  2866.                 }
  2867.                 percent = x_percent * highy_float;
  2868.                 temp += ysize;
  2869.                 for (k = 0, temp_index = temp; k < components;
  2870.                      k++, temp_index += element_size) {
  2871.                     if (myswap_bytes) {
  2872.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2873.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2874.                     } else {
  2875.                         totals[k] += *(const GLint*)temp_index * percent;
  2876.                     }
  2877.                 }
  2878.             } else if (highx_int > lowx_int) {
  2879.                 y_percent = highy_float - lowy_float;
  2880.                 percent = (1-lowx_float)*y_percent;
  2881.  
  2882.                  temp = (const char *)datain + xindex + lowy_int*ysize;
  2883.                 for (k = 0, temp_index = temp; k < components;
  2884.                      k++, temp_index += element_size) {
  2885.                     if (myswap_bytes) {
  2886.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2887.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2888.                     } else {
  2889.                         totals[k] += *(const GLint*)temp_index * percent;
  2890.                     }
  2891.                 }
  2892.                 for (l = lowx_int+1; l < highx_int; l++) {
  2893.                     temp += group_size;
  2894.                     for (k = 0, temp_index = temp; k < components;
  2895.                          k++, temp_index += element_size) {
  2896.                         if (myswap_bytes) {
  2897.                             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2898.                             totals[k] += *(const GLint*)&swapbuf * y_percent;
  2899.                         } else {
  2900.                             totals[k] += *(const GLint*)temp_index * y_percent;
  2901.                         }
  2902.                     }
  2903.                 }
  2904.                 temp += group_size;
  2905.                 percent = y_percent * highx_float;
  2906.                 for (k = 0, temp_index = temp; k < components;
  2907.                      k++, temp_index += element_size) {
  2908.                     if (myswap_bytes) {
  2909.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2910.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2911.                     } else {
  2912.                         totals[k] += *(const GLint*)temp_index * percent;
  2913.                     }
  2914.                 }
  2915.             } else {
  2916.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  2917.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  2918.                 for (k = 0, temp_index = temp; k < components;
  2919.                      k++, temp_index += element_size) {
  2920.                     if (myswap_bytes) {
  2921.                         swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2922.                         totals[k] += *(const GLint*)&swapbuf * percent;
  2923.                     } else {
  2924.                         totals[k] += *(const GLint*)temp_index * percent;
  2925.                     }
  2926.                 }
  2927.             }
  2928.  
  2929.             /* this is for the pixels in the body */
  2930.             temp0 = (const char *)datain + xindex + group_size +
  2931.                  (lowy_int+1)*ysize;
  2932.             for (m = lowy_int+1; m < highy_int; m++) {
  2933.                 temp = temp0;
  2934.                 for(l = lowx_int+1; l < highx_int; l++) {
  2935.                     for (k = 0, temp_index = temp; k < components;
  2936.                          k++, temp_index += element_size) {
  2937.                         if (myswap_bytes) {
  2938.                             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
  2939.                             totals[k] += *(const GLint*)&swapbuf;
  2940.                         } else {
  2941.                             totals[k] += *(const GLint*)temp_index;
  2942.                         }
  2943.                     }
  2944.                     temp += group_size;
  2945.                 }
  2946.                 temp0 += ysize;
  2947.             }
  2948.  
  2949.             outindex = (j + (i * widthout)) * components;
  2950.             for (k = 0; k < components; k++) {
  2951.                 dataout[outindex + k] = totals[k]/area;
  2952.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  2953.             }
  2954.             lowx_int = highx_int;
  2955.             lowx_float = highx_float;
  2956.             highx_int += convx_int;
  2957.             highx_float += convx_float;
  2958.             if(highx_float > 1) {
  2959.                 highx_float -= 1.0;
  2960.                 highx_int++;
  2961.             }
  2962.         }
  2963.         lowy_int = highy_int;
  2964.         lowy_float = highy_float;
  2965.         highy_int += convy_int;
  2966.         highy_float += convy_float;
  2967.         if(highy_float > 1) {
  2968.             highy_float -= 1.0;
  2969.             highy_int++;
  2970.         }
  2971.     }
  2972. }
  2973.  
  2974.  
  2975.  
  2976. static void scale_internal_float(GLint components, GLint widthin,
  2977.                            GLint heightin, const GLfloat *datain,
  2978.                            GLint widthout, GLint heightout,
  2979.                            GLfloat *dataout, GLint element_size,
  2980.                            GLint ysize, GLint group_size,
  2981.                            GLint myswap_bytes)
  2982. {
  2983.     float convx;
  2984.     float convy;
  2985.     float percent;
  2986.     /* Max components in a format is 4, so... */
  2987.     float totals[4];
  2988.     float area;
  2989.     int i,j,k,xindex;
  2990.  
  2991.     const char *temp, *temp0;
  2992.     const char *temp_index;
  2993.     int outindex;
  2994.  
  2995.     int lowx_int, highx_int, lowy_int, highy_int;
  2996.     float x_percent, y_percent;
  2997.     float lowx_float, highx_float, lowy_float, highy_float;
  2998.     float convy_float, convx_float;
  2999.     int convy_int, convx_int;
  3000.     int l, m;
  3001.     const char *left, *right;
  3002.  
  3003.     union { GLuint b; GLfloat f; } swapbuf;
  3004.  
  3005.     if (widthin == widthout*2 && heightin == heightout*2) {
  3006.         halveImage_float(components, widthin, heightin,
  3007.         (const GLfloat *)datain, (GLfloat *)dataout,
  3008.         element_size, ysize, group_size, myswap_bytes);
  3009.         return;
  3010.     }
  3011.     convy = (float) heightin/heightout;
  3012.     convx = (float) widthin/widthout;
  3013.     convy_int = floor(convy);
  3014.     convy_float = convy - convy_int;
  3015.     convx_int = floor(convx);
  3016.     convx_float = convx - convx_int;
  3017.  
  3018.     area = convx * convy;
  3019.  
  3020.     lowy_int = 0;
  3021.     lowy_float = 0;
  3022.     highy_int = convy_int;
  3023.     highy_float = convy_float;
  3024.  
  3025.     for (i = 0; i < heightout; i++) {
  3026.         /* Clamp here to be sure we don't read beyond input buffer. */
  3027.         if (highy_int >= heightin)
  3028.             highy_int = heightin - 1;
  3029.         lowx_int = 0;
  3030.         lowx_float = 0;
  3031.         highx_int = convx_int;
  3032.         highx_float = convx_float;
  3033.  
  3034.         for (j = 0; j < widthout; j++) {
  3035.             /*
  3036.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  3037.             ** to (highx, highy) on input data into this pixel on output
  3038.             ** data.
  3039.             */
  3040.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  3041.  
  3042.             /* calculate the value for pixels in the 1st row */
  3043.             xindex = lowx_int*group_size;
  3044.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  3045.  
  3046.                 y_percent = 1-lowy_float;
  3047.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  3048.                 percent = y_percent * (1-lowx_float);
  3049.                 for (k = 0, temp_index = temp; k < components;
  3050.                      k++, temp_index += element_size) {
  3051.                     if (myswap_bytes) {
  3052.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3053.                         totals[k] += swapbuf.f * percent;
  3054.                     } else {
  3055.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3056.                     }
  3057.                 }
  3058.                 left = temp;
  3059.                 for(l = lowx_int+1; l < highx_int; l++) {
  3060.                     temp += group_size;
  3061.                     for (k = 0, temp_index = temp; k < components;
  3062.                          k++, temp_index += element_size) {
  3063.                         if (myswap_bytes) {
  3064.                             swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3065.                             totals[k] += swapbuf.f * y_percent;
  3066.                         } else {
  3067.                             totals[k] += *(const GLfloat*)temp_index * y_percent;
  3068.                         }
  3069.                     }
  3070.                 }
  3071.                 temp += group_size;
  3072.                 right = temp;
  3073.                 percent = y_percent * highx_float;
  3074.                 for (k = 0, temp_index = temp; k < components;
  3075.                      k++, temp_index += element_size) {
  3076.                     if (myswap_bytes) {
  3077.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3078.                         totals[k] += swapbuf.f * percent;
  3079.                     } else {
  3080.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3081.                     }
  3082.                 }
  3083.  
  3084.                 /* calculate the value for pixels in the last row */
  3085.                 y_percent = highy_float;
  3086.                 percent = y_percent * (1-lowx_float);
  3087.                 temp = (const char *)datain + xindex + highy_int * ysize;
  3088.                 for (k = 0, temp_index = temp; k < components;
  3089.                      k++, temp_index += element_size) {
  3090.                     if (myswap_bytes) {
  3091.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3092.                         totals[k] += swapbuf.f * percent;
  3093.                     } else {
  3094.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3095.                     }
  3096.                 }
  3097.                 for(l = lowx_int+1; l < highx_int; l++) {
  3098.                     temp += group_size;
  3099.                     for (k = 0, temp_index = temp; k < components;
  3100.                          k++, temp_index += element_size) {
  3101.                         if (myswap_bytes) {
  3102.                             swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3103.                             totals[k] += swapbuf.f * y_percent;
  3104.                         } else {
  3105.                             totals[k] += *(const GLfloat*)temp_index * y_percent;
  3106.                         }
  3107.                     }
  3108.                 }
  3109.                 temp += group_size;
  3110.                 percent = y_percent * highx_float;
  3111.                 for (k = 0, temp_index = temp; k < components;
  3112.                      k++, temp_index += element_size) {
  3113.                     if (myswap_bytes) {
  3114.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3115.                         totals[k] += swapbuf.f * percent;
  3116.                     } else {
  3117.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3118.                     }
  3119.                 }
  3120.  
  3121.                 /* calculate the value for pixels in the 1st and last column */
  3122.                 for(m = lowy_int+1; m < highy_int; m++) {
  3123.                     left += ysize;
  3124.                     right += ysize;
  3125.                     for (k = 0; k < components;
  3126.                          k++, left += element_size, right += element_size) {
  3127.                         if (myswap_bytes) {
  3128.                             swapbuf.b = __GLU_SWAP_4_BYTES(left);
  3129.                             totals[k] += swapbuf.f * (1-lowx_float);
  3130.                             swapbuf.b = __GLU_SWAP_4_BYTES(right);
  3131.                             totals[k] += swapbuf.f * highx_float;
  3132.                         } else {
  3133.                             totals[k] += *(const GLfloat*)left * (1-lowx_float)
  3134.                                        + *(const GLfloat*)right * highx_float;
  3135.                         }
  3136.                     }
  3137.                 }
  3138.             } else if (highy_int > lowy_int) {
  3139.                 x_percent = highx_float - lowx_float;
  3140.                 percent = (1-lowy_float)*x_percent;
  3141.                 temp = (const char *)datain + xindex + lowy_int*ysize;
  3142.                 for (k = 0, temp_index = temp; k < components;
  3143.                      k++, temp_index += element_size) {
  3144.                     if (myswap_bytes) {
  3145.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3146.                         totals[k] += swapbuf.f * percent;
  3147.                     } else {
  3148.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3149.                     }
  3150.                 }
  3151.                 for(m = lowy_int+1; m < highy_int; m++) {
  3152.                     temp += ysize;
  3153.                     for (k = 0, temp_index = temp; k < components;
  3154.                          k++, temp_index += element_size) {
  3155.                         if (myswap_bytes) {
  3156.                             swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3157.                             totals[k] += swapbuf.f * x_percent;
  3158.                         } else {
  3159.                             totals[k] += *(const GLfloat*)temp_index * x_percent;
  3160.                         }
  3161.                     }
  3162.                 }
  3163.                 percent = x_percent * highy_float;
  3164.                 temp += ysize;
  3165.                 for (k = 0, temp_index = temp; k < components;
  3166.                      k++, temp_index += element_size) {
  3167.                     if (myswap_bytes) {
  3168.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3169.                         totals[k] += swapbuf.f * percent;
  3170.                     } else {
  3171.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3172.                     }
  3173.                 }
  3174.             } else if (highx_int > lowx_int) {
  3175.                 y_percent = highy_float - lowy_float;
  3176.                 percent = (1-lowx_float)*y_percent;
  3177.  
  3178.              temp = (const char *)datain + xindex + lowy_int*ysize;
  3179.                 for (k = 0, temp_index = temp; k < components;
  3180.                      k++, temp_index += element_size) {
  3181.                     if (myswap_bytes) {
  3182.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3183.                         totals[k] += swapbuf.f * percent;
  3184.                     } else {
  3185.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3186.                     }
  3187.                 }
  3188.                 for (l = lowx_int+1; l < highx_int; l++) {
  3189.                     temp += group_size;
  3190.                     for (k = 0, temp_index = temp; k < components;
  3191.                          k++, temp_index += element_size) {
  3192.                         if (myswap_bytes) {
  3193.                             swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3194.                             totals[k] += swapbuf.f * y_percent;
  3195.                         } else {
  3196.                             totals[k] += *(const GLfloat*)temp_index * y_percent;
  3197.                         }
  3198.                     }
  3199.                 }
  3200.                 temp += group_size;
  3201.                 percent = y_percent * highx_float;
  3202.                 for (k = 0, temp_index = temp; k < components;
  3203.                      k++, temp_index += element_size) {
  3204.                     if (myswap_bytes) {
  3205.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3206.                         totals[k] += swapbuf.f * percent;
  3207.                     } else {
  3208.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3209.                     }
  3210.                 }
  3211.             } else {
  3212.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  3213.                 temp = (const char *)datain + xindex + lowy_int * ysize;
  3214.                 for (k = 0, temp_index = temp; k < components;
  3215.                      k++, temp_index += element_size) {
  3216.                     if (myswap_bytes) {
  3217.                         swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3218.                         totals[k] += swapbuf.f * percent;
  3219.                     } else {
  3220.                         totals[k] += *(const GLfloat*)temp_index * percent;
  3221.                     }
  3222.                 }
  3223.             }
  3224.  
  3225.             /* this is for the pixels in the body */
  3226.             temp0 = (const char *)datain + xindex + group_size +
  3227.                  (lowy_int+1)*ysize;
  3228.             for (m = lowy_int+1; m < highy_int; m++) {
  3229.                 temp = temp0;
  3230.                 for(l = lowx_int+1; l < highx_int; l++) {
  3231.                     for (k = 0, temp_index = temp; k < components;
  3232.                          k++, temp_index += element_size) {
  3233.                         if (myswap_bytes) {
  3234.                             swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
  3235.                             totals[k] += swapbuf.f;
  3236.                         } else {
  3237.                             totals[k] += *(const GLfloat*)temp_index;
  3238.                         }
  3239.                     }
  3240.                     temp += group_size;
  3241.                 }
  3242.                 temp0 += ysize;
  3243.             }
  3244.  
  3245.             outindex = (j + (i * widthout)) * components;
  3246.             for (k = 0; k < components; k++) {
  3247.                 dataout[outindex + k] = totals[k]/area;
  3248.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  3249.             }
  3250.             lowx_int = highx_int;
  3251.             lowx_float = highx_float;
  3252.             highx_int += convx_int;
  3253.             highx_float += convx_float;
  3254.             if(highx_float > 1) {
  3255.                 highx_float -= 1.0;
  3256.                 highx_int++;
  3257.             }
  3258.         }
  3259.         lowy_int = highy_int;
  3260.         lowy_float = highy_float;
  3261.         highy_int += convy_int;
  3262.         highy_float += convy_float;
  3263.         if(highy_float > 1) {
  3264.             highy_float -= 1.0;
  3265.             highy_int++;
  3266.         }
  3267.     }
  3268. }
  3269.  
  3270. static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
  3271. {
  3272.     if (!legalFormat(format) || !legalType(type)) {
  3273.         return GLU_INVALID_ENUM;
  3274.     }
  3275.     if (format == GL_STENCIL_INDEX) {
  3276.         return GLU_INVALID_ENUM;
  3277.     }
  3278.  
  3279.     if (!isLegalFormatForPackedPixelType(format, type)) {
  3280.         return GLU_INVALID_OPERATION;
  3281.     }
  3282.  
  3283.     return 0;
  3284. } /* checkMipmapArgs() */
  3285.  
  3286. static GLboolean legalFormat(GLenum format)
  3287. {
  3288.     switch(format) {
  3289.       case GL_COLOR_INDEX:
  3290.       case GL_STENCIL_INDEX:
  3291.       case GL_DEPTH_COMPONENT:
  3292.       case GL_RED:
  3293.       case GL_GREEN:
  3294.       case GL_BLUE:
  3295.       case GL_ALPHA:
  3296.       case GL_RGB:
  3297.       case GL_RGBA:
  3298.       case GL_LUMINANCE:
  3299.       case GL_LUMINANCE_ALPHA:
  3300.       case GL_BGR:
  3301.       case GL_BGRA:
  3302.         return GL_TRUE;
  3303.       default:
  3304.         return GL_FALSE;
  3305.     }
  3306. }
  3307.  
  3308.  
  3309. static GLboolean legalType(GLenum type)
  3310. {
  3311.     switch(type) {
  3312.       case GL_BITMAP:
  3313.       case GL_BYTE:
  3314.       case GL_UNSIGNED_BYTE:
  3315.       case GL_SHORT:
  3316.       case GL_UNSIGNED_SHORT:
  3317.       case GL_INT:
  3318.       case GL_UNSIGNED_INT:
  3319.       case GL_FLOAT:
  3320.       case GL_UNSIGNED_BYTE_3_3_2:
  3321.       case GL_UNSIGNED_BYTE_2_3_3_REV:  
  3322.       case GL_UNSIGNED_SHORT_5_6_5:
  3323.       case GL_UNSIGNED_SHORT_5_6_5_REV:
  3324.       case GL_UNSIGNED_SHORT_4_4_4_4:
  3325.       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  3326.       case GL_UNSIGNED_SHORT_5_5_5_1:
  3327.       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  3328.       case GL_UNSIGNED_INT_8_8_8_8:
  3329.       case GL_UNSIGNED_INT_8_8_8_8_REV:
  3330.       case GL_UNSIGNED_INT_10_10_10_2:
  3331.       case GL_UNSIGNED_INT_2_10_10_10_REV:
  3332.          return GL_TRUE;
  3333.       default:
  3334.         return GL_FALSE;
  3335.     }
  3336. }
  3337.  
  3338. /* */
  3339. static GLboolean isTypePackedPixel(GLenum type)
  3340. {
  3341.    assert(legalType(type));
  3342.  
  3343.    if (type == GL_UNSIGNED_BYTE_3_3_2 ||
  3344.        type == GL_UNSIGNED_BYTE_2_3_3_REV ||
  3345.        type == GL_UNSIGNED_SHORT_5_6_5 ||
  3346.        type == GL_UNSIGNED_SHORT_5_6_5_REV ||
  3347.        type == GL_UNSIGNED_SHORT_4_4_4_4 ||
  3348.        type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
  3349.        type == GL_UNSIGNED_SHORT_5_5_5_1 ||
  3350.        type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
  3351.        type == GL_UNSIGNED_INT_8_8_8_8 ||
  3352.        type == GL_UNSIGNED_INT_8_8_8_8_REV ||
  3353.        type == GL_UNSIGNED_INT_10_10_10_2 ||
  3354.        type == GL_UNSIGNED_INT_2_10_10_10_REV) {
  3355.       return 1;
  3356.    }
  3357.    else return 0;
  3358. } /* isTypePackedPixel() */
  3359.  
  3360. /* Determines if the packed pixel type is compatible with the format */
  3361. static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
  3362. {
  3363.    /* if not a packed pixel type then return true */
  3364.    if (!isTypePackedPixel(type)) {
  3365.       return GL_TRUE;
  3366.    }
  3367.  
  3368.    /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
  3369.    if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
  3370.         type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
  3371.        && format != GL_RGB)
  3372.       return GL_FALSE;
  3373.  
  3374.    /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
  3375.     * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
  3376.     */
  3377.    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
  3378.         type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
  3379.         type == GL_UNSIGNED_SHORT_5_5_5_1 ||
  3380.         type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
  3381.         type == GL_UNSIGNED_INT_8_8_8_8 ||
  3382.         type == GL_UNSIGNED_INT_8_8_8_8_REV ||
  3383.         type == GL_UNSIGNED_INT_10_10_10_2 ||
  3384.         type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
  3385.        (format != GL_RGBA &&
  3386.         format != GL_BGRA)) {
  3387.       return GL_FALSE;
  3388.    }
  3389.  
  3390.    return GL_TRUE;
  3391. } /* isLegalFormatForPackedPixelType() */
  3392.  
  3393. static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel,
  3394.                                GLint totalLevels)
  3395. {
  3396.    if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel ||
  3397.        totalLevels < maxLevel)
  3398.       return GL_FALSE;
  3399.    else return GL_TRUE;
  3400. } /* isLegalLevels() */
  3401.  
  3402. /* Given user requested texture size, determine if it fits. If it
  3403.  * doesn't then halve both sides and make the determination again
  3404.  * until it does fit (for IR only).
  3405.  * Note that proxy textures are not implemented in RE* even though
  3406.  * they advertise the texture extension.
  3407.  * Note that proxy textures are implemented but not according to spec in
  3408.  * IMPACT*.
  3409.  */
  3410. static void closestFit(GLenum target, GLint width, GLint height,
  3411.                        GLint internalFormat, GLenum format, GLenum type,
  3412.                        GLint *newWidth, GLint *newHeight)
  3413. {
  3414.    /* Use proxy textures if OpenGL version is >= 1.1 */
  3415.    if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
  3416.         ) {
  3417.       GLint widthPowerOf2= nearestPower(width);
  3418.       GLint heightPowerOf2= nearestPower(height);      
  3419.       GLint proxyWidth;
  3420.  
  3421.       do {
  3422.          /* compute level 1 width & height, clamping each at 1 */
  3423.          GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
  3424.                                  widthPowerOf2 >> 1 :
  3425.                                  widthPowerOf2;
  3426.          GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
  3427.                                   heightPowerOf2 >> 1 :
  3428.                                   heightPowerOf2;
  3429.          GLenum proxyTarget;
  3430.          assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
  3431.  
  3432.          /* does width x height at level 1 & all their mipmaps fit? */
  3433.          if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
  3434.             proxyTarget = GL_PROXY_TEXTURE_2D;
  3435.             glTexImage2D(proxyTarget, 1, /* must be non-zero */
  3436.                          internalFormat,
  3437.                          widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
  3438.          } else
  3439. #if defined(GL_ARB_texture_cube_map)
  3440.          if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
  3441.              (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
  3442.              (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
  3443.              (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
  3444.              (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
  3445.              (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
  3446.              proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
  3447.              glTexImage2D(proxyTarget, 1, /* must be non-zero */
  3448.                           internalFormat,
  3449.                           widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
  3450.          } else
  3451. #endif /* GL_ARB_texture_cube_map */
  3452.          {
  3453.             assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
  3454.             proxyTarget = GL_PROXY_TEXTURE_1D;
  3455.             glTexImage1D(proxyTarget, 1, /* must be non-zero */
  3456.                          internalFormat,widthAtLevelOne,0,format,type,NULL);
  3457.          }
  3458.          glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
  3459.          /* does it fit??? */
  3460.          if (proxyWidth == 0) { /* nope, so try again with these sizes */
  3461.             if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
  3462.                /* An 1x1 texture couldn't fit for some reason, so
  3463.                 * break out.  This should never happen. But things
  3464.                 * happen.  The disadvantage with this if-statement is
  3465.                 * that we will never be aware of when this happens
  3466.                 * since it will silently branch out.
  3467.                 */
  3468.                goto noProxyTextures;
  3469.             }
  3470.             widthPowerOf2= widthAtLevelOne;
  3471.             heightPowerOf2= heightAtLevelOne;
  3472.          }
  3473.          /* else it does fit */
  3474.       } while (proxyWidth == 0);
  3475.       /* loop must terminate! */
  3476.  
  3477.       /* return the width & height at level 0 that fits */
  3478.       *newWidth= widthPowerOf2;
  3479.       *newHeight= heightPowerOf2;
  3480. /*printf("Proxy Textures\n");*/
  3481.    } /* if gluCheckExtension() */
  3482.    else {                       /* no texture extension, so do this instead */
  3483.       GLint maxsize;
  3484.  
  3485. noProxyTextures:
  3486.  
  3487.       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
  3488.       /* clamp user's texture sizes to maximum sizes, if necessary */
  3489.       *newWidth = nearestPower(width);
  3490.       if (*newWidth > maxsize) *newWidth = maxsize;
  3491.       *newHeight = nearestPower(height);
  3492.       if (*newHeight > maxsize) *newHeight = maxsize;
  3493. /*printf("NO proxy textures\n");*/
  3494.    }
  3495. } /* closestFit() */
  3496.  
  3497. GLint GLAPIENTRY
  3498. gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
  3499.                     GLenum typein, const void *datain,
  3500.                     GLsizei widthout, GLsizei heightout, GLenum typeout,
  3501.                     void *dataout)
  3502. {
  3503.     int components;
  3504.     GLushort *beforeImage;
  3505.     GLushort *afterImage;
  3506.     PixelStorageModes psm;
  3507.  
  3508.     if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
  3509.         return 0;
  3510.     }
  3511.     if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
  3512.         return GLU_INVALID_VALUE;
  3513.     }
  3514.     if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
  3515.         return GLU_INVALID_ENUM;
  3516.     }
  3517.     if (!isLegalFormatForPackedPixelType(format, typein)) {
  3518.        return GLU_INVALID_OPERATION;
  3519.     }
  3520.     if (!isLegalFormatForPackedPixelType(format, typeout)) {
  3521.        return GLU_INVALID_OPERATION;
  3522.     }
  3523.     beforeImage =
  3524.         malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
  3525.     afterImage =
  3526.         malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
  3527.     if (beforeImage == NULL || afterImage == NULL) {
  3528.         free(beforeImage);
  3529.         free(afterImage);
  3530.         return GLU_OUT_OF_MEMORY;
  3531.     }
  3532.  
  3533.     retrieveStoreModes(&psm);
  3534.     fill_image(&psm,widthin, heightin, format, typein, is_index(format),
  3535.             datain, beforeImage);
  3536.     components = elements_per_group(format, 0);
  3537.     scale_internal(components, widthin, heightin, beforeImage,
  3538.             widthout, heightout, afterImage);
  3539.     empty_image(&psm,widthout, heightout, format, typeout,
  3540.             is_index(format), afterImage, dataout);
  3541.     free((GLbyte *) beforeImage);
  3542.     free((GLbyte *) afterImage);
  3543.  
  3544.     return 0;
  3545. }
  3546.  
  3547. int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
  3548.                                GLsizei width,
  3549.                                GLsizei widthPowerOf2,
  3550.                                GLenum format, GLenum type,
  3551.                                GLint userLevel, GLint baseLevel,GLint maxLevel,
  3552.                                const void *data)
  3553. {
  3554.     GLint newwidth;
  3555.     GLint level, levels;
  3556.     GLushort *newImage;
  3557.     GLint newImage_width;
  3558.     GLushort *otherImage;
  3559.     GLushort *imageTemp;
  3560.     GLint memreq;
  3561.     GLint cmpts;
  3562.     PixelStorageModes psm;
  3563.  
  3564.     assert(checkMipmapArgs(internalFormat,format,type) == 0);
  3565.     assert(width >= 1);
  3566.  
  3567.     otherImage = NULL;
  3568.  
  3569.     newwidth= widthPowerOf2;
  3570.     levels = computeLog(newwidth);
  3571.  
  3572.     levels+= userLevel;
  3573.  
  3574.     retrieveStoreModes(&psm);
  3575.     newImage = (GLushort *)
  3576.         malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
  3577.     newImage_width = width;
  3578.     if (newImage == NULL) {
  3579.         return GLU_OUT_OF_MEMORY;
  3580.     }
  3581.     fill_image(&psm,width, 1, format, type, is_index(format),
  3582.             data, newImage);
  3583.     cmpts = elements_per_group(format,type);
  3584.     glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
  3585.     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  3586.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  3587.     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  3588.     /*
  3589.     ** If swap_bytes was set, swapping occurred in fill_image.
  3590.     */
  3591.     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  3592.  
  3593.     for (level = userLevel; level <= levels; level++) {
  3594.         if (newImage_width == newwidth) {
  3595.             /* Use newImage for this level */
  3596.             if (baseLevel <= level && level <= maxLevel) {
  3597.             glTexImage1D(target, level, internalFormat, newImage_width,
  3598.                     0, format, GL_UNSIGNED_SHORT, (void *) newImage);
  3599.             }
  3600.         } else {
  3601.             if (otherImage == NULL) {
  3602.                 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
  3603.                 otherImage = (GLushort *) malloc(memreq);
  3604.                 if (otherImage == NULL) {
  3605.                     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  3606.                     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  3607.                     glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
  3608.                     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3609.                     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  3610.                     free(newImage);
  3611.                     return GLU_OUT_OF_MEMORY;
  3612.                 }
  3613.             }
  3614.             scale_internal(cmpts, newImage_width, 1, newImage,
  3615.                     newwidth, 1, otherImage);
  3616.             /* Swap newImage and otherImage */
  3617.             imageTemp = otherImage;
  3618.             otherImage = newImage;
  3619.             newImage = imageTemp;
  3620.  
  3621.             newImage_width = newwidth;
  3622.             if (baseLevel <= level && level <= maxLevel) {
  3623.             glTexImage1D(target, level, internalFormat, newImage_width,
  3624.                     0, format, GL_UNSIGNED_SHORT, (void *) newImage);
  3625.             }
  3626.         }
  3627.         if (newwidth > 1) newwidth /= 2;
  3628.     }
  3629.     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  3630.     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  3631.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  3632.     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3633.     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  3634.  
  3635.     free((GLbyte *) newImage);
  3636.     if (otherImage) {
  3637.         free((GLbyte *) otherImage);
  3638.     }
  3639.     return 0;
  3640. }
  3641.  
  3642. GLint GLAPIENTRY
  3643. gluBuild1DMipmapLevels(GLenum target, GLint internalFormat,
  3644.                              GLsizei width,
  3645.                              GLenum format, GLenum type,
  3646.                              GLint userLevel, GLint baseLevel, GLint maxLevel,
  3647.                              const void *data)
  3648. {
  3649.    int levels;
  3650.  
  3651.    int rc= checkMipmapArgs(internalFormat,format,type);
  3652.    if (rc != 0) return rc;
  3653.  
  3654.    if (width < 1) {
  3655.        return GLU_INVALID_VALUE;
  3656.    }
  3657.  
  3658.    levels = computeLog(width);
  3659.  
  3660.    levels+= userLevel;
  3661.    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
  3662.       return GLU_INVALID_VALUE;
  3663.  
  3664.    return gluBuild1DMipmapLevelsCore(target, internalFormat,
  3665.                                      width,
  3666.                                      width,format, type,
  3667.                                      userLevel, baseLevel, maxLevel,
  3668.                                      data);
  3669. } /* gluBuild1DMipmapLevels() */
  3670.  
  3671. GLint GLAPIENTRY
  3672. gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
  3673.                         GLenum format, GLenum type,
  3674.                         const void *data)
  3675. {
  3676.    GLint widthPowerOf2;
  3677.    int levels;
  3678.    GLint dummy;
  3679.  
  3680.    int rc= checkMipmapArgs(internalFormat,format,type);
  3681.    if (rc != 0) return rc;
  3682.  
  3683.    if (width < 1) {
  3684.        return GLU_INVALID_VALUE;
  3685.    }
  3686.  
  3687.    closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
  3688.    levels = computeLog(widthPowerOf2);
  3689.  
  3690.    return gluBuild1DMipmapLevelsCore(target,internalFormat,
  3691.                                      width,
  3692.                                      widthPowerOf2,
  3693.                                      format,type,0,0,levels,data);
  3694. }
  3695.  
  3696. static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
  3697.                      GLint width, GLint height, GLenum format,
  3698.                      GLenum type, const void *data)
  3699. {
  3700.     GLint newwidth, newheight;
  3701.     GLint level, levels;
  3702.     GLushort *newImage;
  3703.     GLint newImage_width;
  3704.     GLint newImage_height;
  3705.     GLushort *otherImage;
  3706.     GLushort *imageTemp;
  3707.     GLint memreq;
  3708.     GLint cmpts;
  3709.     PixelStorageModes psm;
  3710.  
  3711.     retrieveStoreModes(&psm);
  3712.  
  3713. #if 0
  3714.     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
  3715.     newwidth = nearestPower(width);
  3716.     if (newwidth > maxsize) newwidth = maxsize;
  3717.     newheight = nearestPower(height);
  3718.     if (newheight > maxsize) newheight = maxsize;
  3719. #else
  3720.     closestFit(target,width,height,internalFormat,format,type,
  3721.                &newwidth,&newheight);
  3722. #endif
  3723.     levels = computeLog(newwidth);
  3724.     level = computeLog(newheight);
  3725.     if (level > levels) levels=level;
  3726.  
  3727.     otherImage = NULL;
  3728.     newImage = (GLushort *)
  3729.         malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
  3730.     newImage_width = width;
  3731.     newImage_height = height;
  3732.     if (newImage == NULL) {
  3733.         return GLU_OUT_OF_MEMORY;
  3734.     }
  3735.  
  3736.     fill_image(&psm,width, height, format, type, is_index(format),
  3737.           data, newImage);
  3738.  
  3739.     cmpts = elements_per_group(format,type);
  3740.     glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
  3741.     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  3742.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  3743.     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  3744.     /*
  3745.     ** If swap_bytes was set, swapping occurred in fill_image.
  3746.     */
  3747.     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  3748.  
  3749.     for (level = 0; level <= levels; level++) {
  3750.         if (newImage_width == newwidth && newImage_height == newheight) {            /* Use newImage for this level */
  3751.             glTexImage2D(target, level, internalFormat, newImage_width,
  3752.                     newImage_height, 0, format, GL_UNSIGNED_SHORT,
  3753.                     (void *) newImage);
  3754.         } else {
  3755.             if (otherImage == NULL) {
  3756.                 memreq =
  3757.                     image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
  3758.                 otherImage = (GLushort *) malloc(memreq);
  3759.                 if (otherImage == NULL) {
  3760.                     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  3761.                     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  3762.                     glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
  3763.                     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3764.                     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  3765.                     free(newImage);
  3766.                     return GLU_OUT_OF_MEMORY;
  3767.                 }
  3768.             }
  3769.             scale_internal(cmpts, newImage_width, newImage_height, newImage,
  3770.                     newwidth, newheight, otherImage);
  3771.             /* Swap newImage and otherImage */
  3772.             imageTemp = otherImage;
  3773.             otherImage = newImage;
  3774.             newImage = imageTemp;
  3775.  
  3776.             newImage_width = newwidth;
  3777.             newImage_height = newheight;
  3778.             glTexImage2D(target, level, internalFormat, newImage_width,
  3779.                     newImage_height, 0, format, GL_UNSIGNED_SHORT,
  3780.                     (void *) newImage);
  3781.         }
  3782.         if (newwidth > 1) newwidth /= 2;
  3783.         if (newheight > 1) newheight /= 2;
  3784.     }
  3785.     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  3786.     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  3787.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  3788.     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3789.     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  3790.  
  3791.     free((GLbyte *) newImage);
  3792.     if (otherImage) {
  3793.         free((GLbyte *) otherImage);
  3794.     }
  3795.     return 0;
  3796. }
  3797.  
  3798. /* To make swapping images less error prone */
  3799. #define __GLU_INIT_SWAP_IMAGE void *tmpImage
  3800. #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
  3801.  
  3802. static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
  3803.                                       GLsizei width, GLsizei height,
  3804.                                       GLsizei widthPowerOf2,
  3805.                                       GLsizei heightPowerOf2,
  3806.                                       GLenum format, GLenum type,
  3807.                                       GLint userLevel,
  3808.                                       GLint baseLevel,GLint maxLevel,
  3809.                                       const void *data)
  3810. {
  3811.     GLint newwidth, newheight;
  3812.     GLint level, levels;
  3813.     const void *usersImage; /* passed from user. Don't touch! */
  3814.     void *srcImage, *dstImage; /* scratch area to build mipmapped images */
  3815.     __GLU_INIT_SWAP_IMAGE;
  3816.     GLint memreq;
  3817.     GLint cmpts;
  3818.  
  3819.     GLint myswap_bytes, groups_per_line, element_size, group_size;
  3820.     GLint rowsize, padding;
  3821.     PixelStorageModes psm;
  3822.  
  3823.     assert(checkMipmapArgs(internalFormat,format,type) == 0);
  3824.     assert(width >= 1 && height >= 1);
  3825.  
  3826.     if(type == GL_BITMAP) {
  3827.         return bitmapBuild2DMipmaps(target, internalFormat, width, height,
  3828.                 format, type, data);
  3829.     }
  3830.  
  3831.     srcImage = dstImage = NULL;
  3832.  
  3833.     newwidth= widthPowerOf2;
  3834.     newheight= heightPowerOf2;
  3835.     levels = computeLog(newwidth);
  3836.     level = computeLog(newheight);
  3837.     if (level > levels) levels=level;
  3838.  
  3839.     levels+= userLevel;
  3840.  
  3841.     retrieveStoreModes(&psm);
  3842.     myswap_bytes = psm.unpack_swap_bytes;
  3843.     cmpts = elements_per_group(format,type);
  3844.     if (psm.unpack_row_length > 0) {
  3845.         groups_per_line = psm.unpack_row_length;
  3846.     } else {
  3847.         groups_per_line = width;
  3848.     }
  3849.  
  3850.     element_size = bytes_per_element(type);
  3851.     group_size = element_size * cmpts;
  3852.     if (element_size == 1) myswap_bytes = 0;
  3853.  
  3854.     rowsize = groups_per_line * group_size;
  3855.     padding = (rowsize % psm.unpack_alignment);
  3856.     if (padding) {
  3857.         rowsize += psm.unpack_alignment - padding;
  3858.     }
  3859.     usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
  3860.         psm.unpack_skip_pixels * group_size;
  3861.  
  3862.     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  3863.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  3864.     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  3865.  
  3866.     level = userLevel;
  3867.  
  3868.     /* already power-of-two square */
  3869.     if (width == newwidth && height == newheight) {
  3870.         /* Use usersImage for level userLevel */
  3871.         if (baseLevel <= level && level <= maxLevel) {
  3872.         glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3873.         glTexImage2D(target, level, internalFormat, width,
  3874.                 height, 0, format, type,
  3875.                 usersImage);
  3876.         }
  3877.         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  3878.         if(levels == 0) { /* we're done. clean up and return */
  3879.           glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  3880.           glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  3881.           glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  3882.           glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3883.           glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  3884.           return 0;
  3885.         }
  3886.         {
  3887.            int nextWidth= newwidth/2;
  3888.            int nextHeight= newheight/2;
  3889.  
  3890.            /* clamp to 1 */
  3891.            if (nextWidth < 1) nextWidth= 1;
  3892.            if (nextHeight < 1) nextHeight= 1;
  3893.         memreq = image_size(nextWidth, nextHeight, format, type);
  3894.         }
  3895.  
  3896.         switch(type) {
  3897.         case GL_UNSIGNED_BYTE:
  3898.           dstImage = (GLubyte *)malloc(memreq);
  3899.           break;
  3900.         case GL_BYTE:
  3901.           dstImage = (GLbyte *)malloc(memreq);
  3902.           break;
  3903.         case GL_UNSIGNED_SHORT:
  3904.           dstImage = (GLushort *)malloc(memreq);
  3905.           break;
  3906.         case GL_SHORT:
  3907.           dstImage = (GLshort *)malloc(memreq);
  3908.           break;
  3909.         case GL_UNSIGNED_INT:
  3910.           dstImage = (GLuint *)malloc(memreq);
  3911.           break;
  3912.         case GL_INT:
  3913.           dstImage = (GLint *)malloc(memreq);
  3914.           break;
  3915.         case GL_FLOAT:
  3916.           dstImage = (GLfloat *)malloc(memreq);
  3917.           break;
  3918.         case GL_UNSIGNED_BYTE_3_3_2:
  3919.         case GL_UNSIGNED_BYTE_2_3_3_REV:
  3920.           dstImage = (GLubyte *)malloc(memreq);
  3921.           break;
  3922.         case GL_UNSIGNED_SHORT_5_6_5:
  3923.         case GL_UNSIGNED_SHORT_5_6_5_REV:
  3924.         case GL_UNSIGNED_SHORT_4_4_4_4:
  3925.         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  3926.         case GL_UNSIGNED_SHORT_5_5_5_1:
  3927.         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  3928.           dstImage = (GLushort *)malloc(memreq);
  3929.           break;
  3930.         case GL_UNSIGNED_INT_8_8_8_8:
  3931.         case GL_UNSIGNED_INT_8_8_8_8_REV:
  3932.         case GL_UNSIGNED_INT_10_10_10_2:
  3933.         case GL_UNSIGNED_INT_2_10_10_10_REV:
  3934.           dstImage = (GLuint *)malloc(memreq);  
  3935.           break;
  3936.         default:
  3937.           return GLU_INVALID_ENUM;
  3938.         }
  3939.         if (dstImage == NULL) {
  3940.           glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  3941.           glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  3942.           glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  3943.           glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  3944.           glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  3945.           return GLU_OUT_OF_MEMORY;
  3946.         }
  3947.         else
  3948.           switch(type) {
  3949.           case GL_UNSIGNED_BYTE:
  3950.             halveImage_ubyte(cmpts, width, height,
  3951.                              (const GLubyte *)usersImage, (GLubyte *)dstImage,
  3952.                              element_size, rowsize, group_size);
  3953.             break;
  3954.           case GL_BYTE:
  3955.             halveImage_byte(cmpts, width, height,
  3956.                             (const GLbyte *)usersImage, (GLbyte *)dstImage,
  3957.                             element_size, rowsize, group_size);
  3958.             break;
  3959.           case GL_UNSIGNED_SHORT:
  3960.             halveImage_ushort(cmpts, width, height,
  3961.                               (const GLushort *)usersImage, (GLushort *)dstImage,
  3962.                               element_size, rowsize, group_size, myswap_bytes);
  3963.             break;
  3964.           case GL_SHORT:
  3965.             halveImage_short(cmpts, width, height,
  3966.                              (const GLshort *)usersImage, (GLshort *)dstImage,
  3967.                              element_size, rowsize, group_size, myswap_bytes);
  3968.             break;
  3969.           case GL_UNSIGNED_INT:
  3970.             halveImage_uint(cmpts, width, height,
  3971.                             (const GLuint *)usersImage, (GLuint *)dstImage,
  3972.                             element_size, rowsize, group_size, myswap_bytes);
  3973.             break;
  3974.           case GL_INT:
  3975.             halveImage_int(cmpts, width, height,
  3976.                            (const GLint *)usersImage, (GLint *)dstImage,
  3977.                            element_size, rowsize, group_size, myswap_bytes);
  3978.             break;
  3979.           case GL_FLOAT:
  3980.             halveImage_float(cmpts, width, height,
  3981.                              (const GLfloat *)usersImage, (GLfloat *)dstImage,
  3982.                              element_size, rowsize, group_size, myswap_bytes);
  3983.             break;
  3984.           case GL_UNSIGNED_BYTE_3_3_2:
  3985.             assert(format == GL_RGB);
  3986.             halveImagePackedPixel(3,extract332,shove332,
  3987.                                   width,height,usersImage,dstImage,
  3988.                                   element_size,rowsize,myswap_bytes);
  3989.             break;
  3990.           case GL_UNSIGNED_BYTE_2_3_3_REV:
  3991.             assert(format == GL_RGB);
  3992.             halveImagePackedPixel(3,extract233rev,shove233rev,
  3993.                                   width,height,usersImage,dstImage,
  3994.                                   element_size,rowsize,myswap_bytes);
  3995.             break;
  3996.           case GL_UNSIGNED_SHORT_5_6_5:
  3997.             halveImagePackedPixel(3,extract565,shove565,
  3998.                                   width,height,usersImage,dstImage,
  3999.                                   element_size,rowsize,myswap_bytes);
  4000.             break;
  4001.           case GL_UNSIGNED_SHORT_5_6_5_REV:
  4002.             halveImagePackedPixel(3,extract565rev,shove565rev,
  4003.                                   width,height,usersImage,dstImage,
  4004.                                   element_size,rowsize,myswap_bytes);
  4005.             break;
  4006.           case GL_UNSIGNED_SHORT_4_4_4_4:
  4007.             halveImagePackedPixel(4,extract4444,shove4444,
  4008.                                   width,height,usersImage,dstImage,
  4009.                                   element_size,rowsize,myswap_bytes);
  4010.             break;
  4011.           case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4012.             halveImagePackedPixel(4,extract4444rev,shove4444rev,
  4013.                                   width,height,usersImage,dstImage,
  4014.                                   element_size,rowsize,myswap_bytes);
  4015.             break;
  4016.           case GL_UNSIGNED_SHORT_5_5_5_1:
  4017.             halveImagePackedPixel(4,extract5551,shove5551,
  4018.                                   width,height,usersImage,dstImage,
  4019.                                   element_size,rowsize,myswap_bytes);
  4020.             break;
  4021.           case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  4022.             halveImagePackedPixel(4,extract1555rev,shove1555rev,
  4023.                                   width,height,usersImage,dstImage,
  4024.                                   element_size,rowsize,myswap_bytes);
  4025.             break;
  4026.           case GL_UNSIGNED_INT_8_8_8_8:
  4027.             halveImagePackedPixel(4,extract8888,shove8888,
  4028.                                   width,height,usersImage,dstImage,
  4029.                                   element_size,rowsize,myswap_bytes);
  4030.             break;
  4031.           case GL_UNSIGNED_INT_8_8_8_8_REV:
  4032.             halveImagePackedPixel(4,extract8888rev,shove8888rev,
  4033.                                   width,height,usersImage,dstImage,
  4034.                                   element_size,rowsize,myswap_bytes);
  4035.             break;
  4036.           case GL_UNSIGNED_INT_10_10_10_2:
  4037.             halveImagePackedPixel(4,extract1010102,shove1010102,
  4038.                                   width,height,usersImage,dstImage,
  4039.                                   element_size,rowsize,myswap_bytes);
  4040.             break;
  4041.           case GL_UNSIGNED_INT_2_10_10_10_REV:
  4042.             halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
  4043.                                   width,height,usersImage,dstImage,
  4044.                                   element_size,rowsize,myswap_bytes);
  4045.             break;
  4046.           default:
  4047.             assert(0);
  4048.             break;
  4049.           }
  4050.         newwidth = width/2;
  4051.         newheight = height/2;
  4052.         /* clamp to 1 */
  4053.         if (newwidth < 1) newwidth= 1;
  4054.         if (newheight < 1) newheight= 1;
  4055.  
  4056.         myswap_bytes = 0;
  4057.         rowsize = newwidth * group_size;
  4058.         memreq = image_size(newwidth, newheight, format, type);
  4059.         /* Swap srcImage and dstImage */
  4060.         __GLU_SWAP_IMAGE(srcImage,dstImage);
  4061.         switch(type) {
  4062.         case GL_UNSIGNED_BYTE:
  4063.           dstImage = (GLubyte *)malloc(memreq);
  4064.           break;
  4065.         case GL_BYTE:
  4066.           dstImage = (GLbyte *)malloc(memreq);
  4067.           break;
  4068.         case GL_UNSIGNED_SHORT:
  4069.           dstImage = (GLushort *)malloc(memreq);
  4070.           break;
  4071.         case GL_SHORT:
  4072.           dstImage = (GLshort *)malloc(memreq);
  4073.           break;
  4074.         case GL_UNSIGNED_INT:
  4075.           dstImage = (GLuint *)malloc(memreq);
  4076.           break;
  4077.         case GL_INT:
  4078.           dstImage = (GLint *)malloc(memreq);
  4079.           break;
  4080.         case GL_FLOAT:
  4081.           dstImage = (GLfloat *)malloc(memreq);
  4082.           break;
  4083.         case GL_UNSIGNED_BYTE_3_3_2:
  4084.         case GL_UNSIGNED_BYTE_2_3_3_REV:
  4085.           dstImage = (GLubyte *)malloc(memreq);
  4086.           break;
  4087.         case GL_UNSIGNED_SHORT_5_6_5:
  4088.         case GL_UNSIGNED_SHORT_5_6_5_REV:
  4089.         case GL_UNSIGNED_SHORT_4_4_4_4:
  4090.         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4091.         case GL_UNSIGNED_SHORT_5_5_5_1:
  4092.         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  4093.           dstImage = (GLushort *)malloc(memreq);
  4094.           break;
  4095.         case GL_UNSIGNED_INT_8_8_8_8:
  4096.         case GL_UNSIGNED_INT_8_8_8_8_REV:
  4097.         case GL_UNSIGNED_INT_10_10_10_2:
  4098.         case GL_UNSIGNED_INT_2_10_10_10_REV:
  4099.           dstImage = (GLuint *)malloc(memreq);
  4100.           break;
  4101.         default:
  4102.           return GLU_INVALID_ENUM;
  4103.         }
  4104.         if (dstImage == NULL) {
  4105.           glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  4106.           glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  4107.           glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  4108.           glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  4109.           glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  4110.           free(srcImage);
  4111.           return GLU_OUT_OF_MEMORY;
  4112.         }
  4113.         /* level userLevel+1 is in srcImage; level userLevel already saved */
  4114.         level = userLevel+1;
  4115.     } else { /* user's image is *not* nice power-of-2 sized square */
  4116.         memreq = image_size(newwidth, newheight, format, type);
  4117.         switch(type) {
  4118.             case GL_UNSIGNED_BYTE:
  4119.                 dstImage = (GLubyte *)malloc(memreq);
  4120.                 break;
  4121.             case GL_BYTE:
  4122.                 dstImage = (GLbyte *)malloc(memreq);
  4123.                 break;
  4124.             case GL_UNSIGNED_SHORT:
  4125.                 dstImage = (GLushort *)malloc(memreq);
  4126.                 break;
  4127.             case GL_SHORT:
  4128.                 dstImage = (GLshort *)malloc(memreq);
  4129.                 break;
  4130.             case GL_UNSIGNED_INT:
  4131.                 dstImage = (GLuint *)malloc(memreq);
  4132.                 break;
  4133.             case GL_INT:
  4134.                 dstImage = (GLint *)malloc(memreq);
  4135.                 break;
  4136.             case GL_FLOAT:
  4137.                 dstImage = (GLfloat *)malloc(memreq);
  4138.                 break;
  4139.             case GL_UNSIGNED_BYTE_3_3_2:
  4140.             case GL_UNSIGNED_BYTE_2_3_3_REV:
  4141.                 dstImage = (GLubyte *)malloc(memreq);
  4142.                 break;
  4143.             case GL_UNSIGNED_SHORT_5_6_5:
  4144.             case GL_UNSIGNED_SHORT_5_6_5_REV:
  4145.             case GL_UNSIGNED_SHORT_4_4_4_4:
  4146.             case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4147.             case GL_UNSIGNED_SHORT_5_5_5_1:
  4148.             case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  4149.                 dstImage = (GLushort *)malloc(memreq);
  4150.                 break;
  4151.             case GL_UNSIGNED_INT_8_8_8_8:
  4152.             case GL_UNSIGNED_INT_8_8_8_8_REV:
  4153.             case GL_UNSIGNED_INT_10_10_10_2:
  4154.             case GL_UNSIGNED_INT_2_10_10_10_REV:
  4155.                 dstImage = (GLuint *)malloc(memreq);
  4156.                 break;
  4157.             default:
  4158.                 return GLU_INVALID_ENUM;
  4159.         }
  4160.  
  4161.         if (dstImage == NULL) {
  4162.             glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  4163.             glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  4164.             glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  4165.             glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  4166.             glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  4167.             return GLU_OUT_OF_MEMORY;
  4168.         }
  4169.  
  4170.         switch(type) {
  4171.         case GL_UNSIGNED_BYTE:
  4172.             scale_internal_ubyte(cmpts, width, height,
  4173.                                  (const GLubyte *)usersImage, newwidth, newheight,
  4174.                                  (GLubyte *)dstImage, element_size,
  4175.                                  rowsize, group_size);
  4176.             break;
  4177.         case GL_BYTE:
  4178.             scale_internal_byte(cmpts, width, height,
  4179.                                 (const GLbyte *)usersImage, newwidth, newheight,
  4180.                                 (GLbyte *)dstImage, element_size,
  4181.                                 rowsize, group_size);
  4182.             break;
  4183.         case GL_UNSIGNED_SHORT:
  4184.             scale_internal_ushort(cmpts, width, height,
  4185.                                   (const GLushort *)usersImage, newwidth, newheight,
  4186.                                   (GLushort *)dstImage, element_size,
  4187.                                   rowsize, group_size, myswap_bytes);
  4188.             break;
  4189.         case GL_SHORT:
  4190.             scale_internal_short(cmpts, width, height,
  4191.                                  (const GLshort *)usersImage, newwidth, newheight,
  4192.                                  (GLshort *)dstImage, element_size,
  4193.                                  rowsize, group_size, myswap_bytes);
  4194.             break;
  4195.         case GL_UNSIGNED_INT:
  4196.             scale_internal_uint(cmpts, width, height,
  4197.                                 (const GLuint *)usersImage, newwidth, newheight,
  4198.                                 (GLuint *)dstImage, element_size,
  4199.                                 rowsize, group_size, myswap_bytes);
  4200.             break;
  4201.         case GL_INT:
  4202.             scale_internal_int(cmpts, width, height,
  4203.                                (const GLint *)usersImage, newwidth, newheight,
  4204.                                (GLint *)dstImage, element_size,
  4205.                                rowsize, group_size, myswap_bytes);
  4206.             break;
  4207.         case GL_FLOAT:
  4208.             scale_internal_float(cmpts, width, height,
  4209.                                  (const GLfloat *)usersImage, newwidth, newheight,
  4210.                                  (GLfloat *)dstImage, element_size,
  4211.                                  rowsize, group_size, myswap_bytes);
  4212.             break;
  4213.         case GL_UNSIGNED_BYTE_3_3_2:
  4214.             scaleInternalPackedPixel(3,extract332,shove332,
  4215.                                      width, height,usersImage,
  4216.                                      newwidth,newheight,(void *)dstImage,
  4217.                                      element_size,rowsize,myswap_bytes);
  4218.             break;
  4219.         case GL_UNSIGNED_BYTE_2_3_3_REV:
  4220.             scaleInternalPackedPixel(3,extract233rev,shove233rev,
  4221.                                      width, height,usersImage,
  4222.                                      newwidth,newheight,(void *)dstImage,
  4223.                                      element_size,rowsize,myswap_bytes);
  4224.             break;
  4225.         case GL_UNSIGNED_SHORT_5_6_5:
  4226.             scaleInternalPackedPixel(3,extract565,shove565,
  4227.                                      width, height,usersImage,
  4228.                                      newwidth,newheight,(void *)dstImage,
  4229.                                      element_size,rowsize,myswap_bytes);
  4230.             break;
  4231.         case GL_UNSIGNED_SHORT_5_6_5_REV:
  4232.             scaleInternalPackedPixel(3,extract565rev,shove565rev,
  4233.                                      width, height,usersImage,
  4234.                                      newwidth,newheight,(void *)dstImage,
  4235.                                      element_size,rowsize,myswap_bytes);
  4236.             break;
  4237.         case GL_UNSIGNED_SHORT_4_4_4_4:
  4238.             scaleInternalPackedPixel(4,extract4444,shove4444,
  4239.                                      width, height,usersImage,
  4240.                                      newwidth,newheight,(void *)dstImage,
  4241.                                      element_size,rowsize,myswap_bytes);
  4242.             break;
  4243.         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4244.             scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
  4245.                                      width, height,usersImage,
  4246.                                      newwidth,newheight,(void *)dstImage,
  4247.                                      element_size,rowsize,myswap_bytes);
  4248.             break;
  4249.         case GL_UNSIGNED_SHORT_5_5_5_1:
  4250.             scaleInternalPackedPixel(4,extract5551,shove5551,
  4251.                                      width, height,usersImage,
  4252.                                      newwidth,newheight,(void *)dstImage,
  4253.                                      element_size,rowsize,myswap_bytes);
  4254.             break;
  4255.         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  4256.             scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
  4257.                                      width, height,usersImage,
  4258.                                      newwidth,newheight,(void *)dstImage,
  4259.                                      element_size,rowsize,myswap_bytes);
  4260.             break;
  4261.         case GL_UNSIGNED_INT_8_8_8_8:
  4262.             scaleInternalPackedPixel(4,extract8888,shove8888,
  4263.                                      width, height,usersImage,
  4264.                                      newwidth,newheight,(void *)dstImage,
  4265.                                      element_size,rowsize,myswap_bytes);
  4266.             break;
  4267.         case GL_UNSIGNED_INT_8_8_8_8_REV:
  4268.             scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
  4269.                                      width, height,usersImage,
  4270.                                      newwidth,newheight,(void *)dstImage,
  4271.                                      element_size,rowsize,myswap_bytes);
  4272.             break;
  4273.         case GL_UNSIGNED_INT_10_10_10_2:
  4274.             scaleInternalPackedPixel(4,extract1010102,shove1010102,
  4275.                                      width, height,usersImage,
  4276.                                      newwidth,newheight,(void *)dstImage,
  4277.                                      element_size,rowsize,myswap_bytes);
  4278.             break;
  4279.         case GL_UNSIGNED_INT_2_10_10_10_REV:
  4280.             scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
  4281.                                      width, height,usersImage,
  4282.                                      newwidth,newheight,(void *)dstImage,
  4283.                                      element_size,rowsize,myswap_bytes);
  4284.             break;
  4285.         default:
  4286.             assert(0);
  4287.             break;
  4288.         }
  4289.         myswap_bytes = 0;
  4290.         rowsize = newwidth * group_size;
  4291.         /* Swap dstImage and srcImage */
  4292.         __GLU_SWAP_IMAGE(srcImage,dstImage);
  4293.  
  4294.         if(levels != 0) { /* use as little memory as possible */
  4295.           {
  4296.              int nextWidth= newwidth/2;
  4297.              int nextHeight= newheight/2;
  4298.              if (nextWidth < 1) nextWidth= 1;
  4299.              if (nextHeight < 1) nextHeight= 1;
  4300.  
  4301.           memreq = image_size(nextWidth, nextHeight, format, type);
  4302.           }
  4303.  
  4304.           switch(type) {
  4305.           case GL_UNSIGNED_BYTE:
  4306.             dstImage = (GLubyte *)malloc(memreq);
  4307.             break;
  4308.           case GL_BYTE:
  4309.             dstImage = (GLbyte *)malloc(memreq);
  4310.             break;
  4311.           case GL_UNSIGNED_SHORT:
  4312.             dstImage = (GLushort *)malloc(memreq);
  4313.             break;
  4314.           case GL_SHORT:
  4315.             dstImage = (GLshort *)malloc(memreq);
  4316.             break;
  4317.           case GL_UNSIGNED_INT:
  4318.             dstImage = (GLuint *)malloc(memreq);
  4319.             break;
  4320.           case GL_INT:
  4321.             dstImage = (GLint *)malloc(memreq);
  4322.             break;
  4323.           case GL_FLOAT:
  4324.             dstImage = (GLfloat *)malloc(memreq);
  4325.             break;
  4326.           case GL_UNSIGNED_BYTE_3_3_2:
  4327.           case GL_UNSIGNED_BYTE_2_3_3_REV:
  4328.             dstImage = (GLubyte *)malloc(memreq);
  4329.             break;
  4330.           case GL_UNSIGNED_SHORT_5_6_5:
  4331.           case GL_UNSIGNED_SHORT_5_6_5_REV:
  4332.           case GL_UNSIGNED_SHORT_4_4_4_4:
  4333.           case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4334.           case GL_UNSIGNED_SHORT_5_5_5_1:
  4335.           case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  4336.             dstImage = (GLushort *)malloc(memreq);
  4337.             break;
  4338.           case GL_UNSIGNED_INT_8_8_8_8:
  4339.           case GL_UNSIGNED_INT_8_8_8_8_REV:
  4340.           case GL_UNSIGNED_INT_10_10_10_2:
  4341.           case GL_UNSIGNED_INT_2_10_10_10_REV:
  4342.             dstImage = (GLuint *)malloc(memreq);
  4343.             break;
  4344.           default:
  4345.             return GLU_INVALID_ENUM;
  4346.           }
  4347.           if (dstImage == NULL) {
  4348.             glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  4349.             glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  4350.             glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  4351.             glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  4352.             glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  4353.             free(srcImage);
  4354.             return GLU_OUT_OF_MEMORY;
  4355.           }
  4356.         }
  4357.         /* level userLevel is in srcImage; nothing saved yet */
  4358.         level = userLevel;
  4359.     }
  4360.  
  4361.     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  4362.     if (baseLevel <= level && level <= maxLevel) {
  4363.     glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
  4364.                  format, type, (void *)srcImage);
  4365.     }
  4366.  
  4367.     level++; /* update current level for the loop */
  4368.     for (; level <= levels; level++) {
  4369.         switch(type) {
  4370.             case GL_UNSIGNED_BYTE:
  4371.                 halveImage_ubyte(cmpts, newwidth, newheight,
  4372.                 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
  4373.                 rowsize, group_size);
  4374.                 break;
  4375.             case GL_BYTE:
  4376.                 halveImage_byte(cmpts, newwidth, newheight,
  4377.                 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
  4378.                 rowsize, group_size);
  4379.                 break;
  4380.             case GL_UNSIGNED_SHORT:
  4381.                 halveImage_ushort(cmpts, newwidth, newheight,
  4382.                 (GLushort *)srcImage, (GLushort *)dstImage, element_size,
  4383.                 rowsize, group_size, myswap_bytes);
  4384.                 break;
  4385.             case GL_SHORT:
  4386.                 halveImage_short(cmpts, newwidth, newheight,
  4387.                 (GLshort *)srcImage, (GLshort *)dstImage, element_size,
  4388.                 rowsize, group_size, myswap_bytes);
  4389.                 break;
  4390.             case GL_UNSIGNED_INT:
  4391.                 halveImage_uint(cmpts, newwidth, newheight,
  4392.                 (GLuint *)srcImage, (GLuint *)dstImage, element_size,
  4393.                 rowsize, group_size, myswap_bytes);
  4394.                 break;
  4395.             case GL_INT:
  4396.                 halveImage_int(cmpts, newwidth, newheight,
  4397.                 (GLint *)srcImage, (GLint *)dstImage, element_size,
  4398.                 rowsize, group_size, myswap_bytes);
  4399.                 break;
  4400.             case GL_FLOAT:
  4401.                 halveImage_float(cmpts, newwidth, newheight,
  4402.                 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
  4403.                 rowsize, group_size, myswap_bytes);
  4404.                 break;
  4405.             case GL_UNSIGNED_BYTE_3_3_2:
  4406.                 halveImagePackedPixel(3,extract332,shove332,
  4407.                                       newwidth,newheight,
  4408.                                       srcImage,dstImage,element_size,rowsize,
  4409.                                       myswap_bytes);
  4410.                 break;
  4411.             case GL_UNSIGNED_BYTE_2_3_3_REV:
  4412.                 halveImagePackedPixel(3,extract233rev,shove233rev,
  4413.                                       newwidth,newheight,
  4414.                                       srcImage,dstImage,element_size,rowsize,
  4415.                                       myswap_bytes);
  4416.                 break;
  4417.             case GL_UNSIGNED_SHORT_5_6_5:
  4418.                 halveImagePackedPixel(3,extract565,shove565,
  4419.                                       newwidth,newheight,
  4420.                                       srcImage,dstImage,element_size,rowsize,
  4421.                                       myswap_bytes);
  4422.                 break;
  4423.             case GL_UNSIGNED_SHORT_5_6_5_REV:
  4424.                 halveImagePackedPixel(3,extract565rev,shove565rev,
  4425.                                       newwidth,newheight,
  4426.                                       srcImage,dstImage,element_size,rowsize,
  4427.                                       myswap_bytes);
  4428.                 break;
  4429.             case GL_UNSIGNED_SHORT_4_4_4_4:
  4430.                 halveImagePackedPixel(4,extract4444,shove4444,
  4431.                                       newwidth,newheight,
  4432.                                       srcImage,dstImage,element_size,rowsize,
  4433.                                       myswap_bytes);
  4434.                 break;
  4435.             case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4436.                 halveImagePackedPixel(4,extract4444rev,shove4444rev,
  4437.                                       newwidth,newheight,
  4438.                                       srcImage,dstImage,element_size,rowsize,
  4439.                                       myswap_bytes);
  4440.                 break;
  4441.             case GL_UNSIGNED_SHORT_5_5_5_1:            
  4442.                 halveImagePackedPixel(4,extract5551,shove5551,
  4443.                                       newwidth,newheight,
  4444.                                       srcImage,dstImage,element_size,rowsize,
  4445.                                       myswap_bytes);
  4446.                 break;
  4447.             case GL_UNSIGNED_SHORT_1_5_5_5_REV:                
  4448.                 halveImagePackedPixel(4,extract1555rev,shove1555rev,
  4449.                                       newwidth,newheight,
  4450.                                       srcImage,dstImage,element_size,rowsize,
  4451.                                       myswap_bytes);
  4452.                 break;
  4453.             case GL_UNSIGNED_INT_8_8_8_8:
  4454.                 halveImagePackedPixel(4,extract8888,shove8888,
  4455.                                       newwidth,newheight,
  4456.                                       srcImage,dstImage,element_size,rowsize,
  4457.                                       myswap_bytes);
  4458.                 break;
  4459.             case GL_UNSIGNED_INT_8_8_8_8_REV:
  4460.                 halveImagePackedPixel(4,extract8888rev,shove8888rev,
  4461.                                       newwidth,newheight,
  4462.                                       srcImage,dstImage,element_size,rowsize,
  4463.                                       myswap_bytes);
  4464.                 break;
  4465.             case GL_UNSIGNED_INT_10_10_10_2:
  4466.                 halveImagePackedPixel(4,extract1010102,shove1010102,
  4467.                                       newwidth,newheight,
  4468.                                       srcImage,dstImage,element_size,rowsize,
  4469.                                       myswap_bytes);
  4470.                 break;
  4471.             case GL_UNSIGNED_INT_2_10_10_10_REV:
  4472.                 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
  4473.                                       newwidth,newheight,
  4474.                                       srcImage,dstImage,element_size,rowsize,
  4475.                                       myswap_bytes);
  4476.                 break;
  4477.             default:
  4478.                 assert(0);
  4479.                 break;
  4480.         }
  4481.  
  4482.         __GLU_SWAP_IMAGE(srcImage,dstImage);
  4483.  
  4484.         if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
  4485.         if (newheight > 1) newheight /= 2;
  4486.       {
  4487.        /* compute amount to pad per row, if any */
  4488.        int rowPad= rowsize % psm.unpack_alignment;
  4489.  
  4490.        /* should row be padded? */
  4491.        if (rowPad == 0) {       /* nope, row should not be padded */
  4492.            /* call tex image with srcImage untouched since it's not padded */
  4493.            if (baseLevel <= level && level <= maxLevel) {
  4494.            glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
  4495.            format, type, (void *) srcImage);
  4496.            }
  4497.        }
  4498.        else {                   /* yes, row should be padded */
  4499.           /* compute length of new row in bytes, including padding */
  4500.           int newRowLength= rowsize + psm.unpack_alignment - rowPad;
  4501.           int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
  4502.  
  4503.           /* allocate new image for mipmap of size newRowLength x newheight */
  4504.           void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
  4505.           if (newMipmapImage == NULL) {
  4506.              /* out of memory so return */
  4507.              glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  4508.              glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  4509.              glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  4510.              glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  4511.              glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  4512.              return GLU_OUT_OF_MEMORY;
  4513.           }
  4514.  
  4515.           /* copy image from srcImage into newMipmapImage by rows */
  4516.           for (ii= 0,
  4517.                dstTrav= (unsigned char *) newMipmapImage,
  4518.                srcTrav= (unsigned char *) srcImage;
  4519.                ii< newheight;
  4520.                ii++,
  4521.                dstTrav+= newRowLength, /* make sure the correct distance... */
  4522.                srcTrav+= rowsize) {    /* ...is skipped */
  4523.              memcpy(dstTrav,srcTrav,rowsize);
  4524.              /* note that the pad bytes are not visited and will contain
  4525.               * garbage, which is ok.
  4526.               */
  4527.           }
  4528.  
  4529.           /* ...and use this new image for mipmapping instead */
  4530.           if (baseLevel <= level && level <= maxLevel) {
  4531.           glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
  4532.                        format, type, newMipmapImage);
  4533.           }
  4534.           free(newMipmapImage); /* don't forget to free it! */
  4535.        } /* else */
  4536.       }
  4537.     } /* for level */
  4538.     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  4539.     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  4540.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  4541.     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  4542.     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  4543.  
  4544.     free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
  4545.     if (dstImage) { /* if it's non-rectangular and only 1 level */
  4546.       free(dstImage);
  4547.     }
  4548.     return 0;
  4549. } /* gluBuild2DMipmapLevelsCore() */
  4550.  
  4551. GLint GLAPIENTRY
  4552. gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
  4553.                              GLsizei width, GLsizei height,
  4554.                              GLenum format, GLenum type,
  4555.                              GLint userLevel, GLint baseLevel, GLint maxLevel,
  4556.                              const void *data)
  4557. {
  4558.    int level, levels;
  4559.  
  4560.    int rc= checkMipmapArgs(internalFormat,format,type);
  4561.    if (rc != 0) return rc;
  4562.  
  4563.    if (width < 1 || height < 1) {
  4564.        return GLU_INVALID_VALUE;
  4565.    }
  4566.  
  4567.    levels = computeLog(width);
  4568.    level = computeLog(height);
  4569.    if (level > levels) levels=level;
  4570.  
  4571.    levels+= userLevel;
  4572.    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
  4573.       return GLU_INVALID_VALUE;
  4574.  
  4575.    return gluBuild2DMipmapLevelsCore(target, internalFormat,
  4576.                                      width, height,
  4577.                                      width, height,
  4578.                                      format, type,
  4579.                                      userLevel, baseLevel, maxLevel,
  4580.                                      data);
  4581. } /* gluBuild2DMipmapLevels() */
  4582.  
  4583. GLint GLAPIENTRY
  4584. gluBuild2DMipmaps(GLenum target, GLint internalFormat,
  4585.                         GLsizei width, GLsizei height,
  4586.                         GLenum format, GLenum type,
  4587.                         const void *data)
  4588. {
  4589.    GLint widthPowerOf2, heightPowerOf2;
  4590.    int level, levels;
  4591.  
  4592.    int rc= checkMipmapArgs(internalFormat,format,type);
  4593.    if (rc != 0) return rc;
  4594.  
  4595.    if (width < 1 || height < 1) {
  4596.        return GLU_INVALID_VALUE;
  4597.    }
  4598.  
  4599.    closestFit(target,width,height,internalFormat,format,type,
  4600.               &widthPowerOf2,&heightPowerOf2);
  4601.  
  4602.    levels = computeLog(widthPowerOf2);
  4603.    level = computeLog(heightPowerOf2);
  4604.    if (level > levels) levels=level;
  4605.  
  4606.    return gluBuild2DMipmapLevelsCore(target,internalFormat,
  4607.                                      width, height,
  4608.                                      widthPowerOf2,heightPowerOf2,
  4609.                                      format,type,
  4610.                                      0,0,levels,data);
  4611. }  /* gluBuild2DMipmaps() */
  4612.  
  4613. #if 0
  4614. /*
  4615. ** This routine is for the limited case in which
  4616. **      type == GL_UNSIGNED_BYTE && format != index  &&
  4617. **      unpack_alignment = 1 && unpack_swap_bytes == false
  4618. **
  4619. ** so all of the work data can be kept as ubytes instead of shorts.
  4620. */
  4621. static int fastBuild2DMipmaps(const PixelStorageModes *psm,
  4622.                        GLenum target, GLint components, GLint width,
  4623.                      GLint height, GLenum format,
  4624.                      GLenum type, void *data)
  4625. {
  4626.     GLint newwidth, newheight;
  4627.     GLint level, levels;
  4628.     GLubyte *newImage;
  4629.     GLint newImage_width;
  4630.     GLint newImage_height;
  4631.     GLubyte *otherImage;
  4632.     GLubyte *imageTemp;
  4633.     GLint memreq;
  4634.     GLint cmpts;
  4635.  
  4636.  
  4637. #if 0
  4638.     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
  4639.     newwidth = nearestPower(width);
  4640.     if (newwidth > maxsize) newwidth = maxsize;
  4641.     newheight = nearestPower(height);
  4642.     if (newheight > maxsize) newheight = maxsize;
  4643. #else
  4644.     closestFit(target,width,height,components,format,type,
  4645.                &newwidth,&newheight);
  4646. #endif
  4647.     levels = computeLog(newwidth);
  4648.     level = computeLog(newheight);
  4649.     if (level > levels) levels=level;
  4650.  
  4651.     cmpts = elements_per_group(format,type);
  4652.  
  4653.     otherImage = NULL;
  4654.     /**
  4655.     ** No need to copy the user data if its in the packed correctly.
  4656.     ** Make sure that later routines don't change that data.
  4657.     */
  4658.     if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
  4659.         newImage = (GLubyte *)data;
  4660.         newImage_width = width;
  4661.         newImage_height = height;
  4662.     } else {
  4663.         GLint rowsize;
  4664.         GLint groups_per_line;
  4665.         GLint elements_per_line;
  4666.         const GLubyte *start;
  4667.         const GLubyte *iter;
  4668.         GLubyte *iter2;
  4669.         GLint i, j;
  4670.  
  4671.         newImage = (GLubyte *)
  4672.             malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
  4673.         newImage_width = width;
  4674.         newImage_height = height;
  4675.         if (newImage == NULL) {
  4676.             return GLU_OUT_OF_MEMORY;
  4677.         }
  4678.  
  4679.         /*
  4680.         ** Abbreviated version of fill_image for this restricted case.
  4681.         */
  4682.         if (psm->unpack_row_length > 0) {
  4683.             groups_per_line = psm->unpack_row_length;
  4684.         } else {
  4685.             groups_per_line = width;
  4686.         }
  4687.         rowsize = groups_per_line * cmpts;
  4688.         elements_per_line = width * cmpts;
  4689.         start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
  4690.                 psm->unpack_skip_pixels * cmpts;
  4691.         iter2 = newImage;
  4692.  
  4693.         for (i = 0; i < height; i++) {
  4694.             iter = start;
  4695.             for (j = 0; j < elements_per_line; j++) {
  4696.                 *iter2 = *iter;
  4697.                 iter++;
  4698.                 iter2++;
  4699.             }
  4700.             start += rowsize;
  4701.         }
  4702.     }
  4703.  
  4704.  
  4705.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  4706.     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  4707.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  4708.     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  4709.     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  4710.  
  4711.     for (level = 0; level <= levels; level++) {
  4712.         if (newImage_width == newwidth && newImage_height == newheight) {
  4713.             /* Use newImage for this level */
  4714.             glTexImage2D(target, level, components, newImage_width,
  4715.                     newImage_height, 0, format, GL_UNSIGNED_BYTE,
  4716.                     (void *) newImage);
  4717.         } else {
  4718.             if (otherImage == NULL) {
  4719.                 memreq =
  4720.                     image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
  4721.                 otherImage = (GLubyte *) malloc(memreq);
  4722.                 if (otherImage == NULL) {
  4723.                     glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
  4724.                     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
  4725.                     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
  4726.                     glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
  4727.                     glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
  4728.                     return GLU_OUT_OF_MEMORY;
  4729.                 }
  4730.             }
  4731. /*
  4732.             scale_internal_ubyte(cmpts, newImage_width, newImage_height,
  4733.                     newImage, newwidth, newheight, otherImage);
  4734. */
  4735.             /* Swap newImage and otherImage */
  4736.             imageTemp = otherImage;
  4737.             otherImage = newImage;
  4738.             newImage = imageTemp;
  4739.  
  4740.             newImage_width = newwidth;
  4741.             newImage_height = newheight;
  4742.             glTexImage2D(target, level, components, newImage_width,
  4743.                     newImage_height, 0, format, GL_UNSIGNED_BYTE,
  4744.                     (void *) newImage);
  4745.         }
  4746.         if (newwidth > 1) newwidth /= 2;
  4747.         if (newheight > 1) newheight /= 2;
  4748.     }
  4749.     glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
  4750.     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
  4751.     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
  4752.     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
  4753.     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
  4754.  
  4755.     if (newImage != (const GLubyte *)data) {
  4756.         free((GLbyte *) newImage);
  4757.     }
  4758.     if (otherImage && otherImage != (const GLubyte *)data) {
  4759.         free((GLbyte *) otherImage);
  4760.     }
  4761.     return 0;
  4762. }
  4763. #endif
  4764.  
  4765. /*
  4766.  * Utility Routines
  4767.  */
  4768. static GLint elements_per_group(GLenum format, GLenum type)
  4769. {
  4770.     /*
  4771.      * Return the number of elements per group of a specified format
  4772.      */
  4773.  
  4774.     /* If the type is packedpixels then answer is 1 (ignore format) */
  4775.     if (type == GL_UNSIGNED_BYTE_3_3_2 ||
  4776.         type == GL_UNSIGNED_BYTE_2_3_3_REV ||
  4777.         type == GL_UNSIGNED_SHORT_5_6_5 ||
  4778.         type == GL_UNSIGNED_SHORT_5_6_5_REV ||
  4779.         type == GL_UNSIGNED_SHORT_4_4_4_4 ||
  4780.         type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
  4781.         type == GL_UNSIGNED_SHORT_5_5_5_1  ||
  4782.         type == GL_UNSIGNED_SHORT_1_5_5_5_REV  ||
  4783.         type == GL_UNSIGNED_INT_8_8_8_8 ||
  4784.         type == GL_UNSIGNED_INT_8_8_8_8_REV ||
  4785.         type == GL_UNSIGNED_INT_10_10_10_2 ||
  4786.         type == GL_UNSIGNED_INT_2_10_10_10_REV) {
  4787.         return 1;
  4788.     }
  4789.  
  4790.     /* Types are not packed pixels, so get elements per group */
  4791.     switch(format) {
  4792.       case GL_RGB:
  4793.       case GL_BGR:
  4794.         return 3;
  4795.       case GL_LUMINANCE_ALPHA:
  4796.         return 2;
  4797.       case GL_RGBA:
  4798.       case GL_BGRA:
  4799.         return 4;
  4800.       default:
  4801.         return 1;
  4802.     }
  4803. }
  4804.  
  4805. static GLfloat bytes_per_element(GLenum type)
  4806. {
  4807.     /*
  4808.      * Return the number of bytes per element, based on the element type
  4809.      */
  4810.     switch(type) {
  4811.       case GL_BITMAP:
  4812.         return 1.0 / 8.0;
  4813.       case GL_UNSIGNED_SHORT:
  4814.         return(sizeof(GLushort));
  4815.       case GL_SHORT:
  4816.         return(sizeof(GLshort));
  4817.       case GL_UNSIGNED_BYTE:
  4818.         return(sizeof(GLubyte));
  4819.       case GL_BYTE:
  4820.         return(sizeof(GLbyte));
  4821.       case GL_INT:
  4822.         return(sizeof(GLint));
  4823.       case GL_UNSIGNED_INT:
  4824.         return(sizeof(GLuint));
  4825.       case GL_FLOAT:
  4826.         return(sizeof(GLfloat));
  4827.       case GL_UNSIGNED_BYTE_3_3_2:
  4828.       case GL_UNSIGNED_BYTE_2_3_3_REV:  
  4829.         return(sizeof(GLubyte));
  4830.       case GL_UNSIGNED_SHORT_5_6_5:
  4831.       case GL_UNSIGNED_SHORT_5_6_5_REV:
  4832.       case GL_UNSIGNED_SHORT_4_4_4_4:
  4833.       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  4834.       case GL_UNSIGNED_SHORT_5_5_5_1:
  4835.       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  4836.         return(sizeof(GLushort));
  4837.       case GL_UNSIGNED_INT_8_8_8_8:
  4838.       case GL_UNSIGNED_INT_8_8_8_8_REV:
  4839.       case GL_UNSIGNED_INT_10_10_10_2:
  4840.       case GL_UNSIGNED_INT_2_10_10_10_REV:
  4841.         return(sizeof(GLuint));
  4842.       default:
  4843.         return 4;
  4844.     }
  4845. }
  4846.  
  4847. static GLint is_index(GLenum format)
  4848. {
  4849.     return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
  4850. }
  4851.  
  4852. /*
  4853. ** Compute memory required for internal packed array of data of given type
  4854. ** and format.
  4855. */
  4856. static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
  4857. {
  4858.     int bytes_per_row;
  4859.     int components;
  4860.  
  4861. assert(width > 0);
  4862. assert(height > 0);
  4863.     components = elements_per_group(format,type);
  4864.     if (type == GL_BITMAP) {
  4865.         bytes_per_row = (width + 7) / 8;
  4866.     } else {
  4867.         bytes_per_row = bytes_per_element(type) * width;
  4868.     }
  4869.     return bytes_per_row * height * components;
  4870. }
  4871.  
  4872. /*
  4873. ** Extract array from user's data applying all pixel store modes.
  4874. ** The internal format used is an array of unsigned shorts.
  4875. */
  4876. static void fill_image(const PixelStorageModes *psm,
  4877.                        GLint width, GLint height, GLenum format,
  4878.                        GLenum type, GLboolean index_format,
  4879.                        const void *userdata, GLushort *newimage)
  4880. {
  4881.     GLint components;
  4882.     GLint element_size;
  4883.     GLint rowsize;
  4884.     GLint padding;
  4885.     GLint groups_per_line;
  4886.     GLint group_size;
  4887.     GLint elements_per_line;
  4888.     const GLubyte *start;
  4889.     const GLubyte *iter;
  4890.     GLushort *iter2;
  4891.     GLint i, j, k;
  4892.     GLint myswap_bytes;
  4893.  
  4894.     myswap_bytes = psm->unpack_swap_bytes;
  4895.     components = elements_per_group(format,type);
  4896.     if (psm->unpack_row_length > 0) {
  4897.         groups_per_line = psm->unpack_row_length;
  4898.     } else {
  4899.         groups_per_line = width;
  4900.     }
  4901.  
  4902.     /* All formats except GL_BITMAP fall out trivially */
  4903.     if (type == GL_BITMAP) {
  4904.         GLint bit_offset;
  4905.         GLint current_bit;
  4906.  
  4907.         rowsize = (groups_per_line * components + 7) / 8;
  4908.         padding = (rowsize % psm->unpack_alignment);
  4909.         if (padding) {
  4910.             rowsize += psm->unpack_alignment - padding;
  4911.         }
  4912.         start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
  4913.                 (psm->unpack_skip_pixels * components / 8);
  4914.         elements_per_line = width * components;
  4915.         iter2 = newimage;
  4916.         for (i = 0; i < height; i++) {
  4917.             iter = start;
  4918.             bit_offset = (psm->unpack_skip_pixels * components) % 8;
  4919.             for (j = 0; j < elements_per_line; j++) {
  4920.                 /* Retrieve bit */
  4921.                 if (psm->unpack_lsb_first) {
  4922.                     current_bit = iter[0] & (1 << bit_offset);
  4923.                 } else {
  4924.                     current_bit = iter[0] & (1 << (7 - bit_offset));
  4925.                 }
  4926.                 if (current_bit) {
  4927.                     if (index_format) {
  4928.                         *iter2 = 1;
  4929.                     } else {
  4930.                         *iter2 = 65535;
  4931.                     }
  4932.                 } else {
  4933.                     *iter2 = 0;
  4934.                 }
  4935.                 bit_offset++;
  4936.                 if (bit_offset == 8) {
  4937.                     bit_offset = 0;
  4938.                     iter++;
  4939.                 }
  4940.                 iter2++;
  4941.             }
  4942.             start += rowsize;
  4943.         }
  4944.     } else {
  4945.         element_size = bytes_per_element(type);
  4946.         group_size = element_size * components;
  4947.         if (element_size == 1) myswap_bytes = 0;
  4948.  
  4949.         rowsize = groups_per_line * group_size;
  4950.         padding = (rowsize % psm->unpack_alignment);
  4951.         if (padding) {
  4952.             rowsize += psm->unpack_alignment - padding;
  4953.         }
  4954.         start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
  4955.                 psm->unpack_skip_pixels * group_size;
  4956.         elements_per_line = width * components;
  4957.  
  4958.         iter2 = newimage;
  4959.         for (i = 0; i < height; i++) {
  4960.             iter = start;
  4961.             for (j = 0; j < elements_per_line; j++) {
  4962.                 Type_Widget widget;
  4963.                 float extractComponents[4];
  4964.  
  4965.                 switch(type) {
  4966.                   case GL_UNSIGNED_BYTE_3_3_2:
  4967.                     extract332(0,iter,extractComponents);
  4968.                     for (k = 0; k < 3; k++) {
  4969.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  4970.                     }
  4971.                     break;
  4972.                   case GL_UNSIGNED_BYTE_2_3_3_REV:
  4973.                     extract233rev(0,iter,extractComponents);
  4974.                     for (k = 0; k < 3; k++) {
  4975.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  4976.                     }
  4977.                     break;
  4978.                   case GL_UNSIGNED_BYTE:
  4979.                     if (index_format) {
  4980.                         *iter2++ = *iter;
  4981.                     } else {
  4982.                         *iter2++ = (*iter) * 257;
  4983.                     }
  4984.                     break;
  4985.                   case GL_BYTE:
  4986.                     if (index_format) {
  4987.                         *iter2++ = *((const GLbyte *) iter);
  4988.                     } else {
  4989.                         /* rough approx */
  4990.                         *iter2++ = (*((const GLbyte *) iter)) * 516;
  4991.                     }
  4992.                     break;
  4993.                   case GL_UNSIGNED_SHORT_5_6_5:                        
  4994.                     extract565(myswap_bytes,iter,extractComponents);
  4995.                     for (k = 0; k < 3; k++) {
  4996.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  4997.                     }
  4998.                     break;
  4999.                   case GL_UNSIGNED_SHORT_5_6_5_REV:                    
  5000.                     extract565rev(myswap_bytes,iter,extractComponents);
  5001.                     for (k = 0; k < 3; k++) {
  5002.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5003.                     }
  5004.                     break;
  5005.                   case GL_UNSIGNED_SHORT_4_4_4_4:              
  5006.                     extract4444(myswap_bytes,iter,extractComponents);
  5007.                     for (k = 0; k < 4; k++) {
  5008.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5009.                     }
  5010.                     break;
  5011.                   case GL_UNSIGNED_SHORT_4_4_4_4_REV:          
  5012.                     extract4444rev(myswap_bytes,iter,extractComponents);
  5013.                     for (k = 0; k < 4; k++) {
  5014.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5015.                     }
  5016.                     break;
  5017.                   case GL_UNSIGNED_SHORT_5_5_5_1:              
  5018.                     extract5551(myswap_bytes,iter,extractComponents);
  5019.                     for (k = 0; k < 4; k++) {
  5020.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5021.                     }
  5022.                     break;
  5023.                   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  5024.                     extract1555rev(myswap_bytes,iter,extractComponents);
  5025.                     for (k = 0; k < 4; k++) {
  5026.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5027.                     }
  5028.                     break;
  5029.                   case GL_UNSIGNED_SHORT:
  5030.                   case GL_SHORT:
  5031.                     if (myswap_bytes) {
  5032.                         widget.ub[0] = iter[1];
  5033.                         widget.ub[1] = iter[0];
  5034.                     } else {
  5035.                         widget.ub[0] = iter[0];
  5036.                         widget.ub[1] = iter[1];
  5037.                     }
  5038.                     if (type == GL_SHORT) {
  5039.                         if (index_format) {
  5040.                             *iter2++ = widget.s[0];
  5041.                         } else {
  5042.                             /* rough approx */
  5043.                             *iter2++ = widget.s[0]*2;
  5044.                         }
  5045.                     } else {
  5046.                         *iter2++ = widget.us[0];
  5047.                     }
  5048.                     break;
  5049.                   case GL_UNSIGNED_INT_8_8_8_8:        
  5050.                     extract8888(myswap_bytes,iter,extractComponents);
  5051.                     for (k = 0; k < 4; k++) {
  5052.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5053.                     }
  5054.                     break;
  5055.                   case GL_UNSIGNED_INT_8_8_8_8_REV:            
  5056.                     extract8888rev(myswap_bytes,iter,extractComponents);
  5057.                     for (k = 0; k < 4; k++) {
  5058.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5059.                     }
  5060.                     break;
  5061.                   case GL_UNSIGNED_INT_10_10_10_2:             
  5062.                     extract1010102(myswap_bytes,iter,extractComponents);
  5063.                     for (k = 0; k < 4; k++) {
  5064.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5065.                     }
  5066.                     break;
  5067.                   case GL_UNSIGNED_INT_2_10_10_10_REV:
  5068.                     extract2101010rev(myswap_bytes,iter,extractComponents);
  5069.                     for (k = 0; k < 4; k++) {
  5070.                       *iter2++ = (GLushort)(extractComponents[k]*65535);
  5071.                     }
  5072.                     break;
  5073.                   case GL_INT:
  5074.                   case GL_UNSIGNED_INT:
  5075.                   case GL_FLOAT:
  5076.                     if (myswap_bytes) {
  5077.                         widget.ub[0] = iter[3];
  5078.                         widget.ub[1] = iter[2];
  5079.                         widget.ub[2] = iter[1];
  5080.                         widget.ub[3] = iter[0];
  5081.                     } else {
  5082.                         widget.ub[0] = iter[0];
  5083.                         widget.ub[1] = iter[1];
  5084.                         widget.ub[2] = iter[2];
  5085.                         widget.ub[3] = iter[3];
  5086.                     }
  5087.                     if (type == GL_FLOAT) {
  5088.                         if (index_format) {
  5089.                             *iter2++ = widget.f;
  5090.                         } else {
  5091.                             *iter2++ = 65535 * widget.f;
  5092.                         }
  5093.                     } else if (type == GL_UNSIGNED_INT) {
  5094.                         if (index_format) {
  5095.                             *iter2++ = widget.ui;
  5096.                         } else {
  5097.                             *iter2++ = widget.ui >> 16;
  5098.                         }
  5099.                     } else {
  5100.                         if (index_format) {
  5101.                             *iter2++ = widget.i;
  5102.                         } else {
  5103.                             *iter2++ = widget.i >> 15;
  5104.                         }
  5105.                     }
  5106.                     break;
  5107.                 }
  5108.                 iter += element_size;
  5109.             } /* for j */
  5110.             start += rowsize;
  5111. #if 1
  5112.             /* want 'iter' pointing at start, not within, row for assertion
  5113.              * purposes
  5114.              */
  5115.             iter= start;        
  5116. #endif
  5117.         } /* for i */
  5118.  
  5119.        /* iterators should be one byte past end */
  5120.        if (!isTypePackedPixel(type)) {
  5121.           assert(iter2 == &newimage[width*height*components]);
  5122.        }
  5123.        else {
  5124.           assert(iter2 == &newimage[width*height*
  5125.                                     elements_per_group(format,0)]);
  5126.        }
  5127.        assert( iter == &((const GLubyte *)userdata)[rowsize*height +
  5128.                                         psm->unpack_skip_rows * rowsize +
  5129.                                         psm->unpack_skip_pixels * group_size] );
  5130.  
  5131.     } /* else */
  5132. } /* fill_image() */
  5133.  
  5134. /*
  5135. ** Insert array into user's data applying all pixel store modes.
  5136. ** The internal format is an array of unsigned shorts.
  5137. ** empty_image() because it is the opposite of fill_image().
  5138. */
  5139. static void empty_image(const PixelStorageModes *psm,
  5140.                         GLint width, GLint height, GLenum format,
  5141.                         GLenum type, GLboolean index_format,
  5142.                         const GLushort *oldimage, void *userdata)
  5143. {
  5144.     GLint components;
  5145.     GLint element_size;
  5146.     GLint rowsize;
  5147.     GLint padding;
  5148.     GLint groups_per_line;
  5149.     GLint group_size;
  5150.     GLint elements_per_line;
  5151.     GLubyte *start;
  5152.     GLubyte *iter;
  5153.     const GLushort *iter2;
  5154.     GLint i, j, k;
  5155.     GLint myswap_bytes;
  5156.  
  5157.     myswap_bytes = psm->pack_swap_bytes;
  5158.     components = elements_per_group(format,type);
  5159.     if (psm->pack_row_length > 0) {
  5160.         groups_per_line = psm->pack_row_length;
  5161.     } else {
  5162.         groups_per_line = width;
  5163.     }
  5164.  
  5165.     /* All formats except GL_BITMAP fall out trivially */
  5166.     if (type == GL_BITMAP) {
  5167.         GLint bit_offset;
  5168.         GLint current_bit;
  5169.  
  5170.         rowsize = (groups_per_line * components + 7) / 8;
  5171.         padding = (rowsize % psm->pack_alignment);
  5172.         if (padding) {
  5173.             rowsize += psm->pack_alignment - padding;
  5174.         }
  5175.         start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
  5176.                 (psm->pack_skip_pixels * components / 8);
  5177.         elements_per_line = width * components;
  5178.         iter2 = oldimage;
  5179.         for (i = 0; i < height; i++) {
  5180.             iter = start;
  5181.             bit_offset = (psm->pack_skip_pixels * components) % 8;
  5182.             for (j = 0; j < elements_per_line; j++) {
  5183.                 if (index_format) {
  5184.                     current_bit = iter2[0] & 1;
  5185.                 } else {
  5186.                     if (iter2[0] > 32767) {
  5187.                         current_bit = 1;
  5188.                     } else {
  5189.                         current_bit = 0;
  5190.                     }
  5191.                 }
  5192.  
  5193.                 if (current_bit) {
  5194.                     if (psm->pack_lsb_first) {
  5195.                         *iter |= (1 << bit_offset);
  5196.                     } else {
  5197.                         *iter |= (1 << (7 - bit_offset));
  5198.                     }
  5199.                 } else {
  5200.                     if (psm->pack_lsb_first) {
  5201.                         *iter &= ~(1 << bit_offset);
  5202.                     } else {
  5203.                         *iter &= ~(1 << (7 - bit_offset));
  5204.                     }
  5205.                 }
  5206.  
  5207.                 bit_offset++;
  5208.                 if (bit_offset == 8) {
  5209.                     bit_offset = 0;
  5210.                     iter++;
  5211.                 }
  5212.                 iter2++;
  5213.             }
  5214.             start += rowsize;
  5215.         }
  5216.     } else {
  5217.         float shoveComponents[4];
  5218.  
  5219.         element_size = bytes_per_element(type);
  5220.         group_size = element_size * components;
  5221.         if (element_size == 1) myswap_bytes = 0;
  5222.  
  5223.         rowsize = groups_per_line * group_size;
  5224.         padding = (rowsize % psm->pack_alignment);
  5225.         if (padding) {
  5226.             rowsize += psm->pack_alignment - padding;
  5227.         }
  5228.         start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
  5229.                 psm->pack_skip_pixels * group_size;
  5230.         elements_per_line = width * components;
  5231.  
  5232.         iter2 = oldimage;
  5233.         for (i = 0; i < height; i++) {
  5234.             iter = start;
  5235.             for (j = 0; j < elements_per_line; j++) {
  5236.                 Type_Widget widget;
  5237.  
  5238.                 switch(type) {
  5239.                   case GL_UNSIGNED_BYTE_3_3_2:
  5240.                     for (k = 0; k < 3; k++) {
  5241.                        shoveComponents[k]= *iter2++ / 65535.0;
  5242.                     }
  5243.                     shove332(shoveComponents,0,(void *)iter);
  5244.                     break;
  5245.                   case GL_UNSIGNED_BYTE_2_3_3_REV:
  5246.                     for (k = 0; k < 3; k++) {
  5247.                        shoveComponents[k]= *iter2++ / 65535.0;
  5248.                     }
  5249.                     shove233rev(shoveComponents,0,(void *)iter);
  5250.                     break;
  5251.                   case GL_UNSIGNED_BYTE:
  5252.                     if (index_format) {
  5253.                         *iter = *iter2++;
  5254.                     } else {
  5255.                         *iter = *iter2++ >> 8;
  5256.                     }
  5257.                     break;
  5258.                   case GL_BYTE:
  5259.                     if (index_format) {
  5260.                         *((GLbyte *) iter) = *iter2++;
  5261.                     } else {
  5262.                         *((GLbyte *) iter) = *iter2++ >> 9;
  5263.                     }
  5264.                     break;
  5265.                   case GL_UNSIGNED_SHORT_5_6_5:        
  5266.                     for (k = 0; k < 3; k++) {
  5267.                        shoveComponents[k]= *iter2++ / 65535.0;
  5268.                     }
  5269.                     shove565(shoveComponents,0,(void *)&widget.us[0]);
  5270.                     if (myswap_bytes) {
  5271.                        iter[0] = widget.ub[1];
  5272.                        iter[1] = widget.ub[0];
  5273.                     }
  5274.                     else {
  5275.                        *(GLushort *)iter = widget.us[0];
  5276.                     }
  5277.                     break;
  5278.                   case GL_UNSIGNED_SHORT_5_6_5_REV:            
  5279.                     for (k = 0; k < 3; k++) {
  5280.                        shoveComponents[k]= *iter2++ / 65535.0;
  5281.                     }
  5282.                     shove565rev(shoveComponents,0,(void *)&widget.us[0]);
  5283.                     if (myswap_bytes) {
  5284.                        iter[0] = widget.ub[1];
  5285.                        iter[1] = widget.ub[0];
  5286.                     }
  5287.                     else {
  5288.                        *(GLushort *)iter = widget.us[0];
  5289.                     }
  5290.                     break;
  5291.                   case GL_UNSIGNED_SHORT_4_4_4_4:
  5292.                     for (k = 0; k < 4; k++) {
  5293.                        shoveComponents[k]= *iter2++ / 65535.0;
  5294.                     }
  5295.                     shove4444(shoveComponents,0,(void *)&widget.us[0]);
  5296.                     if (myswap_bytes) {
  5297.                        iter[0] = widget.ub[1];
  5298.                        iter[1] = widget.ub[0];
  5299.                     } else {
  5300.                        *(GLushort *)iter = widget.us[0];
  5301.                     }
  5302.                     break;
  5303.                   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  5304.                     for (k = 0; k < 4; k++) {
  5305.                        shoveComponents[k]= *iter2++ / 65535.0;
  5306.                     }
  5307.                     shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
  5308.                     if (myswap_bytes) {
  5309.                        iter[0] = widget.ub[1];
  5310.                        iter[1] = widget.ub[0];
  5311.                     } else {
  5312.                        *(GLushort *)iter = widget.us[0];
  5313.                     }
  5314.                     break;
  5315.                   case GL_UNSIGNED_SHORT_5_5_5_1:
  5316.                     for (k = 0; k < 4; k++) {
  5317.                        shoveComponents[k]= *iter2++ / 65535.0;
  5318.                     }
  5319.                     shove5551(shoveComponents,0,(void *)&widget.us[0]);
  5320.                     if (myswap_bytes) {
  5321.                        iter[0] = widget.ub[1];
  5322.                        iter[1] = widget.ub[0];
  5323.                     } else {
  5324.                        *(GLushort *)iter = widget.us[0];
  5325.                     }
  5326.                     break;
  5327.                   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  5328.                     for (k = 0; k < 4; k++) {
  5329.                        shoveComponents[k]= *iter2++ / 65535.0;
  5330.                     }
  5331.                     shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
  5332.                     if (myswap_bytes) {
  5333.                        iter[0] = widget.ub[1];
  5334.                        iter[1] = widget.ub[0];
  5335.                     } else {
  5336.                        *(GLushort *)iter = widget.us[0];
  5337.                     }
  5338.                     break;
  5339.                   case GL_UNSIGNED_SHORT:
  5340.                   case GL_SHORT:
  5341.                     if (type == GL_SHORT) {
  5342.                         if (index_format) {
  5343.                             widget.s[0] = *iter2++;
  5344.                         } else {
  5345.                             widget.s[0] = *iter2++ >> 1;
  5346.                         }
  5347.                     } else {
  5348.                         widget.us[0] = *iter2++;
  5349.                     }
  5350.                     if (myswap_bytes) {
  5351.                         iter[0] = widget.ub[1];
  5352.                         iter[1] = widget.ub[0];
  5353.                     } else {
  5354.                         iter[0] = widget.ub[0];
  5355.                         iter[1] = widget.ub[1];
  5356.                     }
  5357.                     break;
  5358.                   case GL_UNSIGNED_INT_8_8_8_8:
  5359.                     for (k = 0; k < 4; k++) {
  5360.                        shoveComponents[k]= *iter2++ / 65535.0;
  5361.                     }
  5362.                     shove8888(shoveComponents,0,(void *)&widget.ui);
  5363.                     if (myswap_bytes) {
  5364.                         iter[3] = widget.ub[0];
  5365.                         iter[2] = widget.ub[1];
  5366.                         iter[1] = widget.ub[2];
  5367.                         iter[0] = widget.ub[3];
  5368.                     } else {
  5369.                         *(GLuint *)iter= widget.ui;
  5370.                     }
  5371.  
  5372.                     break;
  5373.                   case GL_UNSIGNED_INT_8_8_8_8_REV:
  5374.                     for (k = 0; k < 4; k++) {
  5375.                        shoveComponents[k]= *iter2++ / 65535.0;
  5376.                     }
  5377.                     shove8888rev(shoveComponents,0,(void *)&widget.ui);
  5378.                     if (myswap_bytes) {
  5379.                         iter[3] = widget.ub[0];
  5380.                         iter[2] = widget.ub[1];
  5381.                         iter[1] = widget.ub[2];
  5382.                         iter[0] = widget.ub[3];
  5383.                     } else {
  5384.                         *(GLuint *)iter= widget.ui;
  5385.                     }
  5386.                     break;
  5387.                   case GL_UNSIGNED_INT_10_10_10_2:
  5388.                     for (k = 0; k < 4; k++) {
  5389.                        shoveComponents[k]= *iter2++ / 65535.0;
  5390.                     }
  5391.                     shove1010102(shoveComponents,0,(void *)&widget.ui);
  5392.                     if (myswap_bytes) {
  5393.                         iter[3] = widget.ub[0];
  5394.                         iter[2] = widget.ub[1];
  5395.                         iter[1] = widget.ub[2];
  5396.                         iter[0] = widget.ub[3];
  5397.                     } else {
  5398.                         *(GLuint *)iter= widget.ui;
  5399.                     }
  5400.                     break;
  5401.                   case GL_UNSIGNED_INT_2_10_10_10_REV:
  5402.                     for (k = 0; k < 4; k++) {
  5403.                        shoveComponents[k]= *iter2++ / 65535.0;
  5404.                     }
  5405.                     shove2101010rev(shoveComponents,0,(void *)&widget.ui);
  5406.                     if (myswap_bytes) {
  5407.                         iter[3] = widget.ub[0];
  5408.                         iter[2] = widget.ub[1];
  5409.                         iter[1] = widget.ub[2];
  5410.                         iter[0] = widget.ub[3];
  5411.                     } else {
  5412.                         *(GLuint *)iter= widget.ui;
  5413.                     }
  5414.                     break;
  5415.                   case GL_INT:
  5416.                   case GL_UNSIGNED_INT:
  5417.                   case GL_FLOAT:
  5418.                     if (type == GL_FLOAT) {
  5419.                         if (index_format) {
  5420.                             widget.f = *iter2++;
  5421.                         } else {
  5422.                             widget.f = *iter2++ / (float) 65535.0;
  5423.                         }
  5424.                     } else if (type == GL_UNSIGNED_INT) {
  5425.                         if (index_format) {
  5426.                             widget.ui = *iter2++;
  5427.                         } else {
  5428.                             widget.ui = (unsigned int) *iter2++ * 65537;
  5429.                         }
  5430.                     } else {
  5431.                         if (index_format) {
  5432.                             widget.i = *iter2++;
  5433.                         } else {
  5434.                             widget.i = ((unsigned int) *iter2++ * 65537)/2;
  5435.                         }
  5436.                     }
  5437.                     if (myswap_bytes) {
  5438.                         iter[3] = widget.ub[0];
  5439.                         iter[2] = widget.ub[1];
  5440.                         iter[1] = widget.ub[2];
  5441.                         iter[0] = widget.ub[3];
  5442.                     } else {
  5443.                         iter[0] = widget.ub[0];
  5444.                         iter[1] = widget.ub[1];
  5445.                         iter[2] = widget.ub[2];
  5446.                         iter[3] = widget.ub[3];
  5447.                     }
  5448.                     break;
  5449.                 }
  5450.                 iter += element_size;
  5451.             } /* for j */
  5452.             start += rowsize;
  5453. #if 1
  5454.             /* want 'iter' pointing at start, not within, row for assertion
  5455.              * purposes
  5456.              */
  5457.             iter= start;        
  5458. #endif
  5459.         } /* for i */
  5460.  
  5461.         /* iterators should be one byte past end */
  5462.         if (!isTypePackedPixel(type)) {
  5463.            assert(iter2 == &oldimage[width*height*components]);
  5464.         }
  5465.         else {
  5466.            assert(iter2 == &oldimage[width*height*
  5467.                                      elements_per_group(format,0)]);
  5468.         }
  5469.         assert( iter == &((GLubyte *)userdata)[rowsize*height +
  5470.                                         psm->pack_skip_rows * rowsize +
  5471.                                         psm->pack_skip_pixels * group_size] );
  5472.  
  5473.     } /* else */
  5474. } /* empty_image() */
  5475.  
  5476. /*--------------------------------------------------------------------------
  5477.  * Decimation of packed pixel types
  5478.  *--------------------------------------------------------------------------
  5479.  */
  5480. static void extract332(int isSwap,
  5481.                        const void *packedPixel, GLfloat extractComponents[])
  5482. {
  5483.    GLubyte ubyte= *(const GLubyte *)packedPixel;
  5484.  
  5485.    isSwap= isSwap;              /* turn off warnings */
  5486.  
  5487.    /* 11100000 == 0xe0 */
  5488.    /* 00011100 == 0x1c */
  5489.    /* 00000011 == 0x03 */
  5490.  
  5491.    extractComponents[0]=   (float)((ubyte & 0xe0)  >> 5) / 7.0;
  5492.    extractComponents[1]=   (float)((ubyte & 0x1c)  >> 2) / 7.0; /* 7 = 2^3-1 */
  5493.    extractComponents[2]=   (float)((ubyte & 0x03)      ) / 3.0; /* 3 = 2^2-1 */
  5494. } /* extract332() */
  5495.  
  5496. static void shove332(const GLfloat shoveComponents[],
  5497.                      int index, void *packedPixel)      
  5498. {
  5499.    /* 11100000 == 0xe0 */
  5500.    /* 00011100 == 0x1c */
  5501.    /* 00000011 == 0x03 */
  5502.  
  5503.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5504.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5505.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5506.  
  5507.    /* due to limited precision, need to round before shoving */
  5508.    ((GLubyte *)packedPixel)[index]  =
  5509.      ((GLubyte)((shoveComponents[0] * 7)+0.5)  << 5) & 0xe0;
  5510.    ((GLubyte *)packedPixel)[index] |=
  5511.      ((GLubyte)((shoveComponents[1] * 7)+0.5)  << 2) & 0x1c;
  5512.    ((GLubyte *)packedPixel)[index]  |=
  5513.      ((GLubyte)((shoveComponents[2] * 3)+0.5)      ) & 0x03;
  5514. } /* shove332() */
  5515.  
  5516. static void extract233rev(int isSwap,
  5517.                           const void *packedPixel, GLfloat extractComponents[])
  5518. {
  5519.    GLubyte ubyte= *(const GLubyte *)packedPixel;
  5520.  
  5521.    isSwap= isSwap;              /* turn off warnings */
  5522.  
  5523.    /* 0000,0111 == 0x07 */
  5524.    /* 0011,1000 == 0x38 */
  5525.    /* 1100,0000 == 0xC0 */
  5526.  
  5527.    extractComponents[0]= (float)((ubyte & 0x07)     ) / 7.0;
  5528.    extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
  5529.    extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
  5530. } /* extract233rev() */
  5531.  
  5532. static void shove233rev(const GLfloat shoveComponents[],
  5533.                         int index, void *packedPixel)  
  5534. {
  5535.    /* 0000,0111 == 0x07 */
  5536.    /* 0011,1000 == 0x38 */
  5537.    /* 1100,0000 == 0xC0 */
  5538.  
  5539.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5540.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5541.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5542.  
  5543.    /* due to limited precision, need to round before shoving */
  5544.    ((GLubyte *)packedPixel)[index] =
  5545.      ((GLubyte)((shoveComponents[0] * 7.0)+0.5)     ) & 0x07;
  5546.    ((GLubyte *)packedPixel)[index]|=
  5547.      ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
  5548.    ((GLubyte *)packedPixel)[index]|=
  5549.      ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
  5550. } /* shove233rev() */
  5551.  
  5552. static void extract565(int isSwap,
  5553.                        const void *packedPixel, GLfloat extractComponents[])
  5554. {
  5555.    GLushort ushort;
  5556.  
  5557.    if (isSwap) {
  5558.      ushort= __GLU_SWAP_2_BYTES(packedPixel);
  5559.    }
  5560.    else {
  5561.      ushort= *(const GLushort *)packedPixel;
  5562.    }
  5563.  
  5564.    /* 11111000,00000000 == 0xf800 */
  5565.    /* 00000111,11100000 == 0x07e0 */
  5566.    /* 00000000,00011111 == 0x001f */
  5567.  
  5568.    extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
  5569.    extractComponents[1]=(float)((ushort & 0x07e0) >>  5) / 63.0;/* 63 = 2^6-1*/
  5570.    extractComponents[2]=(float)((ushort & 0x001f)      ) / 31.0;
  5571. } /* extract565() */
  5572.  
  5573. static void shove565(const GLfloat shoveComponents[],
  5574.                      int index,void *packedPixel)
  5575. {
  5576.    /* 11111000,00000000 == 0xf800 */
  5577.    /* 00000111,11100000 == 0x07e0 */
  5578.    /* 00000000,00011111 == 0x001f */
  5579.  
  5580.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5581.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5582.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5583.  
  5584.    /* due to limited precision, need to round before shoving */
  5585.    ((GLushort *)packedPixel)[index] =
  5586.      ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
  5587.    ((GLushort *)packedPixel)[index]|=
  5588.      ((GLushort)((shoveComponents[1] * 63)+0.5) <<  5) & 0x07e0;
  5589.    ((GLushort *)packedPixel)[index]|=
  5590.      ((GLushort)((shoveComponents[2] * 31)+0.5)      ) & 0x001f;
  5591. } /* shove565() */
  5592.  
  5593. static void extract565rev(int isSwap,
  5594.                           const void *packedPixel, GLfloat extractComponents[])
  5595. {
  5596.    GLushort ushort;
  5597.  
  5598.    if (isSwap) {
  5599.      ushort= __GLU_SWAP_2_BYTES(packedPixel);
  5600.    }
  5601.    else {
  5602.      ushort= *(const GLushort *)packedPixel;
  5603.    }
  5604.  
  5605.    /* 00000000,00011111 == 0x001f */
  5606.    /* 00000111,11100000 == 0x07e0 */
  5607.    /* 11111000,00000000 == 0xf800 */
  5608.  
  5609.    extractComponents[0]= (float)((ushort & 0x001F)      ) / 31.0;
  5610.    extractComponents[1]= (float)((ushort & 0x07E0) >>  5) / 63.0;
  5611.    extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
  5612. } /* extract565rev() */
  5613.  
  5614. static void shove565rev(const GLfloat shoveComponents[],
  5615.                         int index,void *packedPixel)
  5616. {
  5617.    /* 00000000,00011111 == 0x001f */
  5618.    /* 00000111,11100000 == 0x07e0 */
  5619.    /* 11111000,00000000 == 0xf800 */
  5620.  
  5621.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5622.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5623.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5624.  
  5625.    /* due to limited precision, need to round before shoving */
  5626.    ((GLushort *)packedPixel)[index] =
  5627.      ((GLushort)((shoveComponents[0] * 31.0)+0.5)      ) & 0x001F;
  5628.    ((GLushort *)packedPixel)[index]|=
  5629.      ((GLushort)((shoveComponents[1] * 63.0)+0.5) <<  5) & 0x07E0;
  5630.    ((GLushort *)packedPixel)[index]|=
  5631.      ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
  5632. } /* shove565rev() */
  5633.  
  5634. static void extract4444(int isSwap,const void *packedPixel,
  5635.                         GLfloat extractComponents[])
  5636. {
  5637.    GLushort ushort;
  5638.  
  5639.    if (isSwap) {
  5640.      ushort= __GLU_SWAP_2_BYTES(packedPixel);
  5641.    }
  5642.    else {
  5643.      ushort= *(const GLushort *)packedPixel;
  5644.    }
  5645.  
  5646.    /* 11110000,00000000 == 0xf000 */
  5647.    /* 00001111,00000000 == 0x0f00 */
  5648.    /* 00000000,11110000 == 0x00f0 */
  5649.    /* 00000000,00001111 == 0x000f */
  5650.  
  5651.    extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
  5652.    extractComponents[1]= (float)((ushort & 0x0f00) >>  8) / 15.0;
  5653.    extractComponents[2]= (float)((ushort & 0x00f0) >>  4) / 15.0;
  5654.    extractComponents[3]= (float)((ushort & 0x000f)      ) / 15.0;
  5655. } /* extract4444() */
  5656.  
  5657. static void shove4444(const GLfloat shoveComponents[],
  5658.                       int index,void *packedPixel)
  5659. {
  5660.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5661.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5662.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5663.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5664.  
  5665.    /* due to limited precision, need to round before shoving */
  5666.    ((GLushort *)packedPixel)[index] =
  5667.      ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
  5668.    ((GLushort *)packedPixel)[index]|=
  5669.      ((GLushort)((shoveComponents[1] * 15)+0.5) <<  8) & 0x0f00;
  5670.    ((GLushort *)packedPixel)[index]|=
  5671.      ((GLushort)((shoveComponents[2] * 15)+0.5) <<  4) & 0x00f0;
  5672.    ((GLushort *)packedPixel)[index]|=
  5673.      ((GLushort)((shoveComponents[3] * 15)+0.5)      ) & 0x000f;
  5674. } /* shove4444() */
  5675.  
  5676. static void extract4444rev(int isSwap,const void *packedPixel,
  5677.                            GLfloat extractComponents[])
  5678. {
  5679.    GLushort ushort;
  5680.  
  5681.    if (isSwap) {
  5682.      ushort= __GLU_SWAP_2_BYTES(packedPixel);
  5683.    }
  5684.    else {
  5685.      ushort= *(const GLushort *)packedPixel;
  5686.    }
  5687.  
  5688.    /* 00000000,00001111 == 0x000f */
  5689.    /* 00000000,11110000 == 0x00f0 */
  5690.    /* 00001111,00000000 == 0x0f00 */
  5691.    /* 11110000,00000000 == 0xf000 */
  5692.  
  5693.    /* 15 = 2^4-1 */
  5694.    extractComponents[0]= (float)((ushort & 0x000F)      ) / 15.0;
  5695.    extractComponents[1]= (float)((ushort & 0x00F0) >>  4) / 15.0;
  5696.    extractComponents[2]= (float)((ushort & 0x0F00) >>  8) / 15.0;
  5697.    extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
  5698. } /* extract4444rev() */
  5699.  
  5700. static void shove4444rev(const GLfloat shoveComponents[],
  5701.                          int index,void *packedPixel)
  5702. {
  5703.    /* 00000000,00001111 == 0x000f */
  5704.    /* 00000000,11110000 == 0x00f0 */
  5705.    /* 00001111,00000000 == 0x0f00 */
  5706.    /* 11110000,00000000 == 0xf000 */
  5707.  
  5708.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5709.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5710.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5711.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5712.  
  5713.    /* due to limited precision, need to round before shoving */
  5714.    ((GLushort *)packedPixel)[index] =
  5715.      ((GLushort)((shoveComponents[0] * 15)+0.5)      ) & 0x000F;
  5716.    ((GLushort *)packedPixel)[index]|=
  5717.      ((GLushort)((shoveComponents[1] * 15)+0.5) <<  4) & 0x00F0;
  5718.    ((GLushort *)packedPixel)[index]|=
  5719.      ((GLushort)((shoveComponents[2] * 15)+0.5) <<  8) & 0x0F00;
  5720.    ((GLushort *)packedPixel)[index]|=
  5721.      ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
  5722. } /* shove4444rev() */
  5723.  
  5724. static void extract5551(int isSwap,const void *packedPixel,
  5725.                         GLfloat extractComponents[])
  5726. {
  5727.    GLushort ushort;
  5728.  
  5729.    if (isSwap) {
  5730.      ushort= __GLU_SWAP_2_BYTES(packedPixel);
  5731.    }
  5732.    else {
  5733.      ushort= *(const GLushort *)packedPixel;
  5734.    }
  5735.  
  5736.    /* 11111000,00000000 == 0xf800 */
  5737.    /* 00000111,11000000 == 0x07c0 */
  5738.    /* 00000000,00111110 == 0x003e */
  5739.    /* 00000000,00000001 == 0x0001 */
  5740.  
  5741.    extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
  5742.    extractComponents[1]=(float)((ushort & 0x07c0) >>  6) / 31.0;
  5743.    extractComponents[2]=(float)((ushort & 0x003e) >>  1) / 31.0;
  5744.    extractComponents[3]=(float)((ushort & 0x0001)      );
  5745. } /* extract5551() */
  5746.  
  5747. static void shove5551(const GLfloat shoveComponents[],
  5748.                       int index,void *packedPixel)
  5749. {
  5750.    /* 11111000,00000000 == 0xf800 */
  5751.    /* 00000111,11000000 == 0x07c0 */
  5752.    /* 00000000,00111110 == 0x003e */
  5753.    /* 00000000,00000001 == 0x0001 */
  5754.  
  5755.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5756.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5757.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5758.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5759.  
  5760.    /* due to limited precision, need to round before shoving */
  5761.    ((GLushort *)packedPixel)[index]  =
  5762.      ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
  5763.    ((GLushort *)packedPixel)[index]|=
  5764.      ((GLushort)((shoveComponents[1] * 31)+0.5) <<  6) & 0x07c0;
  5765.    ((GLushort *)packedPixel)[index]|=
  5766.      ((GLushort)((shoveComponents[2] * 31)+0.5) <<  1) & 0x003e;
  5767.    ((GLushort *)packedPixel)[index]|=
  5768.      ((GLushort)((shoveComponents[3])+0.5)           ) & 0x0001;
  5769. } /* shove5551() */
  5770.  
  5771. static void extract1555rev(int isSwap,const void *packedPixel,
  5772.                            GLfloat extractComponents[])
  5773. {
  5774.    GLushort ushort;
  5775.  
  5776.    if (isSwap) {
  5777.      ushort= __GLU_SWAP_2_BYTES(packedPixel);
  5778.    }
  5779.    else {
  5780.      ushort= *(const GLushort *)packedPixel;
  5781.    }
  5782.  
  5783.    /* 00000000,00011111 == 0x001F */
  5784.    /* 00000011,11100000 == 0x03E0 */
  5785.    /* 01111100,00000000 == 0x7C00 */
  5786.    /* 10000000,00000000 == 0x8000 */
  5787.  
  5788.    /* 31 = 2^5-1 */
  5789.    extractComponents[0]= (float)((ushort & 0x001F)      ) / 31.0;
  5790.    extractComponents[1]= (float)((ushort & 0x03E0) >>  5) / 31.0;
  5791.    extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
  5792.    extractComponents[3]= (float)((ushort & 0x8000) >> 15);
  5793. } /* extract1555rev() */
  5794.  
  5795. static void shove1555rev(const GLfloat shoveComponents[],
  5796.                          int index,void *packedPixel)
  5797. {
  5798.    /* 00000000,00011111 == 0x001F */
  5799.    /* 00000011,11100000 == 0x03E0 */
  5800.    /* 01111100,00000000 == 0x7C00 */
  5801.    /* 10000000,00000000 == 0x8000 */
  5802.  
  5803.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5804.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5805.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5806.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5807.  
  5808.    /* due to limited precision, need to round before shoving */
  5809.    ((GLushort *)packedPixel)[index] =
  5810.      ((GLushort)((shoveComponents[0] * 31)+0.5)      ) & 0x001F;
  5811.    ((GLushort *)packedPixel)[index]|=
  5812.      ((GLushort)((shoveComponents[1] * 31)+0.5) <<  5) & 0x03E0;
  5813.    ((GLushort *)packedPixel)[index]|=
  5814.      ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
  5815.    ((GLushort *)packedPixel)[index]|=
  5816.      ((GLushort)((shoveComponents[3])+0.5)      << 15) & 0x8000;
  5817. } /* shove1555rev() */
  5818.  
  5819. static void extract8888(int isSwap,
  5820.                         const void *packedPixel, GLfloat extractComponents[])
  5821. {
  5822.    GLuint uint;
  5823.  
  5824.    if (isSwap) {
  5825.      uint= __GLU_SWAP_4_BYTES(packedPixel);
  5826.    }
  5827.    else {
  5828.      uint= *(const GLuint *)packedPixel;
  5829.    }
  5830.  
  5831.    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
  5832.    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
  5833.    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
  5834.    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
  5835.  
  5836.    /* 255 = 2^8-1 */
  5837.    extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
  5838.    extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
  5839.    extractComponents[2]= (float)((uint & 0x0000ff00) >>  8) / 255.0;
  5840.    extractComponents[3]= (float)((uint & 0x000000ff)      ) / 255.0;
  5841. } /* extract8888() */
  5842.  
  5843. static void shove8888(const GLfloat shoveComponents[],
  5844.                       int index,void *packedPixel)
  5845. {
  5846.    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
  5847.    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
  5848.    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
  5849.    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
  5850.  
  5851.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5852.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5853.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5854.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5855.  
  5856.    /* due to limited precision, need to round before shoving */
  5857.    ((GLuint *)packedPixel)[index] =
  5858.      ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
  5859.    ((GLuint *)packedPixel)[index]|=
  5860.      ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
  5861.    ((GLuint *)packedPixel)[index]|=
  5862.      ((GLuint)((shoveComponents[2] * 255)+0.5) <<  8) & 0x0000ff00;
  5863.    ((GLuint *)packedPixel)[index]|=
  5864.      ((GLuint)((shoveComponents[3] * 255)+0.5)      ) & 0x000000ff;
  5865. } /* shove8888() */
  5866.  
  5867. static void extract8888rev(int isSwap,
  5868.                            const void *packedPixel,GLfloat extractComponents[])
  5869. {
  5870.    GLuint uint;
  5871.  
  5872.    if (isSwap) {
  5873.      uint= __GLU_SWAP_4_BYTES(packedPixel);
  5874.    }
  5875.    else {
  5876.      uint= *(const GLuint *)packedPixel;
  5877.    }
  5878.  
  5879.    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
  5880.    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
  5881.    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
  5882.    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
  5883.  
  5884.    /* 255 = 2^8-1 */
  5885.    extractComponents[0]= (float)((uint & 0x000000FF)      ) / 255.0;
  5886.    extractComponents[1]= (float)((uint & 0x0000FF00) >>  8) / 255.0;
  5887.    extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
  5888.    extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
  5889. } /* extract8888rev() */
  5890.  
  5891. static void shove8888rev(const GLfloat shoveComponents[],
  5892.                          int index,void *packedPixel)
  5893. {
  5894.    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
  5895.    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
  5896.    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
  5897.    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
  5898.  
  5899.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5900.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5901.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5902.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5903.  
  5904.    /* due to limited precision, need to round before shoving */
  5905.    ((GLuint *)packedPixel)[index] =
  5906.      ((GLuint)((shoveComponents[0] * 255)+0.5)      ) & 0x000000FF;
  5907.    ((GLuint *)packedPixel)[index]|=
  5908.      ((GLuint)((shoveComponents[1] * 255)+0.5) <<  8) & 0x0000FF00;
  5909.    ((GLuint *)packedPixel)[index]|=
  5910.      ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
  5911.    ((GLuint *)packedPixel)[index]|=
  5912.      ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
  5913. } /* shove8888rev() */
  5914.  
  5915. static void extract1010102(int isSwap,
  5916.                            const void *packedPixel,GLfloat extractComponents[])
  5917. {
  5918.    GLuint uint;
  5919.  
  5920.    if (isSwap) {
  5921.      uint= __GLU_SWAP_4_BYTES(packedPixel);
  5922.    }
  5923.    else {
  5924.      uint= *(const GLuint *)packedPixel;
  5925.    }
  5926.  
  5927.    /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
  5928.    /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
  5929.    /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
  5930.    /* 00000000,00000000,00000000,00000011 == 0x00000003 */
  5931.  
  5932.    /* 1023 = 2^10-1 */
  5933.    extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
  5934.    extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
  5935.    extractComponents[2]= (float)((uint & 0x00000ffc) >>  2) / 1023.0;
  5936.    extractComponents[3]= (float)((uint & 0x00000003)      ) / 3.0;
  5937. } /* extract1010102() */
  5938.  
  5939. static void shove1010102(const GLfloat shoveComponents[],
  5940.                          int index,void *packedPixel)
  5941. {
  5942.    /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
  5943.    /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
  5944.    /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
  5945.    /* 00000000,00000000,00000000,00000011 == 0x00000003 */
  5946.  
  5947.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5948.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5949.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  5950.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  5951.  
  5952.    /* due to limited precision, need to round before shoving */
  5953.    ((GLuint *)packedPixel)[index] =
  5954.      ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
  5955.    ((GLuint *)packedPixel)[index]|=
  5956.      ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
  5957.    ((GLuint *)packedPixel)[index]|=
  5958.      ((GLuint)((shoveComponents[2] * 1023)+0.5) <<  2) & 0x00000ffc;
  5959.    ((GLuint *)packedPixel)[index]|=
  5960.      ((GLuint)((shoveComponents[3] * 3)+0.5)         ) & 0x00000003;
  5961. } /* shove1010102() */
  5962.  
  5963. static void extract2101010rev(int isSwap,
  5964.                               const void *packedPixel,
  5965.                               GLfloat extractComponents[])
  5966. {
  5967.    GLuint uint;
  5968.  
  5969.    if (isSwap) {
  5970.      uint= __GLU_SWAP_4_BYTES(packedPixel);
  5971.    }
  5972.    else {
  5973.      uint= *(const GLuint *)packedPixel;
  5974.    }
  5975.  
  5976.    /* 00000000,00000000,00000011,11111111 == 0x000003FF */
  5977.    /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
  5978.    /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
  5979.    /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
  5980.  
  5981.    /* 1023 = 2^10-1 */
  5982.    extractComponents[0]= (float)((uint & 0x000003FF)      ) / 1023.0;
  5983.    extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
  5984.    extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
  5985.    extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
  5986.    /* 3 = 2^2-1 */
  5987. } /* extract2101010rev() */
  5988.  
  5989. static void shove2101010rev(const GLfloat shoveComponents[],
  5990.                             int index,void *packedPixel)
  5991. {
  5992.    /* 00000000,00000000,00000011,11111111 == 0x000003FF */
  5993.    /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
  5994.    /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
  5995.    /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
  5996.  
  5997.    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
  5998.    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
  5999.    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
  6000.    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
  6001.  
  6002.    /* due to limited precision, need to round before shoving */
  6003.    ((GLuint *)packedPixel)[index] =
  6004.      ((GLuint)((shoveComponents[0] * 1023)+0.5)      ) & 0x000003FF;
  6005.    ((GLuint *)packedPixel)[index]|=
  6006.      ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
  6007.    ((GLuint *)packedPixel)[index]|=
  6008.      ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
  6009.    ((GLuint *)packedPixel)[index]|=
  6010.      ((GLuint)((shoveComponents[3] * 3)+0.5)    << 30) & 0xC0000000;
  6011. } /* shove2101010rev() */
  6012.  
  6013. static void scaleInternalPackedPixel(int components,
  6014.                                      void (*extractPackedPixel)
  6015.                                      (int, const void *,GLfloat []),
  6016.                                      void (*shovePackedPixel)
  6017.                                      (const GLfloat [], int, void *),
  6018.                                      GLint widthIn,GLint heightIn,
  6019.                                      const void *dataIn,
  6020.                                      GLint widthOut,GLint heightOut,
  6021.                                      void *dataOut,
  6022.                                      GLint pixelSizeInBytes,
  6023.                                      GLint rowSizeInBytes,GLint isSwap)
  6024. {
  6025.     float convx;
  6026.     float convy;
  6027.     float percent;
  6028.  
  6029.     /* Max components in a format is 4, so... */
  6030.     float totals[4];
  6031.     float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
  6032.  
  6033.     float area;
  6034.     int i,j,k,xindex;
  6035.  
  6036.     const char *temp, *temp0;
  6037.     int outindex;
  6038.  
  6039.     int lowx_int, highx_int, lowy_int, highy_int;
  6040.     float x_percent, y_percent;
  6041.     float lowx_float, highx_float, lowy_float, highy_float;
  6042.     float convy_float, convx_float;
  6043.     int convy_int, convx_int;
  6044.     int l, m;
  6045.     const char *left, *right;
  6046.  
  6047.     if (widthIn == widthOut*2 && heightIn == heightOut*2) {
  6048.         halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
  6049.                               widthIn, heightIn, dataIn, dataOut,
  6050.                               pixelSizeInBytes,rowSizeInBytes,isSwap);
  6051.         return;
  6052.     }
  6053.     convy = (float) heightIn/heightOut;
  6054.     convx = (float) widthIn/widthOut;
  6055.     convy_int = floor(convy);
  6056.     convy_float = convy - convy_int;
  6057.     convx_int = floor(convx);
  6058.     convx_float = convx - convx_int;
  6059.  
  6060.     area = convx * convy;
  6061.  
  6062.     lowy_int = 0;
  6063.     lowy_float = 0;
  6064.     highy_int = convy_int;
  6065.     highy_float = convy_float;
  6066.  
  6067.     for (i = 0; i < heightOut; i++) {
  6068.         lowx_int = 0;
  6069.         lowx_float = 0;
  6070.         highx_int = convx_int;
  6071.         highx_float = convx_float;
  6072.  
  6073.         for (j = 0; j < widthOut; j++) {
  6074.             /*
  6075.             ** Ok, now apply box filter to box that goes from (lowx, lowy)
  6076.             ** to (highx, highy) on input data into this pixel on output
  6077.             ** data.
  6078.             */
  6079.             totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  6080.  
  6081.             /* calculate the value for pixels in the 1st row */
  6082.             xindex = lowx_int*pixelSizeInBytes;
  6083.             if((highy_int>lowy_int) && (highx_int>lowx_int)) {
  6084.  
  6085.                 y_percent = 1-lowy_float;
  6086.                 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
  6087.                 percent = y_percent * (1-lowx_float);
  6088. #if 0
  6089.                 for (k = 0, temp_index = temp; k < components;
  6090.                      k++, temp_index += element_size) {
  6091.                     if (myswap_bytes) {
  6092.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6093.                     } else {
  6094.                         totals[k] += *(const GLushort*)temp_index * percent;
  6095.                     }
  6096.                 }
  6097. #else
  6098.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6099.                 for (k = 0; k < components; k++) {
  6100.                    totals[k]+= extractTotals[k] * percent;
  6101.                 }
  6102. #endif
  6103.                 left = temp;
  6104.                 for(l = lowx_int+1; l < highx_int; l++) {
  6105.                     temp += pixelSizeInBytes;
  6106. #if 0
  6107.                     for (k = 0, temp_index = temp; k < components;
  6108.                          k++, temp_index += element_size) {
  6109.                         if (myswap_bytes) {
  6110.                             totals[k] +=
  6111.                                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
  6112.                         } else {
  6113.                             totals[k] += *(const GLushort*)temp_index * y_percent;
  6114.                         }
  6115.                     }
  6116. #else
  6117.                     (*extractPackedPixel)(isSwap,temp,extractTotals);
  6118.                     for (k = 0; k < components; k++) {
  6119.                        totals[k]+= extractTotals[k] * y_percent;
  6120.                     }
  6121. #endif
  6122.                 }
  6123.                 temp += pixelSizeInBytes;
  6124.                 right = temp;
  6125.                 percent = y_percent * highx_float;
  6126. #if 0
  6127.                 for (k = 0, temp_index = temp; k < components;
  6128.                      k++, temp_index += element_size) {
  6129.                     if (myswap_bytes) {
  6130.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6131.                     } else {
  6132.                         totals[k] += *(const GLushort*)temp_index * percent;
  6133.                     }
  6134.                 }
  6135. #else
  6136.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6137.                 for (k = 0; k < components; k++) {
  6138.                    totals[k]+= extractTotals[k] * percent;
  6139.                 }
  6140. #endif
  6141.  
  6142.                 /* calculate the value for pixels in the last row */
  6143.                
  6144.                 y_percent = highy_float;
  6145.                 percent = y_percent * (1-lowx_float);
  6146.                 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
  6147. #if 0
  6148.                 for (k = 0, temp_index = temp; k < components;
  6149.                      k++, temp_index += element_size) {
  6150.                     if (myswap_bytes) {
  6151.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6152.                     } else {
  6153.                         totals[k] += *(const GLushort*)temp_index * percent;
  6154.                     }
  6155.                 }
  6156. #else
  6157.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6158.                 for (k = 0; k < components; k++) {
  6159.                    totals[k]+= extractTotals[k] * percent;
  6160.                 }
  6161. #endif
  6162.                 for(l = lowx_int+1; l < highx_int; l++) {
  6163.                     temp += pixelSizeInBytes;
  6164. #if 0
  6165.                     for (k = 0, temp_index = temp; k < components;
  6166.                          k++, temp_index += element_size) {
  6167.                         if (myswap_bytes) {
  6168.                             totals[k] +=
  6169.                                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
  6170.                         } else {
  6171.                             totals[k] += *(const GLushort*)temp_index * y_percent;
  6172.                         }
  6173.                     }
  6174. #else
  6175.                     (*extractPackedPixel)(isSwap,temp,extractTotals);
  6176.                     for (k = 0; k < components; k++) {
  6177.                        totals[k]+= extractTotals[k] * y_percent;
  6178.                     }
  6179. #endif
  6180.  
  6181.                 }
  6182.                 temp += pixelSizeInBytes;
  6183.                 percent = y_percent * highx_float;
  6184. #if 0
  6185.                 for (k = 0, temp_index = temp; k < components;
  6186.                      k++, temp_index += element_size) {
  6187.                     if (myswap_bytes) {
  6188.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6189.                     } else {
  6190.                         totals[k] += *(const GLushort*)temp_index * percent;
  6191.                     }
  6192.                 }
  6193. #else
  6194.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6195.                 for (k = 0; k < components; k++) {
  6196.                    totals[k]+= extractTotals[k] * percent;
  6197.                 }
  6198. #endif
  6199.  
  6200.                 /* calculate the value for pixels in the 1st and last column */
  6201.                 for(m = lowy_int+1; m < highy_int; m++) {
  6202.                     left += rowSizeInBytes;
  6203.                     right += rowSizeInBytes;
  6204. #if 0
  6205.                     for (k = 0; k < components;
  6206.                          k++, left += element_size, right += element_size) {
  6207.                         if (myswap_bytes) {
  6208.                             totals[k] +=
  6209.                                 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
  6210.                                 __GLU_SWAP_2_BYTES(right) * highx_float;
  6211.                         } else {
  6212.                             totals[k] += *(const GLushort*)left * (1-lowx_float)
  6213.                                        + *(const GLushort*)right * highx_float;
  6214.                         }
  6215.                     }
  6216. #else
  6217.                     (*extractPackedPixel)(isSwap,left,extractTotals);
  6218.                     (*extractPackedPixel)(isSwap,right,extractMoreTotals);
  6219.                     for (k = 0; k < components; k++) {
  6220.                        totals[k]+= (extractTotals[k]*(1-lowx_float) +
  6221.                                    extractMoreTotals[k]*highx_float);
  6222.                     }
  6223. #endif
  6224.                 }
  6225.             } else if (highy_int > lowy_int) {
  6226.                 x_percent = highx_float - lowx_float;
  6227.                 percent = (1-lowy_float)*x_percent;
  6228.                 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
  6229. #if 0
  6230.                 for (k = 0, temp_index = temp; k < components;
  6231.                      k++, temp_index += element_size) {
  6232.                     if (myswap_bytes) {
  6233.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6234.                     } else {
  6235.                         totals[k] += *(const GLushort*)temp_index * percent;
  6236.                     }
  6237.                 }
  6238. #else
  6239.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6240.                 for (k = 0; k < components; k++) {
  6241.                    totals[k]+= extractTotals[k] * percent;
  6242.                 }
  6243. #endif
  6244.                 for(m = lowy_int+1; m < highy_int; m++) {
  6245.                     temp += rowSizeInBytes;
  6246. #if 0
  6247.                     for (k = 0, temp_index = temp; k < components;
  6248.                          k++, temp_index += element_size) {
  6249.                         if (myswap_bytes) {
  6250.                             totals[k] +=
  6251.                                 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
  6252.                         } else {
  6253.                             totals[k] += *(const GLushort*)temp_index * x_percent;
  6254.                         }
  6255.                     }
  6256. #else
  6257.                     (*extractPackedPixel)(isSwap,temp,extractTotals);
  6258.                     for (k = 0; k < components; k++) {
  6259.                        totals[k]+= extractTotals[k] * x_percent;
  6260.                     }
  6261. #endif
  6262.                 }
  6263.                 percent = x_percent * highy_float;
  6264.                 temp += rowSizeInBytes;
  6265. #if 0
  6266.                 for (k = 0, temp_index = temp; k < components;
  6267.                      k++, temp_index += element_size) {
  6268.                     if (myswap_bytes) {
  6269.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6270.                     } else {
  6271.                         totals[k] += *(const GLushort*)temp_index * percent;
  6272.                     }
  6273.                 }
  6274. #else
  6275.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6276.                 for (k = 0; k < components; k++) {
  6277.                    totals[k]+= extractTotals[k] * percent;
  6278.                 }
  6279. #endif
  6280.             } else if (highx_int > lowx_int) {
  6281.                 y_percent = highy_float - lowy_float;
  6282.                 percent = (1-lowx_float)*y_percent;
  6283.                 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
  6284. #if 0
  6285.                 for (k = 0, temp_index = temp; k < components;
  6286.                      k++, temp_index += element_size) {
  6287.                     if (myswap_bytes) {
  6288.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6289.                     } else {
  6290.                         totals[k] += *(const GLushort*)temp_index * percent;
  6291.                     }
  6292.                 }
  6293. #else
  6294.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6295.                 for (k = 0; k < components; k++) {
  6296.                    totals[k]+= extractTotals[k] * percent;
  6297.                 }
  6298. #endif
  6299.                 for (l = lowx_int+1; l < highx_int; l++) {
  6300.                     temp += pixelSizeInBytes;
  6301. #if 0
  6302.                     for (k = 0, temp_index = temp; k < components;
  6303.                          k++, temp_index += element_size) {
  6304.                         if (myswap_bytes) {
  6305.                             totals[k] +=
  6306.                                 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
  6307.                         } else {
  6308.                             totals[k] += *(const GLushort*)temp_index * y_percent;
  6309.                         }
  6310.                     }
  6311. #else
  6312.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6313.                 for (k = 0; k < components; k++) {
  6314.                    totals[k]+= extractTotals[k] * y_percent;
  6315.                 }
  6316. #endif
  6317.                 }
  6318.                 temp += pixelSizeInBytes;
  6319.                 percent = y_percent * highx_float;
  6320. #if 0
  6321.                 for (k = 0, temp_index = temp; k < components;
  6322.                      k++, temp_index += element_size) {
  6323.                     if (myswap_bytes) {
  6324.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6325.                     } else {
  6326.                         totals[k] += *(const GLushort*)temp_index * percent;
  6327.                     }
  6328.                 }
  6329. #else
  6330.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6331.                 for (k = 0; k < components; k++) {
  6332.                    totals[k]+= extractTotals[k] * percent;
  6333.                 }
  6334. #endif
  6335.             } else {
  6336.                 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
  6337.                 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
  6338. #if 0
  6339.                 for (k = 0, temp_index = temp; k < components;
  6340.                      k++, temp_index += element_size) {
  6341.                     if (myswap_bytes) {
  6342.                         totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
  6343.                     } else {
  6344.                         totals[k] += *(const GLushort*)temp_index * percent;
  6345.                     }
  6346.                 }
  6347. #else
  6348.                 (*extractPackedPixel)(isSwap,temp,extractTotals);
  6349.                 for (k = 0; k < components; k++) {
  6350.                    totals[k]+= extractTotals[k] * percent;
  6351.                 }
  6352. #endif
  6353.             }
  6354.  
  6355.             /* this is for the pixels in the body */
  6356.             temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
  6357.             for (m = lowy_int+1; m < highy_int; m++) {
  6358.                 temp = temp0;
  6359.                 for(l = lowx_int+1; l < highx_int; l++) {
  6360. #if 0
  6361.                     for (k = 0, temp_index = temp; k < components;
  6362.                          k++, temp_index += element_size) {
  6363.                         if (myswap_bytes) {
  6364.                             totals[k] += __GLU_SWAP_2_BYTES(temp_index);
  6365.                         } else {
  6366.                             totals[k] += *(const GLushort*)temp_index;
  6367.                         }
  6368.                     }
  6369. #else
  6370.                     (*extractPackedPixel)(isSwap,temp,extractTotals);
  6371.                     for (k = 0; k < components; k++) {
  6372.                        totals[k]+= extractTotals[k];
  6373.                     }
  6374. #endif
  6375.                     temp += pixelSizeInBytes;
  6376.                 }
  6377.                 temp0 += rowSizeInBytes;
  6378.             }
  6379.  
  6380.             outindex = (j + (i * widthOut)); /* * (components == 1) */
  6381. #if 0
  6382.             for (k = 0; k < components; k++) {
  6383.                 dataout[outindex + k] = totals[k]/area;
  6384.                 /*printf("totals[%d] = %f\n", k, totals[k]);*/
  6385.             }
  6386. #else
  6387.             for (k = 0; k < components; k++) {
  6388.                 shoveTotals[k]= totals[k]/area;
  6389.             }
  6390.             (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
  6391. #endif
  6392.             lowx_int = highx_int;
  6393.             lowx_float = highx_float;
  6394.             highx_int += convx_int;
  6395.             highx_float += convx_float;
  6396.             if(highx_float > 1) {
  6397.                 highx_float -= 1.0;
  6398.                 highx_int++;
  6399.             }
  6400.         }
  6401.         lowy_int = highy_int;
  6402.         lowy_float = highy_float;
  6403.         highy_int += convy_int;
  6404.         highy_float += convy_float;
  6405.         if(highy_float > 1) {
  6406.             highy_float -= 1.0;
  6407.             highy_int++;
  6408.         }
  6409.     }
  6410.  
  6411.     assert(outindex == (widthOut*heightOut - 1));
  6412. } /* scaleInternalPackedPixel() */
  6413.  
  6414. /* rowSizeInBytes is at least the width (in bytes) due to padding on
  6415.  *  inputs; not always equal. Output NEVER has row padding.
  6416.  */
  6417. static void halveImagePackedPixel(int components,
  6418.                                   void (*extractPackedPixel)
  6419.                                   (int, const void *,GLfloat []),
  6420.                                   void (*shovePackedPixel)
  6421.                                   (const GLfloat [],int, void *),
  6422.                                   GLint width, GLint height,
  6423.                                   const void *dataIn, void *dataOut,
  6424.                                   GLint pixelSizeInBytes,
  6425.                                   GLint rowSizeInBytes, GLint isSwap)
  6426. {
  6427.    /* handle case where there is only 1 column/row */
  6428.    if (width == 1 || height == 1) {
  6429.       assert(!(width == 1 && height == 1)); /* can't be 1x1 */
  6430.       halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
  6431.                               width,height,dataIn,dataOut,pixelSizeInBytes,
  6432.                               rowSizeInBytes,isSwap);
  6433.       return;
  6434.    }
  6435.  
  6436.    {
  6437.       int ii, jj;
  6438.  
  6439.       int halfWidth= width / 2;
  6440.       int halfHeight= height / 2;
  6441.       const char *src= (const char *) dataIn;
  6442.       int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
  6443.       int outIndex= 0;
  6444.  
  6445.       for (ii= 0; ii< halfHeight; ii++) {
  6446.          for (jj= 0; jj< halfWidth; jj++) {
  6447. #define BOX4 4
  6448.             float totals[4];    /* 4 is maximum components */
  6449.             float extractTotals[BOX4][4]; /* 4 is maximum components */
  6450.             int cc;
  6451.  
  6452.             (*extractPackedPixel)(isSwap,src,
  6453.                                   &extractTotals[0][0]);
  6454.             (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
  6455.                                   &extractTotals[1][0]);
  6456.             (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
  6457.                                   &extractTotals[2][0]);
  6458.             (*extractPackedPixel)(isSwap,
  6459.                                   (src+rowSizeInBytes+pixelSizeInBytes),
  6460.                                   &extractTotals[3][0]);
  6461.             for (cc = 0; cc < components; cc++) {
  6462.                int kk;
  6463.  
  6464.                /* grab 4 pixels to average */
  6465.                totals[cc]= 0.0;
  6466.                /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  6467.                 *              extractTotals[2][RED]+extractTotals[3][RED];
  6468.                 * totals[RED]/= 4.0;
  6469.                 */
  6470.                for (kk = 0; kk < BOX4; kk++) {
  6471.                   totals[cc]+= extractTotals[kk][cc];
  6472.                }
  6473.                totals[cc]/= (float)BOX4;
  6474.             }
  6475.             (*shovePackedPixel)(totals,outIndex,dataOut);
  6476.  
  6477.             outIndex++;
  6478.             /* skip over to next square of 4 */
  6479.             src+= pixelSizeInBytes + pixelSizeInBytes;
  6480.          }
  6481.          /* skip past pad bytes, if any, to get to next row */
  6482.          src+= padBytes;
  6483.  
  6484.          /* src is at beginning of a row here, but it's the second row of
  6485.           * the square block of 4 pixels that we just worked on so we
  6486.           * need to go one more row.
  6487.           * i.e.,
  6488.           *                   OO...
  6489.           *           here -->OO...
  6490.           *       but want -->OO...
  6491.           *                   OO...
  6492.           *                   ...
  6493.           */
  6494.          src+= rowSizeInBytes;
  6495.       }
  6496.  
  6497.       /* both pointers must reach one byte after the end */
  6498.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
  6499.       assert(outIndex == halfWidth * halfHeight);
  6500.    }
  6501. } /* halveImagePackedPixel() */
  6502.  
  6503. static void halve1DimagePackedPixel(int components,
  6504.                                     void (*extractPackedPixel)
  6505.                                     (int, const void *,GLfloat []),
  6506.                                     void (*shovePackedPixel)
  6507.                                     (const GLfloat [],int, void *),
  6508.                                     GLint width, GLint height,
  6509.                                     const void *dataIn, void *dataOut,
  6510.                                     GLint pixelSizeInBytes,
  6511.                                     GLint rowSizeInBytes, GLint isSwap)
  6512. {
  6513.    int halfWidth= width / 2;
  6514.    int halfHeight= height / 2;
  6515.    const char *src= (const char *) dataIn;
  6516.    int jj;
  6517.  
  6518.    assert(width == 1 || height == 1); /* must be 1D */
  6519.    assert(width != height);     /* can't be square */
  6520.  
  6521.    if (height == 1) {   /* 1 row */
  6522.       int outIndex= 0;
  6523.  
  6524.       assert(width != 1);       /* widthxheight can't be 1x1 */
  6525.       halfHeight= 1;
  6526.  
  6527.       /* one horizontal row with possible pad bytes */
  6528.  
  6529.       for (jj= 0; jj< halfWidth; jj++) {
  6530. #define BOX2 2
  6531.          float totals[4];       /* 4 is maximum components */
  6532.          float extractTotals[BOX2][4]; /* 4 is maximum components */
  6533.          int cc;
  6534.  
  6535.          /* average two at a time, instead of four */
  6536.          (*extractPackedPixel)(isSwap,src,
  6537.                                &extractTotals[0][0]);
  6538.          (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
  6539.                                &extractTotals[1][0]);                  
  6540.          for (cc = 0; cc < components; cc++) {
  6541.             int kk;
  6542.  
  6543.             /* grab 2 pixels to average */
  6544.             totals[cc]= 0.0;
  6545.             /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
  6546.              * totals[RED]/= 2.0;
  6547.              */
  6548.             for (kk = 0; kk < BOX2; kk++) {
  6549.                totals[cc]+= extractTotals[kk][cc];
  6550.             }
  6551.             totals[cc]/= (float)BOX2;
  6552.          }
  6553.          (*shovePackedPixel)(totals,outIndex,dataOut);
  6554.  
  6555.          outIndex++;
  6556.          /* skip over to next group of 2 */
  6557.          src+= pixelSizeInBytes + pixelSizeInBytes;
  6558.       }
  6559.  
  6560.       {
  6561.          int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
  6562.          src+= padBytes;        /* for assertion only */
  6563.       }
  6564.       assert(src == &((const char *)dataIn)[rowSizeInBytes]);
  6565.       assert(outIndex == halfWidth * halfHeight);
  6566.    }
  6567.    else if (width == 1) { /* 1 column */
  6568.       int outIndex= 0;
  6569.  
  6570.       assert(height != 1);      /* widthxheight can't be 1x1 */
  6571.       halfWidth= 1;
  6572.       /* one vertical column with possible pad bytes per row */
  6573.       /* average two at a time */
  6574.  
  6575.       for (jj= 0; jj< halfHeight; jj++) {
  6576. #define BOX2 2
  6577.          float totals[4];       /* 4 is maximum components */
  6578.          float extractTotals[BOX2][4]; /* 4 is maximum components */
  6579.          int cc;
  6580.  
  6581.          /* average two at a time, instead of four */
  6582.          (*extractPackedPixel)(isSwap,src,
  6583.                                &extractTotals[0][0]);
  6584.          (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
  6585.                                &extractTotals[1][0]);                  
  6586.          for (cc = 0; cc < components; cc++) {
  6587.             int kk;
  6588.  
  6589.             /* grab 2 pixels to average */
  6590.             totals[cc]= 0.0;
  6591.             /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
  6592.              * totals[RED]/= 2.0;
  6593.              */
  6594.             for (kk = 0; kk < BOX2; kk++) {
  6595.                totals[cc]+= extractTotals[kk][cc];
  6596.             }
  6597.             totals[cc]/= (float)BOX2;
  6598.          }
  6599.          (*shovePackedPixel)(totals,outIndex,dataOut);
  6600.  
  6601.          outIndex++;
  6602.          src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
  6603.       }
  6604.  
  6605.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
  6606.       assert(outIndex == halfWidth * halfHeight);
  6607.    }
  6608. } /* halve1DimagePackedPixel() */
  6609.  
  6610. /*===========================================================================*/
  6611.  
  6612. #ifdef RESOLVE_3D_TEXTURE_SUPPORT
  6613. /*
  6614.  * This section ensures that GLU 1.3 will load and run on
  6615.  * a GL 1.1 implementation. It dynamically resolves the
  6616.  * call to glTexImage3D() which might not be available.
  6617.  * Or is it might be supported as an extension.
  6618.  * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
  6619.  */
  6620.  
  6621. typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
  6622.                                                  GLenum internalFormat,
  6623.                                                  GLsizei width, GLsizei height,
  6624.                                                  GLsizei depth, GLint border,
  6625.                                                  GLenum format, GLenum type,
  6626.                                                  const GLvoid *pixels );
  6627.  
  6628. static TexImage3Dproc pTexImage3D = 0;
  6629.  
  6630. #if !defined(_WIN32) && !defined(__WIN32__)
  6631. #  include <dlfcn.h>
  6632. #  include <sys/types.h>
  6633. #else
  6634.   WINGDIAPI PROC  WINAPI wglGetProcAddress(LPCSTR);
  6635. #endif
  6636.  
  6637. static void gluTexImage3D( GLenum target, GLint level,
  6638.                            GLenum internalFormat,
  6639.                            GLsizei width, GLsizei height,
  6640.                            GLsizei depth, GLint border,
  6641.                            GLenum format, GLenum type,
  6642.                            const GLvoid *pixels )
  6643. {
  6644.    if (!pTexImage3D) {
  6645. #if defined(_WIN32) || defined(__WIN32__)
  6646.       pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
  6647.       if (!pTexImage3D)
  6648.          pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
  6649. #else
  6650.       void *libHandle = dlopen("libgl.so", RTLD_LAZY);
  6651.       pTexImage3D = TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
  6652.       if (!pTexImage3D)
  6653.          pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
  6654.       dlclose(libHandle);
  6655. #endif
  6656.    }
  6657.  
  6658.    /* Now call glTexImage3D */
  6659.    if (pTexImage3D)
  6660.       pTexImage3D(target, level, internalFormat, width, height,
  6661.                   depth, border, format, type, pixels);
  6662. }
  6663.  
  6664. #else
  6665.  
  6666. /* Only bind to a GL 1.2 implementation: */
  6667. #define gluTexImage3D glTexImage3D
  6668.  
  6669. #endif
  6670.  
  6671. static GLint imageSize3D(GLint width, GLint height, GLint depth,
  6672.                          GLenum format, GLenum type)
  6673. {
  6674.     int components= elements_per_group(format,type);
  6675.     int bytes_per_row=  bytes_per_element(type) * width;
  6676.  
  6677. assert(width > 0 && height > 0 && depth > 0);
  6678. assert(type != GL_BITMAP);
  6679.  
  6680.     return bytes_per_row * height * depth * components;
  6681. } /* imageSize3D() */
  6682.  
  6683. static void fillImage3D(const PixelStorageModes *psm,
  6684.                         GLint width, GLint height, GLint depth, GLenum format,
  6685.                         GLenum type, GLboolean indexFormat,
  6686.                         const void *userImage, GLushort *newImage)
  6687. {
  6688.    int myswapBytes;
  6689.    int components;
  6690.    int groupsPerLine;
  6691.    int elementSize;
  6692.    int groupSize;
  6693.    int rowSize;
  6694.    int padding;
  6695.    int elementsPerLine;
  6696.    int rowsPerImage;
  6697.    int imageSize;
  6698.    const GLubyte *start, *rowStart, *iter;
  6699.    GLushort *iter2;
  6700.    int ww, hh, dd, k;
  6701.  
  6702.    myswapBytes= psm->unpack_swap_bytes;
  6703.    components= elements_per_group(format,type);
  6704.    if (psm->unpack_row_length > 0) {
  6705.       groupsPerLine= psm->unpack_row_length;
  6706.    }
  6707.    else {
  6708.       groupsPerLine= width;
  6709.    }
  6710.    elementSize= bytes_per_element(type);
  6711.    groupSize= elementSize * components;
  6712.    if (elementSize == 1) myswapBytes= 0;
  6713.  
  6714.    /* 3dstuff begin */
  6715.    if (psm->unpack_image_height > 0) {
  6716.       rowsPerImage= psm->unpack_image_height;
  6717.    }
  6718.    else {
  6719.       rowsPerImage= height;
  6720.    }
  6721.    /* 3dstuff end */
  6722.  
  6723.    rowSize= groupsPerLine * groupSize;
  6724.    padding= rowSize % psm->unpack_alignment;
  6725.    if (padding) {
  6726.       rowSize+= psm->unpack_alignment - padding;
  6727.    }
  6728.  
  6729.    imageSize= rowsPerImage * rowSize; /* 3dstuff */
  6730.  
  6731.    start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
  6732.                                  psm->unpack_skip_pixels * groupSize +
  6733.                                  /*3dstuff*/
  6734.                                  psm->unpack_skip_images * imageSize;
  6735.    elementsPerLine = width * components;
  6736.  
  6737.    iter2= newImage;
  6738.    for (dd= 0; dd < depth; dd++) {
  6739.       rowStart= start;
  6740.  
  6741.       for (hh= 0; hh < height; hh++) {
  6742.          iter= rowStart;
  6743.  
  6744.          for (ww= 0; ww < elementsPerLine; ww++) {
  6745.             Type_Widget widget;
  6746.             float extractComponents[4];
  6747.  
  6748.             switch(type) {
  6749.             case GL_UNSIGNED_BYTE:
  6750.               if (indexFormat) {
  6751.                   *iter2++ = *iter;
  6752.               } else {
  6753.                   *iter2++ = (*iter) * 257;
  6754.               }
  6755.               break;
  6756.             case GL_BYTE:
  6757.               if (indexFormat) {
  6758.                   *iter2++ = *((const GLbyte *) iter);
  6759.               } else {
  6760.                   /* rough approx */
  6761.                   *iter2++ = (*((const GLbyte *) iter)) * 516;
  6762.               }
  6763.               break;
  6764.             case GL_UNSIGNED_BYTE_3_3_2:
  6765.               extract332(0,iter,extractComponents);
  6766.               for (k = 0; k < 3; k++) {
  6767.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6768.               }
  6769.               break;
  6770.             case GL_UNSIGNED_BYTE_2_3_3_REV:
  6771.               extract233rev(0,iter,extractComponents);
  6772.               for (k = 0; k < 3; k++) {
  6773.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6774.               }
  6775.               break;
  6776.             case GL_UNSIGNED_SHORT_5_6_5:                              
  6777.               extract565(myswapBytes,iter,extractComponents);
  6778.               for (k = 0; k < 3; k++) {
  6779.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6780.               }
  6781.               break;
  6782.             case GL_UNSIGNED_SHORT_5_6_5_REV:                          
  6783.               extract565rev(myswapBytes,iter,extractComponents);
  6784.               for (k = 0; k < 3; k++) {
  6785.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6786.               }
  6787.               break;
  6788.             case GL_UNSIGNED_SHORT_4_4_4_4:            
  6789.               extract4444(myswapBytes,iter,extractComponents);
  6790.               for (k = 0; k < 4; k++) {
  6791.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6792.               }
  6793.               break;
  6794.             case GL_UNSIGNED_SHORT_4_4_4_4_REV:        
  6795.               extract4444rev(myswapBytes,iter,extractComponents);
  6796.               for (k = 0; k < 4; k++) {
  6797.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6798.               }
  6799.               break;
  6800.             case GL_UNSIGNED_SHORT_5_5_5_1:            
  6801.               extract5551(myswapBytes,iter,extractComponents);
  6802.               for (k = 0; k < 4; k++) {
  6803.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6804.               }
  6805.               break;
  6806.             case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  6807.               extract1555rev(myswapBytes,iter,extractComponents);
  6808.               for (k = 0; k < 4; k++) {
  6809.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6810.               }
  6811.               break;
  6812.             case GL_UNSIGNED_SHORT:
  6813.             case GL_SHORT:
  6814.               if (myswapBytes) {
  6815.                   widget.ub[0] = iter[1];
  6816.                   widget.ub[1] = iter[0];
  6817.               } else {
  6818.                   widget.ub[0] = iter[0];
  6819.                   widget.ub[1] = iter[1];
  6820.               }
  6821.               if (type == GL_SHORT) {
  6822.                   if (indexFormat) {
  6823.                       *iter2++ = widget.s[0];
  6824.                   } else {
  6825.                       /* rough approx */
  6826.                       *iter2++ = widget.s[0]*2;
  6827.                   }
  6828.               } else {
  6829.                   *iter2++ = widget.us[0];
  6830.               }
  6831.               break;
  6832.             case GL_UNSIGNED_INT_8_8_8_8:              
  6833.               extract8888(myswapBytes,iter,extractComponents);
  6834.               for (k = 0; k < 4; k++) {
  6835.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6836.               }
  6837.               break;
  6838.             case GL_UNSIGNED_INT_8_8_8_8_REV:          
  6839.               extract8888rev(myswapBytes,iter,extractComponents);
  6840.               for (k = 0; k < 4; k++) {
  6841.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6842.               }
  6843.               break;
  6844.             case GL_UNSIGNED_INT_10_10_10_2:           
  6845.               extract1010102(myswapBytes,iter,extractComponents);
  6846.               for (k = 0; k < 4; k++) {
  6847.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6848.               }
  6849.               break;
  6850.             case GL_UNSIGNED_INT_2_10_10_10_REV:
  6851.               extract2101010rev(myswapBytes,iter,extractComponents);
  6852.               for (k = 0; k < 4; k++) {
  6853.                 *iter2++ = (GLushort)(extractComponents[k]*65535);
  6854.               }
  6855.               break;
  6856.             case GL_INT:
  6857.             case GL_UNSIGNED_INT:
  6858.             case GL_FLOAT:
  6859.               if (myswapBytes) {
  6860.                   widget.ub[0] = iter[3];
  6861.                   widget.ub[1] = iter[2];
  6862.                   widget.ub[2] = iter[1];
  6863.                   widget.ub[3] = iter[0];
  6864.               } else {
  6865.                   widget.ub[0] = iter[0];
  6866.                   widget.ub[1] = iter[1];
  6867.                   widget.ub[2] = iter[2];
  6868.                   widget.ub[3] = iter[3];
  6869.               }
  6870.               if (type == GL_FLOAT) {
  6871.                   if (indexFormat) {
  6872.                       *iter2++ = widget.f;
  6873.                   } else {
  6874.                       *iter2++ = 65535 * widget.f;
  6875.                   }
  6876.               } else if (type == GL_UNSIGNED_INT) {
  6877.                   if (indexFormat) {
  6878.                       *iter2++ = widget.ui;
  6879.                   } else {
  6880.                       *iter2++ = widget.ui >> 16;
  6881.                   }
  6882.               } else {
  6883.                   if (indexFormat) {
  6884.                       *iter2++ = widget.i;
  6885.                   } else {
  6886.                       *iter2++ = widget.i >> 15;
  6887.                   }
  6888.               }
  6889.               break;
  6890.             default:
  6891.               assert(0);
  6892.             }
  6893.  
  6894.             iter+= elementSize;
  6895.          } /* for ww */
  6896.          rowStart+= rowSize;
  6897.  
  6898.          iter= rowStart;        /* for assertion purposes */
  6899.       } /* for hh */
  6900.  
  6901.       start+= imageSize;
  6902.    } /* for dd */
  6903.  
  6904.    /* iterators should be one byte past end */
  6905.    if (!isTypePackedPixel(type)) {
  6906.       assert(iter2 == &newImage[width*height*depth*components]);
  6907.    }
  6908.    else {
  6909.       assert(iter2 == &newImage[width*height*depth*
  6910.                                 elements_per_group(format,0)]);
  6911.    }
  6912.    assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
  6913.                                         psm->unpack_skip_rows * rowSize +
  6914.                                         psm->unpack_skip_pixels * groupSize +
  6915.                                         /*3dstuff*/
  6916.                                         psm->unpack_skip_images * imageSize] );
  6917. } /* fillImage3D () */
  6918.  
  6919. static void scaleInternal3D(GLint components,
  6920.                             GLint widthIn, GLint heightIn, GLint depthIn,
  6921.                             const GLushort *dataIn,
  6922.                             GLint widthOut, GLint heightOut, GLint depthOut,
  6923.                             GLushort *dataOut)
  6924. {
  6925.     float x, lowx, highx, convx, halfconvx;
  6926.     float y, lowy, highy, convy, halfconvy;
  6927.     float z, lowz, highz, convz, halfconvz;
  6928.     float xpercent,ypercent,zpercent;
  6929.     float percent;
  6930.     /* Max components in a format is 4, so... */
  6931.     float totals[4];
  6932.     float volume;
  6933.     int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
  6934.     int temp;
  6935.  
  6936.     convz = (float) depthIn/depthOut;
  6937.     convy = (float) heightIn/heightOut;
  6938.     convx = (float) widthIn/widthOut;
  6939.     halfconvx = convx/2;
  6940.     halfconvy = convy/2;
  6941.     halfconvz = convz/2;
  6942.     for (d = 0; d < depthOut; d++) {
  6943.        z = convz * (d+0.5);
  6944.        if (depthIn > depthOut) {
  6945.            highz = z + halfconvz;
  6946.            lowz = z - halfconvz;
  6947.        } else {
  6948.            highz = z + 0.5;
  6949.            lowz = z - 0.5;
  6950.        }
  6951.        for (i = 0; i < heightOut; i++) {
  6952.            y = convy * (i+0.5);
  6953.            if (heightIn > heightOut) {
  6954.                highy = y + halfconvy;
  6955.                lowy = y - halfconvy;
  6956.            } else {
  6957.                highy = y + 0.5;
  6958.                lowy = y - 0.5;
  6959.            }
  6960.            for (j = 0; j < widthOut; j++) {
  6961.                x = convx * (j+0.5);
  6962.                if (widthIn > widthOut) {
  6963.                    highx = x + halfconvx;
  6964.                    lowx = x - halfconvx;
  6965.                } else {
  6966.                    highx = x + 0.5;
  6967.                    lowx = x - 0.5;
  6968.                }
  6969.  
  6970.                /*
  6971.                ** Ok, now apply box filter to box that goes from (lowx, lowy,
  6972.                ** lowz) to (highx, highy, highz) on input data into this pixel
  6973.                ** on output data.
  6974.                */
  6975.                totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  6976.                volume = 0.0;
  6977.  
  6978.                z = lowz;
  6979.                zint = floor(z);
  6980.                while (z < highz) {
  6981.                   zindex = (zint + depthIn) % depthIn;
  6982.                   if (highz < zint+1) {
  6983.                       zpercent = highz - z;
  6984.                   } else {
  6985.                       zpercent = zint+1 - z;
  6986.                   }
  6987.  
  6988.                   y = lowy;
  6989.                   yint = floor(y);
  6990.                   while (y < highy) {
  6991.                       yindex = (yint + heightIn) % heightIn;
  6992.                       if (highy < yint+1) {
  6993.                           ypercent = highy - y;
  6994.                       } else {
  6995.                           ypercent = yint+1 - y;
  6996.                       }
  6997.  
  6998.                       x = lowx;
  6999.                       xint = floor(x);
  7000.  
  7001.                       while (x < highx) {
  7002.                           xindex = (xint + widthIn) % widthIn;
  7003.                           if (highx < xint+1) {
  7004.                               xpercent = highx - x;
  7005.                           } else {
  7006.                               xpercent = xint+1 - x;
  7007.                           }
  7008.  
  7009.                           percent = xpercent * ypercent * zpercent;
  7010.                           volume += percent;
  7011.  
  7012.                           temp = (xindex + (yindex*widthIn) +
  7013.                                   (zindex*widthIn*heightIn)) * components;
  7014.                           for (k = 0; k < components; k++) {
  7015.                               assert(0 <= (temp+k) &&
  7016.                                      (temp+k) <
  7017.                                      (widthIn*heightIn*depthIn*components));
  7018.                               totals[k] += dataIn[temp + k] * percent;
  7019.                           }
  7020.  
  7021.                           xint++;
  7022.                           x = xint;
  7023.                       } /* while x */
  7024.  
  7025.                       yint++;
  7026.                       y = yint;
  7027.                   } /* while y */
  7028.  
  7029.                   zint++;
  7030.                   z = zint;
  7031.                } /* while z */
  7032.  
  7033.                temp = (j + (i * widthOut) +
  7034.                        (d*widthOut*heightOut)) * components;
  7035.                for (k = 0; k < components; k++) {
  7036.                    /* totals[] should be rounded in the case of enlarging an
  7037.                     * RGB ramp when the type is 332 or 4444
  7038.                     */
  7039.                    assert(0 <= (temp+k) &&
  7040.                           (temp+k) < (widthOut*heightOut*depthOut*components));
  7041.                    dataOut[temp + k] = (totals[k]+0.5)/volume;
  7042.                }
  7043.            } /* for j */
  7044.        } /* for i */
  7045.     } /* for d */
  7046. } /* scaleInternal3D() */
  7047.  
  7048. static void emptyImage3D(const PixelStorageModes *psm,
  7049.                          GLint width, GLint height, GLint depth,
  7050.                          GLenum format, GLenum type, GLboolean indexFormat,
  7051.                          const GLushort *oldImage, void *userImage)
  7052. {
  7053.    int myswapBytes;
  7054.    int components;
  7055.    int groupsPerLine;
  7056.    int elementSize;
  7057.    int groupSize;
  7058.    int rowSize;
  7059.    int padding;
  7060.    GLubyte *start, *rowStart, *iter;
  7061.    int elementsPerLine;
  7062.    const GLushort *iter2;
  7063.    int ii, jj, dd, k;
  7064.    int rowsPerImage;
  7065.    int imageSize;
  7066.  
  7067.    myswapBytes= psm->pack_swap_bytes;
  7068.    components = elements_per_group(format,type);
  7069.    if (psm->pack_row_length > 0) {
  7070.       groupsPerLine = psm->pack_row_length;
  7071.    }
  7072.    else {
  7073.       groupsPerLine = width;
  7074.    }
  7075.  
  7076.    elementSize= bytes_per_element(type);
  7077.    groupSize= elementSize * components;
  7078.    if (elementSize == 1) myswapBytes= 0;
  7079.  
  7080.    /* 3dstuff begin */
  7081.    if (psm->pack_image_height > 0) {
  7082.       rowsPerImage= psm->pack_image_height;
  7083.    }
  7084.    else {
  7085.       rowsPerImage= height;
  7086.    }
  7087.  
  7088.    /* 3dstuff end */
  7089.  
  7090.    rowSize = groupsPerLine * groupSize;
  7091.    padding = rowSize % psm->pack_alignment;
  7092.    if (padding) {
  7093.       rowSize+= psm->pack_alignment - padding;
  7094.    }
  7095.  
  7096.    imageSize= rowsPerImage * rowSize; /* 3dstuff */
  7097.  
  7098.    start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
  7099.                                   psm->pack_skip_pixels * groupSize +
  7100.                                   /*3dstuff*/
  7101.                                   psm->pack_skip_images * imageSize;
  7102.    elementsPerLine= width * components;
  7103.  
  7104.    iter2 = oldImage;
  7105.    for (dd= 0; dd < depth; dd++) {
  7106.       rowStart= start;
  7107.  
  7108.       for (ii= 0; ii< height; ii++) {
  7109.          iter = rowStart;
  7110.  
  7111.          for (jj = 0; jj < elementsPerLine; jj++) {
  7112.             Type_Widget widget;
  7113.             float shoveComponents[4];
  7114.  
  7115.             switch(type){
  7116.             case GL_UNSIGNED_BYTE:
  7117.               if (indexFormat) {
  7118.                   *iter = *iter2++;
  7119.               } else {
  7120.                   *iter = *iter2++ >> 8;
  7121.               }
  7122.               break;
  7123.             case GL_BYTE:
  7124.               if (indexFormat) {
  7125.                   *((GLbyte *) iter) = *iter2++;
  7126.               } else {
  7127.                   *((GLbyte *) iter) = *iter2++ >> 9;
  7128.               }
  7129.               break;
  7130.             case GL_UNSIGNED_BYTE_3_3_2:
  7131.               for (k = 0; k < 3; k++) {
  7132.                  shoveComponents[k]= *iter2++ / 65535.0;
  7133.               }
  7134.               shove332(shoveComponents,0,(void *)iter);
  7135.               break;
  7136.             case GL_UNSIGNED_BYTE_2_3_3_REV:
  7137.               for (k = 0; k < 3; k++) {
  7138.                  shoveComponents[k]= *iter2++ / 65535.0;
  7139.               }
  7140.               shove233rev(shoveComponents,0,(void *)iter);
  7141.               break;
  7142.             case GL_UNSIGNED_SHORT_5_6_5:              
  7143.               for (k = 0; k < 3; k++) {
  7144.                  shoveComponents[k]= *iter2++ / 65535.0;
  7145.               }
  7146.               shove565(shoveComponents,0,(void *)&widget.us[0]);
  7147.               if (myswapBytes) {
  7148.                  iter[0] = widget.ub[1];
  7149.                  iter[1] = widget.ub[0];
  7150.               }
  7151.               else {
  7152.                  *(GLushort *)iter = widget.us[0];
  7153.               }
  7154.               break;
  7155.             case GL_UNSIGNED_SHORT_5_6_5_REV:          
  7156.               for (k = 0; k < 3; k++) {
  7157.                  shoveComponents[k]= *iter2++ / 65535.0;
  7158.               }
  7159.               shove565rev(shoveComponents,0,(void *)&widget.us[0]);
  7160.               if (myswapBytes) {
  7161.                  iter[0] = widget.ub[1];
  7162.                  iter[1] = widget.ub[0];
  7163.               }
  7164.               else {
  7165.                  *(GLushort *)iter = widget.us[0];
  7166.               }
  7167.               break;
  7168.             case GL_UNSIGNED_SHORT_4_4_4_4:
  7169.               for (k = 0; k < 4; k++) {
  7170.                  shoveComponents[k]= *iter2++ / 65535.0;
  7171.               }
  7172.               shove4444(shoveComponents,0,(void *)&widget.us[0]);
  7173.               if (myswapBytes) {
  7174.                  iter[0] = widget.ub[1];
  7175.                  iter[1] = widget.ub[0];
  7176.               } else {
  7177.                  *(GLushort *)iter = widget.us[0];
  7178.               }
  7179.               break;
  7180.             case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  7181.               for (k = 0; k < 4; k++) {
  7182.                  shoveComponents[k]= *iter2++ / 65535.0;
  7183.               }
  7184.               shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
  7185.               if (myswapBytes) {
  7186.                  iter[0] = widget.ub[1];
  7187.                  iter[1] = widget.ub[0];
  7188.               } else {
  7189.                  *(GLushort *)iter = widget.us[0];
  7190.               }
  7191.               break;
  7192.             case GL_UNSIGNED_SHORT_5_5_5_1:
  7193.               for (k = 0; k < 4; k++) {
  7194.                  shoveComponents[k]= *iter2++ / 65535.0;
  7195.               }
  7196.               shove5551(shoveComponents,0,(void *)&widget.us[0]);
  7197.               if (myswapBytes) {
  7198.                  iter[0] = widget.ub[1];
  7199.                  iter[1] = widget.ub[0];
  7200.               } else {
  7201.                  *(GLushort *)iter = widget.us[0];
  7202.               }
  7203.               break;
  7204.             case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  7205.               for (k = 0; k < 4; k++) {
  7206.                  shoveComponents[k]= *iter2++ / 65535.0;
  7207.               }
  7208.               shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
  7209.               if (myswapBytes) {
  7210.                  iter[0] = widget.ub[1];
  7211.                  iter[1] = widget.ub[0];
  7212.               } else {
  7213.                  *(GLushort *)iter = widget.us[0];
  7214.               }
  7215.               break;
  7216.             case GL_UNSIGNED_SHORT:
  7217.             case GL_SHORT:
  7218.               if (type == GL_SHORT) {
  7219.                   if (indexFormat) {
  7220.                       widget.s[0] = *iter2++;
  7221.                   } else {
  7222.                       widget.s[0] = *iter2++ >> 1;
  7223.                   }
  7224.               } else {
  7225.                   widget.us[0] = *iter2++;
  7226.               }
  7227.               if (myswapBytes) {
  7228.                   iter[0] = widget.ub[1];
  7229.                   iter[1] = widget.ub[0];
  7230.               } else {
  7231.                   iter[0] = widget.ub[0];
  7232.                   iter[1] = widget.ub[1];
  7233.               }
  7234.               break;
  7235.             case GL_UNSIGNED_INT_8_8_8_8:
  7236.                for (k = 0; k < 4; k++) {
  7237.                   shoveComponents[k]= *iter2++ / 65535.0;
  7238.                }
  7239.                shove8888(shoveComponents,0,(void *)&widget.ui);
  7240.                if (myswapBytes) {
  7241.                    iter[3] = widget.ub[0];
  7242.                    iter[2] = widget.ub[1];
  7243.                    iter[1] = widget.ub[2];
  7244.                    iter[0] = widget.ub[3];
  7245.                } else {
  7246.                    *(GLuint *)iter= widget.ui;
  7247.                }
  7248.                break;
  7249.             case GL_UNSIGNED_INT_8_8_8_8_REV:
  7250.                for (k = 0; k < 4; k++) {
  7251.                   shoveComponents[k]= *iter2++ / 65535.0;
  7252.                }
  7253.                shove8888rev(shoveComponents,0,(void *)&widget.ui);
  7254.                if (myswapBytes) {
  7255.                    iter[3] = widget.ub[0];
  7256.                    iter[2] = widget.ub[1];
  7257.                    iter[1] = widget.ub[2];
  7258.                    iter[0] = widget.ub[3];
  7259.                } else {
  7260.                    *(GLuint *)iter= widget.ui;
  7261.                }
  7262.                break;
  7263.             case GL_UNSIGNED_INT_10_10_10_2:
  7264.                for (k = 0; k < 4; k++) {
  7265.                   shoveComponents[k]= *iter2++ / 65535.0;
  7266.                }
  7267.                shove1010102(shoveComponents,0,(void *)&widget.ui);
  7268.                if (myswapBytes) {
  7269.                    iter[3] = widget.ub[0];
  7270.                    iter[2] = widget.ub[1];
  7271.                    iter[1] = widget.ub[2];
  7272.                    iter[0] = widget.ub[3];
  7273.                } else {
  7274.                    *(GLuint *)iter= widget.ui;
  7275.                }
  7276.                break;
  7277.             case GL_UNSIGNED_INT_2_10_10_10_REV:
  7278.                for (k = 0; k < 4; k++) {
  7279.                   shoveComponents[k]= *iter2++ / 65535.0;
  7280.                }
  7281.                shove2101010rev(shoveComponents,0,(void *)&widget.ui);
  7282.                if (myswapBytes) {
  7283.                    iter[3] = widget.ub[0];
  7284.                    iter[2] = widget.ub[1];
  7285.                    iter[1] = widget.ub[2];
  7286.                    iter[0] = widget.ub[3];
  7287.                } else {
  7288.                    *(GLuint *)iter= widget.ui;
  7289.                }
  7290.                break;
  7291.             case GL_INT:
  7292.             case GL_UNSIGNED_INT:
  7293.             case GL_FLOAT:
  7294.               if (type == GL_FLOAT) {
  7295.                   if (indexFormat) {
  7296.                       widget.f = *iter2++;
  7297.                   } else {
  7298.                       widget.f = *iter2++ / (float) 65535.0;
  7299.                   }
  7300.               } else if (type == GL_UNSIGNED_INT) {
  7301.                   if (indexFormat) {
  7302.                       widget.ui = *iter2++;
  7303.                   } else {
  7304.                       widget.ui = (unsigned int) *iter2++ * 65537;
  7305.                   }
  7306.               } else {
  7307.                   if (indexFormat) {
  7308.                       widget.i = *iter2++;
  7309.                   } else {
  7310.                       widget.i = ((unsigned int) *iter2++ * 65537)/2;
  7311.                   }
  7312.               }
  7313.               if (myswapBytes) {
  7314.                   iter[3] = widget.ub[0];
  7315.                   iter[2] = widget.ub[1];
  7316.                   iter[1] = widget.ub[2];
  7317.                   iter[0] = widget.ub[3];
  7318.               } else {
  7319.                   iter[0] = widget.ub[0];
  7320.                   iter[1] = widget.ub[1];
  7321.                   iter[2] = widget.ub[2];
  7322.                   iter[3] = widget.ub[3];
  7323.               }
  7324.               break;
  7325.             default:
  7326.                assert(0);
  7327.             }
  7328.  
  7329.             iter+= elementSize;
  7330.          }  /* for jj */
  7331.  
  7332.          rowStart+= rowSize;
  7333.       } /* for ii */
  7334.  
  7335.       start+= imageSize;
  7336.    } /* for dd */
  7337.  
  7338.    /* iterators should be one byte past end */
  7339.    if (!isTypePackedPixel(type)) {
  7340.       assert(iter2 == &oldImage[width*height*depth*components]);
  7341.    }
  7342.    else {
  7343.       assert(iter2 == &oldImage[width*height*depth*
  7344.                                 elements_per_group(format,0)]);
  7345.    }
  7346.    assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
  7347.                                         psm->unpack_skip_rows * rowSize +
  7348.                                         psm->unpack_skip_pixels * groupSize +
  7349.                                         /*3dstuff*/
  7350.                                         psm->unpack_skip_images * imageSize] );
  7351. } /* emptyImage3D() */
  7352.  
  7353. static
  7354. int gluScaleImage3D(GLenum format,
  7355.                     GLint widthIn, GLint heightIn, GLint depthIn,
  7356.                     GLenum typeIn, const void *dataIn,
  7357.                     GLint widthOut, GLint heightOut, GLint depthOut,
  7358.                     GLenum typeOut, void *dataOut)
  7359. {
  7360.    int components;
  7361.    GLushort *beforeImage, *afterImage;
  7362.    PixelStorageModes psm;
  7363.  
  7364.    if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
  7365.        widthOut == 0 || heightOut == 0 || depthOut == 0) {
  7366.       return 0;
  7367.    }
  7368.  
  7369.    if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
  7370.        widthOut < 0 || heightOut < 0 || depthOut < 0) {
  7371.       return GLU_INVALID_VALUE;
  7372.    }
  7373.  
  7374.    if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
  7375.        typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
  7376.       return GLU_INVALID_ENUM;
  7377.    }
  7378.    if (!isLegalFormatForPackedPixelType(format, typeIn)) {
  7379.       return GLU_INVALID_OPERATION;
  7380.    }
  7381.    if (!isLegalFormatForPackedPixelType(format, typeOut)) {
  7382.       return GLU_INVALID_OPERATION;
  7383.    }
  7384.  
  7385.    beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
  7386.                                     GL_UNSIGNED_SHORT));
  7387.    afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
  7388.                                    GL_UNSIGNED_SHORT));
  7389.    if (beforeImage == NULL || afterImage == NULL) {
  7390.        free(beforeImage);
  7391.        free(afterImage);
  7392.        return GLU_OUT_OF_MEMORY;
  7393.    }
  7394.    retrieveStoreModes3D(&psm);
  7395.  
  7396.    fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
  7397.                dataIn, beforeImage);
  7398.    components = elements_per_group(format,0);
  7399.    scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
  7400.                    widthOut,heightOut,depthOut,afterImage);
  7401.    emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
  7402.                 is_index(format),afterImage, dataOut);
  7403.    free((void *) beforeImage);
  7404.    free((void *) afterImage);
  7405.  
  7406.    return 0;
  7407. } /* gluScaleImage3D() */
  7408.  
  7409.  
  7410. static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
  7411.                          GLint internalFormat, GLenum format, GLenum type,
  7412.                          GLint *newWidth, GLint *newHeight, GLint *newDepth)
  7413. {
  7414.    GLint widthPowerOf2= nearestPower(width);
  7415.    GLint heightPowerOf2= nearestPower(height);         
  7416.    GLint depthPowerOf2= nearestPower(depth);
  7417.    GLint proxyWidth;
  7418.  
  7419.    do {
  7420.       /* compute level 1 width & height & depth, clamping each at 1 */
  7421.       GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
  7422.                               widthPowerOf2 >> 1 :
  7423.                               widthPowerOf2;
  7424.       GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
  7425.                                heightPowerOf2 >> 1 :
  7426.                                heightPowerOf2;
  7427.       GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
  7428.                               depthPowerOf2 >> 1 :
  7429.                               depthPowerOf2;
  7430.       GLenum proxyTarget = GL_PROXY_TEXTURE_3D;
  7431.       assert(widthAtLevelOne > 0);
  7432.       assert(heightAtLevelOne > 0);
  7433.       assert(depthAtLevelOne > 0);
  7434.  
  7435.       /* does width x height x depth at level 1 & all their mipmaps fit? */
  7436.       assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D);
  7437.       gluTexImage3D(proxyTarget, 1, /* must be non-zero */
  7438.                     internalFormat,
  7439.                     widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
  7440.                     0,format,type,NULL);
  7441.       glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
  7442.       /* does it fit??? */
  7443.       if (proxyWidth == 0) { /* nope, so try again with these sizes */
  7444.          if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
  7445.              depthPowerOf2 == 1) {
  7446.             *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
  7447.             return;
  7448.          }
  7449.          widthPowerOf2= widthAtLevelOne;
  7450.          heightPowerOf2= heightAtLevelOne;
  7451.          depthPowerOf2= depthAtLevelOne;
  7452.       }
  7453.       /* else it does fit */
  7454.    } while (proxyWidth == 0);
  7455.    /* loop must terminate! */
  7456.  
  7457.    /* return the width & height at level 0 that fits */
  7458.    *newWidth= widthPowerOf2;
  7459.    *newHeight= heightPowerOf2;
  7460.    *newDepth= depthPowerOf2;
  7461. /*printf("Proxy Textures\n");*/
  7462. } /* closestFit3D() */
  7463.  
  7464. static void halveImagePackedPixelSlice(int components,
  7465.                                        void (*extractPackedPixel)
  7466.                                        (int, const void *,GLfloat []),
  7467.                                        void (*shovePackedPixel)
  7468.                                        (const GLfloat [],int, void *),
  7469.                                        GLint width, GLint height, GLint depth,
  7470.                                        const void *dataIn, void *dataOut,
  7471.                                        GLint pixelSizeInBytes,
  7472.                                        GLint rowSizeInBytes,
  7473.                                        GLint imageSizeInBytes,
  7474.                                        GLint isSwap)
  7475. {
  7476.    int ii, jj;
  7477.    int halfWidth= width / 2;
  7478.    int halfHeight= height / 2;
  7479.    int halfDepth= depth / 2;
  7480.    const char *src= (const char *)dataIn;
  7481.    int outIndex= 0;
  7482.  
  7483.    assert((width == 1 || height == 1) && depth >= 2);
  7484.  
  7485.    if (width == height) {       /* a 1-pixel column viewed from top */
  7486.       assert(width == 1 && height == 1);
  7487.       assert(depth >= 2);
  7488.  
  7489.       for (ii= 0; ii< halfDepth; ii++) {
  7490.          float totals[4];
  7491.          float extractTotals[BOX2][4];
  7492.          int cc;
  7493.  
  7494.          (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
  7495.          (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
  7496.                                &extractTotals[1][0]);
  7497.          for (cc = 0; cc < components; cc++) {
  7498.             int kk;
  7499.  
  7500.             /* average 2 pixels since only a column */
  7501.             totals[cc]= 0.0;
  7502.             /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
  7503.              * totals[RED]/= 2.0;
  7504.              */
  7505.             for (kk = 0; kk < BOX2; kk++) {
  7506.               totals[cc]+= extractTotals[kk][cc];
  7507.             }
  7508.             totals[cc]/= (float)BOX2;
  7509.          } /* for cc */
  7510.        
  7511.          (*shovePackedPixel)(totals,outIndex,dataOut);
  7512.          outIndex++;
  7513.          /* skip over to next group of 2 */
  7514.          src+= imageSizeInBytes + imageSizeInBytes;
  7515.       } /* for ii */
  7516.    }
  7517.    else if (height == 1) {      /* horizontal slice viewed from top */
  7518.       assert(width != 1);
  7519.  
  7520.       for (ii= 0; ii< halfDepth; ii++) {
  7521.          for (jj= 0; jj< halfWidth; jj++) {
  7522.              float totals[4];
  7523.              float extractTotals[BOX4][4];
  7524.              int cc;
  7525.  
  7526.              (*extractPackedPixel)(isSwap,src,
  7527.                                    &extractTotals[0][0]);
  7528.              (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
  7529.                                    &extractTotals[1][0]);
  7530.              (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
  7531.                                    &extractTotals[2][0]);
  7532.              (*extractPackedPixel)(isSwap,
  7533.                                    (src+imageSizeInBytes+pixelSizeInBytes),
  7534.                                    &extractTotals[3][0]);
  7535.              for (cc = 0; cc < components; cc++) {
  7536.                 int kk;
  7537.  
  7538.                 /* grab 4 pixels to average */
  7539.                 totals[cc]= 0.0;
  7540.                 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  7541.                  *              extractTotals[2][RED]+extractTotals[3][RED];
  7542.                  * totals[RED]/= 4.0;
  7543.                  */
  7544.                 for (kk = 0; kk < BOX4; kk++) {
  7545.                    totals[cc]+= extractTotals[kk][cc];
  7546.                 }
  7547.                 totals[cc]/= (float)BOX4;
  7548.              }
  7549.              (*shovePackedPixel)(totals,outIndex,dataOut);
  7550.  
  7551.              outIndex++;
  7552.              /* skip over to next horizontal square of 4 */
  7553.              src+= imageSizeInBytes + imageSizeInBytes;
  7554.          }
  7555.       }
  7556.  
  7557.       /* assert() */
  7558.    }
  7559.    else if (width == 1) {       /* vertical slice viewed from top */
  7560.       assert(height != 1);
  7561.  
  7562.       for (ii= 0; ii< halfDepth; ii++) {
  7563.          for (jj= 0; jj< halfHeight; jj++) {
  7564.             float totals[4];
  7565.             float extractTotals[BOX4][4];
  7566.             int cc;
  7567.  
  7568.             (*extractPackedPixel)(isSwap,src,
  7569.                                   &extractTotals[0][0]);
  7570.             (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
  7571.                                   &extractTotals[1][0]);
  7572.             (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
  7573.                                   &extractTotals[2][0]);
  7574.             (*extractPackedPixel)(isSwap,
  7575.                                   (src+imageSizeInBytes+rowSizeInBytes),
  7576.                                   &extractTotals[3][0]);
  7577.             for (cc = 0; cc < components; cc++) {
  7578.                int kk;
  7579.  
  7580.                /* grab 4 pixels to average */
  7581.                totals[cc]= 0.0;
  7582.                /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  7583.                 *              extractTotals[2][RED]+extractTotals[3][RED];
  7584.                 * totals[RED]/= 4.0;
  7585.                 */
  7586.                for (kk = 0; kk < BOX4; kk++) {
  7587.                   totals[cc]+= extractTotals[kk][cc];
  7588.                }
  7589.                totals[cc]/= (float)BOX4;
  7590.             }
  7591.             (*shovePackedPixel)(totals,outIndex,dataOut);
  7592.  
  7593.             outIndex++;
  7594.  
  7595.             /* skip over to next vertical square of 4 */
  7596.             src+= imageSizeInBytes + imageSizeInBytes;
  7597.          }
  7598.       }
  7599.       /* assert() */
  7600.    }
  7601.  
  7602. } /* halveImagePackedPixelSlice() */
  7603.  
  7604. static void halveImagePackedPixel3D(int components,
  7605.                                     void (*extractPackedPixel)
  7606.                                     (int, const void *,GLfloat []),
  7607.                                     void (*shovePackedPixel)
  7608.                                     (const GLfloat [],int, void *),
  7609.                                     GLint width, GLint height, GLint depth,
  7610.                                     const void *dataIn, void *dataOut,
  7611.                                     GLint pixelSizeInBytes,
  7612.                                     GLint rowSizeInBytes,
  7613.                                     GLint imageSizeInBytes,
  7614.                                     GLint isSwap)
  7615. {
  7616.    if (depth == 1) {
  7617.       assert(1 <= width && 1 <= height);
  7618.  
  7619.       halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
  7620.                             width,height,dataIn,dataOut,pixelSizeInBytes,
  7621.                             rowSizeInBytes,isSwap);
  7622.       return;
  7623.    }
  7624.    /* a horizontal or vertical slice viewed from top */
  7625.    else if (width == 1 || height == 1) {
  7626.       assert(1 <= depth);
  7627.  
  7628.       halveImagePackedPixelSlice(components,
  7629.                                  extractPackedPixel,shovePackedPixel,
  7630.                                  width, height, depth, dataIn, dataOut,
  7631.                                  pixelSizeInBytes, rowSizeInBytes,
  7632.                                  imageSizeInBytes, isSwap);
  7633.       return;
  7634.    }
  7635.    {
  7636.       int ii, jj, dd;
  7637.  
  7638.       int halfWidth= width / 2;
  7639.       int halfHeight= height / 2;
  7640.       int halfDepth= depth / 2;
  7641.       const char *src= (const char *) dataIn;
  7642.       int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
  7643.       int outIndex= 0;
  7644.  
  7645.       for (dd= 0; dd < halfDepth; dd++) {
  7646.          for (ii= 0; ii< halfHeight; ii++) {
  7647.             for (jj= 0; jj< halfWidth; jj++) {
  7648. #define BOX8 8
  7649.                float totals[4]; /* 4 is maximum components */
  7650.                float extractTotals[BOX8][4]; /* 4 is maximum components */
  7651.                int cc;
  7652.  
  7653.                (*extractPackedPixel)(isSwap,src,
  7654.                                      &extractTotals[0][0]);
  7655.                (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
  7656.                                      &extractTotals[1][0]);
  7657.                (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
  7658.                                      &extractTotals[2][0]);
  7659.                (*extractPackedPixel)(isSwap,
  7660.                                      (src+rowSizeInBytes+pixelSizeInBytes),
  7661.                                      &extractTotals[3][0]);
  7662.  
  7663.                (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
  7664.                                      &extractTotals[4][0]);
  7665.                (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
  7666.                                      &extractTotals[5][0]);
  7667.                (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
  7668.                                      &extractTotals[6][0]);
  7669.                (*extractPackedPixel)(isSwap,
  7670.                                      (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
  7671.                                      &extractTotals[7][0]);
  7672.                for (cc = 0; cc < components; cc++) {
  7673.                   int kk;
  7674.  
  7675.                   /* grab 8 pixels to average */
  7676.                   totals[cc]= 0.0;
  7677.                   /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  7678.                    *              extractTotals[2][RED]+extractTotals[3][RED]+
  7679.                    *              extractTotals[4][RED]+extractTotals[5][RED]+
  7680.                    *              extractTotals[6][RED]+extractTotals[7][RED];
  7681.                    * totals[RED]/= 8.0;
  7682.                    */
  7683.                   for (kk = 0; kk < BOX8; kk++) {
  7684.                      totals[cc]+= extractTotals[kk][cc];
  7685.                   }
  7686.                   totals[cc]/= (float)BOX8;
  7687.                }
  7688.                (*shovePackedPixel)(totals,outIndex,dataOut);
  7689.  
  7690.                outIndex++;
  7691.                /* skip over to next square of 4 */
  7692.                src+= pixelSizeInBytes + pixelSizeInBytes;
  7693.             }
  7694.             /* skip past pad bytes, if any, to get to next row */
  7695.             src+= padBytes;
  7696.  
  7697.             /* src is at beginning of a row here, but it's the second row of
  7698.              * the square block of 4 pixels that we just worked on so we
  7699.              * need to go one more row.
  7700.              * i.e.,
  7701.              *                   OO...
  7702.              *           here -->OO...
  7703.              *       but want -->OO...
  7704.              *                   OO...
  7705.              *                   ...
  7706.              */
  7707.             src+= rowSizeInBytes;
  7708.          }
  7709.  
  7710.          src+= imageSizeInBytes;
  7711.       } /* for dd */
  7712.  
  7713.       /* both pointers must reach one byte after the end */
  7714.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
  7715.       assert(outIndex == halfWidth * halfHeight * halfDepth);
  7716.    } /* for dd */
  7717.  
  7718. } /* halveImagePackedPixel3D() */
  7719.  
  7720. static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
  7721.                                       GLsizei width,
  7722.                                       GLsizei height,
  7723.                                       GLsizei depth,
  7724.                                       GLsizei widthPowerOf2,
  7725.                                       GLsizei heightPowerOf2,
  7726.                                       GLsizei depthPowerOf2,
  7727.                                       GLenum format, GLenum type,
  7728.                                       GLint userLevel,
  7729.                                       GLint baseLevel,GLint maxLevel,
  7730.                                       const void *data)
  7731. {
  7732.    GLint newWidth, newHeight, newDepth;
  7733.    GLint level, levels;
  7734.    const void *usersImage;
  7735.    void *srcImage, *dstImage;
  7736.    __GLU_INIT_SWAP_IMAGE;
  7737.    GLint memReq;
  7738.    GLint cmpts;
  7739.  
  7740.    GLint myswapBytes, groupsPerLine, elementSize, groupSize;
  7741.    GLint rowsPerImage, imageSize;
  7742.    GLint rowSize, padding;
  7743.    PixelStorageModes psm;
  7744.  
  7745.    assert(checkMipmapArgs(internalFormat,format,type) == 0);
  7746.    assert(width >= 1 && height >= 1 && depth >= 1);
  7747.    assert(type != GL_BITMAP);
  7748.  
  7749.    srcImage = dstImage = NULL;
  7750.  
  7751.    newWidth= widthPowerOf2;
  7752.    newHeight= heightPowerOf2;
  7753.    newDepth= depthPowerOf2;
  7754.    levels = computeLog(newWidth);
  7755.    level = computeLog(newHeight);
  7756.    if (level > levels) levels=level;
  7757.    level = computeLog(newDepth);
  7758.    if (level > levels) levels=level;
  7759.  
  7760.    levels+= userLevel;
  7761.  
  7762.    retrieveStoreModes3D(&psm);
  7763.    myswapBytes = psm.unpack_swap_bytes;
  7764.    cmpts = elements_per_group(format,type);
  7765.    if (psm.unpack_row_length > 0) {
  7766.        groupsPerLine = psm.unpack_row_length;
  7767.    } else {
  7768.        groupsPerLine = width;
  7769.    }
  7770.  
  7771.    elementSize = bytes_per_element(type);
  7772.    groupSize = elementSize * cmpts;
  7773.    if (elementSize == 1) myswapBytes = 0;
  7774.  
  7775.    /* 3dstuff begin */
  7776.    if (psm.unpack_image_height > 0) {
  7777.       rowsPerImage= psm.unpack_image_height;
  7778.    }
  7779.    else {
  7780.       rowsPerImage= height;
  7781.    }
  7782.  
  7783.    /* 3dstuff end */
  7784.    rowSize = groupsPerLine * groupSize;
  7785.    padding = (rowSize % psm.unpack_alignment);
  7786.    if (padding) {
  7787.        rowSize += psm.unpack_alignment - padding;
  7788.    }
  7789.  
  7790.    imageSize= rowsPerImage * rowSize; /* 3dstuff */
  7791.  
  7792.    usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
  7793.                                   psm.unpack_skip_pixels * groupSize +
  7794.                                   /* 3dstuff */
  7795.                                   psm.unpack_skip_images * imageSize;
  7796.  
  7797.    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  7798.    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  7799.    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  7800.    glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
  7801.    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
  7802.  
  7803.    level = userLevel;
  7804.  
  7805.    if (width == newWidth && height == newHeight && depth == newDepth) {
  7806.        /* Use usersImage for level userLevel */
  7807.        if (baseLevel <= level && level <= maxLevel) {
  7808.           gluTexImage3D(target, level, internalFormat, width,
  7809.                        height, depth, 0, format, type,
  7810.                        usersImage);
  7811.        }
  7812.        if(levels == 0) { /* we're done. clean up and return */
  7813.          glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  7814.          glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  7815.          glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  7816.          glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  7817.          glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  7818.          glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
  7819.          glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
  7820.          return 0;
  7821.        }
  7822.        {
  7823.           int nextWidth= newWidth/2;
  7824.           int nextHeight= newHeight/2;
  7825.           int nextDepth= newDepth/2;
  7826.  
  7827.           /* clamp to 1 */
  7828.           if (nextWidth < 1) nextWidth= 1;
  7829.           if (nextHeight < 1) nextHeight= 1;
  7830.           if (nextDepth < 1) nextDepth= 1;      
  7831.        memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
  7832.        }
  7833.        switch(type) {
  7834.        case GL_UNSIGNED_BYTE:
  7835.          dstImage = (GLubyte *)malloc(memReq);
  7836.          break;
  7837.        case GL_BYTE:
  7838.          dstImage = (GLbyte *)malloc(memReq);
  7839.          break;
  7840.        case GL_UNSIGNED_SHORT:
  7841.          dstImage = (GLushort *)malloc(memReq);
  7842.          break;
  7843.        case GL_SHORT:
  7844.          dstImage = (GLshort *)malloc(memReq);
  7845.          break;
  7846.        case GL_UNSIGNED_INT:
  7847.          dstImage = (GLuint *)malloc(memReq);
  7848.          break;
  7849.        case GL_INT:
  7850.          dstImage = (GLint *)malloc(memReq);
  7851.          break;
  7852.        case GL_FLOAT:
  7853.          dstImage = (GLfloat *)malloc(memReq);
  7854.          break;
  7855.        case GL_UNSIGNED_BYTE_3_3_2:
  7856.        case GL_UNSIGNED_BYTE_2_3_3_REV:
  7857.          dstImage = (GLubyte *)malloc(memReq);
  7858.          break;
  7859.        case GL_UNSIGNED_SHORT_5_6_5:
  7860.        case GL_UNSIGNED_SHORT_5_6_5_REV:
  7861.        case GL_UNSIGNED_SHORT_4_4_4_4:
  7862.        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  7863.        case GL_UNSIGNED_SHORT_5_5_5_1:
  7864.        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  7865.          dstImage = (GLushort *)malloc(memReq);
  7866.          break;
  7867.        case GL_UNSIGNED_INT_8_8_8_8:
  7868.        case GL_UNSIGNED_INT_8_8_8_8_REV:
  7869.        case GL_UNSIGNED_INT_10_10_10_2:
  7870.        case GL_UNSIGNED_INT_2_10_10_10_REV:
  7871.          dstImage = (GLuint *)malloc(memReq);  
  7872.          break;
  7873.        default:
  7874.          return GLU_INVALID_ENUM; /* assertion */
  7875.        }
  7876.        if (dstImage == NULL) {
  7877.          glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  7878.          glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  7879.          glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  7880.          glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  7881.          glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  7882.          glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
  7883.          glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
  7884.          return GLU_OUT_OF_MEMORY;
  7885.        }
  7886.        else
  7887.          switch(type) {
  7888.          case GL_UNSIGNED_BYTE:
  7889.            if (depth > 1) {
  7890.              halveImage3D(cmpts,extractUbyte,shoveUbyte,
  7891.                           width,height,depth,
  7892.                           usersImage,dstImage,elementSize,groupSize,rowSize,
  7893.                           imageSize,myswapBytes);
  7894.            }
  7895.            else {
  7896.              halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
  7897.                               elementSize,rowSize,groupSize);
  7898.            }
  7899.            break;
  7900.          case GL_BYTE:
  7901.            if (depth > 1) {
  7902.            halveImage3D(cmpts,extractSbyte,shoveSbyte,
  7903.                         width,height,depth,
  7904.                         usersImage,dstImage,elementSize,groupSize,rowSize,
  7905.                         imageSize,myswapBytes);
  7906.            }
  7907.            else {
  7908.              halveImage_byte(cmpts,width,height,usersImage,dstImage,
  7909.                              elementSize,rowSize,groupSize);
  7910.            }
  7911.            break;
  7912.          case GL_UNSIGNED_SHORT:
  7913.            if (depth > 1) {
  7914.            halveImage3D(cmpts,extractUshort,shoveUshort,
  7915.                         width,height,depth,
  7916.                         usersImage,dstImage,elementSize,groupSize,rowSize,
  7917.                         imageSize,myswapBytes);
  7918.            }
  7919.            else {
  7920.              halveImage_ushort(cmpts,width,height,usersImage,dstImage,
  7921.                                elementSize,rowSize,groupSize,myswapBytes);
  7922.            }
  7923.            break;
  7924.          case GL_SHORT:
  7925.            if (depth > 1) {
  7926.            halveImage3D(cmpts,extractSshort,shoveSshort,
  7927.                         width,height,depth,
  7928.                         usersImage,dstImage,elementSize,groupSize,rowSize,
  7929.                         imageSize,myswapBytes);
  7930.            }
  7931.            else {
  7932.              halveImage_short(cmpts,width,height,usersImage,dstImage,
  7933.                               elementSize,rowSize,groupSize,myswapBytes);
  7934.            }
  7935.            break;
  7936.          case GL_UNSIGNED_INT:
  7937.            if (depth > 1) {
  7938.            halveImage3D(cmpts,extractUint,shoveUint,
  7939.                         width,height,depth,
  7940.                         usersImage,dstImage,elementSize,groupSize,rowSize,
  7941.                         imageSize,myswapBytes);
  7942.            }
  7943.            else {
  7944.              halveImage_uint(cmpts,width,height,usersImage,dstImage,
  7945.                              elementSize,rowSize,groupSize,myswapBytes);
  7946.            }
  7947.            break;
  7948.          case GL_INT:
  7949.            if (depth > 1) {
  7950.            halveImage3D(cmpts,extractSint,shoveSint,
  7951.                         width,height,depth,
  7952.                         usersImage,dstImage,elementSize,groupSize,rowSize,
  7953.                         imageSize,myswapBytes);
  7954.            }
  7955.            else {
  7956.              halveImage_int(cmpts,width,height,usersImage,dstImage,
  7957.                             elementSize,rowSize,groupSize,myswapBytes);
  7958.            }
  7959.            break;
  7960.          case GL_FLOAT:
  7961.            if (depth > 1 ) {
  7962.            halveImage3D(cmpts,extractFloat,shoveFloat,
  7963.                         width,height,depth,
  7964.                         usersImage,dstImage,elementSize,groupSize,rowSize,
  7965.                         imageSize,myswapBytes);
  7966.            }
  7967.            else {
  7968.              halveImage_float(cmpts,width,height,usersImage,dstImage,
  7969.                               elementSize,rowSize,groupSize,myswapBytes);
  7970.            }
  7971.            break;
  7972.          case GL_UNSIGNED_BYTE_3_3_2:
  7973.            assert(format == GL_RGB);
  7974.            halveImagePackedPixel3D(3,extract332,shove332,
  7975.                                    width,height,depth,usersImage,dstImage,
  7976.                                    elementSize,rowSize,imageSize,myswapBytes);
  7977.            break;
  7978.          case GL_UNSIGNED_BYTE_2_3_3_REV:
  7979.            assert(format == GL_RGB);
  7980.            halveImagePackedPixel3D(3,extract233rev,shove233rev,
  7981.                                    width,height,depth,usersImage,dstImage,
  7982.                                    elementSize,rowSize,imageSize,myswapBytes);
  7983.            break;
  7984.          case GL_UNSIGNED_SHORT_5_6_5:
  7985.            halveImagePackedPixel3D(3,extract565,shove565,
  7986.                                    width,height,depth,usersImage,dstImage,
  7987.                                    elementSize,rowSize,imageSize,myswapBytes);
  7988.            break;
  7989.          case GL_UNSIGNED_SHORT_5_6_5_REV:
  7990.            halveImagePackedPixel3D(3,extract565rev,shove565rev,
  7991.                                    width,height,depth,usersImage,dstImage,
  7992.                                    elementSize,rowSize,imageSize,myswapBytes);
  7993.            break;
  7994.          case GL_UNSIGNED_SHORT_4_4_4_4:
  7995.            halveImagePackedPixel3D(4,extract4444,shove4444,
  7996.                                    width,height,depth,usersImage,dstImage,
  7997.                                    elementSize,rowSize,imageSize,myswapBytes);
  7998.            break;
  7999.          case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  8000.            halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
  8001.                                    width,height,depth,usersImage,dstImage,
  8002.                                    elementSize,rowSize,imageSize,myswapBytes);
  8003.            break;
  8004.          case GL_UNSIGNED_SHORT_5_5_5_1:
  8005.            halveImagePackedPixel3D(4,extract5551,shove5551,
  8006.                                    width,height,depth,usersImage,dstImage,
  8007.                                    elementSize,rowSize,imageSize,myswapBytes);
  8008.            break;
  8009.          case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  8010.            halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
  8011.                                    width,height,depth,usersImage,dstImage,
  8012.                                    elementSize,rowSize,imageSize,myswapBytes);
  8013.            break;
  8014.          case GL_UNSIGNED_INT_8_8_8_8:
  8015.            halveImagePackedPixel3D(4,extract8888,shove8888,
  8016.                                    width,height,depth,usersImage,dstImage,
  8017.                                    elementSize,rowSize,imageSize,myswapBytes);
  8018.            break;
  8019.          case GL_UNSIGNED_INT_8_8_8_8_REV:
  8020.            halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
  8021.                                    width,height,depth,usersImage,dstImage,
  8022.                                    elementSize,rowSize,imageSize,myswapBytes);
  8023.            break;
  8024.          case GL_UNSIGNED_INT_10_10_10_2:
  8025.            halveImagePackedPixel3D(4,extract1010102,shove1010102,
  8026.                                    width,height,depth,usersImage,dstImage,
  8027.                                    elementSize,rowSize,imageSize,myswapBytes);
  8028.            break;
  8029.          case GL_UNSIGNED_INT_2_10_10_10_REV:
  8030.            halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
  8031.                                    width,height,depth,usersImage,dstImage,
  8032.                                    elementSize,rowSize,imageSize,myswapBytes);
  8033.            break;
  8034.          default:
  8035.            assert(0);
  8036.            break;
  8037.          }
  8038.        newWidth = width/2;
  8039.        newHeight = height/2;
  8040.        newDepth = depth/2;
  8041.        /* clamp to 1 */
  8042.        if (newWidth < 1) newWidth= 1;
  8043.        if (newHeight < 1) newHeight= 1;
  8044.        if (newDepth < 1) newDepth= 1;
  8045.  
  8046.        myswapBytes = 0;
  8047.        rowSize = newWidth * groupSize;
  8048.        imageSize= rowSize * newHeight; /* 3dstuff */
  8049.        memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
  8050.        /* Swap srcImage and dstImage */
  8051.        __GLU_SWAP_IMAGE(srcImage,dstImage);
  8052.        switch(type) {
  8053.        case GL_UNSIGNED_BYTE:
  8054.          dstImage = (GLubyte *)malloc(memReq);
  8055.          break;
  8056.        case GL_BYTE:
  8057.          dstImage = (GLbyte *)malloc(memReq);
  8058.          break;
  8059.        case GL_UNSIGNED_SHORT:
  8060.          dstImage = (GLushort *)malloc(memReq);
  8061.          break;
  8062.        case GL_SHORT:
  8063.          dstImage = (GLshort *)malloc(memReq);
  8064.          break;
  8065.        case GL_UNSIGNED_INT:
  8066.          dstImage = (GLuint *)malloc(memReq);
  8067.          break;
  8068.        case GL_INT:
  8069.          dstImage = (GLint *)malloc(memReq);
  8070.          break;
  8071.        case GL_FLOAT:
  8072.          dstImage = (GLfloat *)malloc(memReq);
  8073.          break;
  8074.        case GL_UNSIGNED_BYTE_3_3_2:
  8075.        case GL_UNSIGNED_BYTE_2_3_3_REV:
  8076.          dstImage = (GLubyte *)malloc(memReq);
  8077.          break;
  8078.        case GL_UNSIGNED_SHORT_5_6_5:
  8079.        case GL_UNSIGNED_SHORT_5_6_5_REV:
  8080.        case GL_UNSIGNED_SHORT_4_4_4_4:
  8081.        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  8082.        case GL_UNSIGNED_SHORT_5_5_5_1:
  8083.        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  8084.          dstImage = (GLushort *)malloc(memReq);
  8085.          break;
  8086.        case GL_UNSIGNED_INT_8_8_8_8:
  8087.        case GL_UNSIGNED_INT_8_8_8_8_REV:
  8088.        case GL_UNSIGNED_INT_10_10_10_2:
  8089.        case GL_UNSIGNED_INT_2_10_10_10_REV:
  8090.          dstImage = (GLuint *)malloc(memReq);
  8091.          break;
  8092.        default:
  8093.          return GLU_INVALID_ENUM; /* assertion */
  8094.        }
  8095.        if (dstImage == NULL) {
  8096.          glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  8097.          glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  8098.          glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  8099.          glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  8100.          glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  8101.          glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
  8102.          glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
  8103.          free(srcImage);
  8104.          return GLU_OUT_OF_MEMORY;
  8105.        }
  8106.        /* level userLevel+1 is in srcImage; level userLevel already saved */
  8107.        level = userLevel+1;
  8108.    } else {/* user's image is *not* nice power-of-2 sized square */
  8109.        memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
  8110.        switch(type) {
  8111.            case GL_UNSIGNED_BYTE:
  8112.                dstImage = (GLubyte *)malloc(memReq);
  8113.                break;
  8114.            case GL_BYTE:
  8115.                dstImage = (GLbyte *)malloc(memReq);
  8116.                break;
  8117.            case GL_UNSIGNED_SHORT:
  8118.                dstImage = (GLushort *)malloc(memReq);
  8119.                break;
  8120.            case GL_SHORT:
  8121.                dstImage = (GLshort *)malloc(memReq);
  8122.                break;
  8123.            case GL_UNSIGNED_INT:
  8124.                dstImage = (GLuint *)malloc(memReq);
  8125.                break;
  8126.            case GL_INT:
  8127.                dstImage = (GLint *)malloc(memReq);
  8128.                break;
  8129.            case GL_FLOAT:
  8130.                dstImage = (GLfloat *)malloc(memReq);
  8131.                break;
  8132.            case GL_UNSIGNED_BYTE_3_3_2:
  8133.            case GL_UNSIGNED_BYTE_2_3_3_REV:
  8134.                dstImage = (GLubyte *)malloc(memReq);
  8135.                break;
  8136.            case GL_UNSIGNED_SHORT_5_6_5:
  8137.            case GL_UNSIGNED_SHORT_5_6_5_REV:
  8138.            case GL_UNSIGNED_SHORT_4_4_4_4:
  8139.            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  8140.            case GL_UNSIGNED_SHORT_5_5_5_1:
  8141.            case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  8142.                dstImage = (GLushort *)malloc(memReq);
  8143.                break;
  8144.            case GL_UNSIGNED_INT_8_8_8_8:
  8145.            case GL_UNSIGNED_INT_8_8_8_8_REV:
  8146.            case GL_UNSIGNED_INT_10_10_10_2:
  8147.            case GL_UNSIGNED_INT_2_10_10_10_REV:
  8148.                dstImage = (GLuint *)malloc(memReq);
  8149.                break;
  8150.            default:
  8151.                return GLU_INVALID_ENUM; /* assertion */
  8152.        }
  8153.  
  8154.        if (dstImage == NULL) {
  8155.            glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  8156.            glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  8157.            glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  8158.            glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  8159.            glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  8160.            glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
  8161.            glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
  8162.            return GLU_OUT_OF_MEMORY;
  8163.        }
  8164.        /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
  8165.        width,height,depth,newWidth,newHeight,newDepth);*/
  8166.  
  8167.        gluScaleImage3D(format, width, height, depth, type, usersImage,
  8168.                        newWidth, newHeight, newDepth, type, dstImage);
  8169.  
  8170.        myswapBytes = 0;
  8171.        rowSize = newWidth * groupSize;
  8172.        imageSize = rowSize * newHeight; /* 3dstuff */
  8173.        /* Swap dstImage and srcImage */
  8174.        __GLU_SWAP_IMAGE(srcImage,dstImage);
  8175.  
  8176.        if(levels != 0) { /* use as little memory as possible */
  8177.          {
  8178.             int nextWidth= newWidth/2;
  8179.             int nextHeight= newHeight/2;
  8180.             int nextDepth= newDepth/2;
  8181.             if (nextWidth < 1) nextWidth= 1;
  8182.             if (nextHeight < 1) nextHeight= 1;  
  8183.             if (nextDepth < 1) nextDepth= 1;    
  8184.  
  8185.          memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
  8186.          }
  8187.          switch(type) {
  8188.          case GL_UNSIGNED_BYTE:
  8189.            dstImage = (GLubyte *)malloc(memReq);
  8190.            break;
  8191.          case GL_BYTE:
  8192.            dstImage = (GLbyte *)malloc(memReq);
  8193.            break;
  8194.          case GL_UNSIGNED_SHORT:
  8195.            dstImage = (GLushort *)malloc(memReq);
  8196.            break;
  8197.          case GL_SHORT:
  8198.            dstImage = (GLshort *)malloc(memReq);
  8199.            break;
  8200.          case GL_UNSIGNED_INT:
  8201.            dstImage = (GLuint *)malloc(memReq);
  8202.            break;
  8203.          case GL_INT:
  8204.            dstImage = (GLint *)malloc(memReq);
  8205.            break;
  8206.          case GL_FLOAT:
  8207.            dstImage = (GLfloat *)malloc(memReq);
  8208.            break;
  8209.          case GL_UNSIGNED_BYTE_3_3_2:
  8210.          case GL_UNSIGNED_BYTE_2_3_3_REV:
  8211.            dstImage = (GLubyte *)malloc(memReq);
  8212.            break;
  8213.          case GL_UNSIGNED_SHORT_5_6_5:
  8214.          case GL_UNSIGNED_SHORT_5_6_5_REV:
  8215.          case GL_UNSIGNED_SHORT_4_4_4_4:
  8216.          case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  8217.          case GL_UNSIGNED_SHORT_5_5_5_1:
  8218.          case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  8219.            dstImage = (GLushort *)malloc(memReq);
  8220.            break;
  8221.          case GL_UNSIGNED_INT_8_8_8_8:
  8222.          case GL_UNSIGNED_INT_8_8_8_8_REV:
  8223.          case GL_UNSIGNED_INT_10_10_10_2:
  8224.          case GL_UNSIGNED_INT_2_10_10_10_REV:
  8225.            dstImage = (GLuint *)malloc(memReq);
  8226.            break;
  8227.          default:
  8228.            return GLU_INVALID_ENUM; /* assertion */
  8229.          }
  8230.          if (dstImage == NULL) {
  8231.            glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  8232.            glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  8233.            glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  8234.            glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  8235.            glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  8236.            glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
  8237.            glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
  8238.            free(srcImage);
  8239.            return GLU_OUT_OF_MEMORY;
  8240.          }
  8241.        }
  8242.        /* level userLevel is in srcImage; nothing saved yet */
  8243.        level = userLevel;      
  8244.    }
  8245.  
  8246.    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  8247.    if (baseLevel <= level && level <= maxLevel) {
  8248.      gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
  8249.                   0,format, type, (void *)srcImage);
  8250.    }
  8251.    level++; /* update current level for the loop */
  8252.    for (; level <= levels; level++) {
  8253.        switch(type) {
  8254.            case GL_UNSIGNED_BYTE:
  8255.                if (newDepth > 1) {
  8256.                halveImage3D(cmpts,extractUbyte,shoveUbyte,
  8257.                             newWidth,newHeight,newDepth,
  8258.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8259.                             imageSize,myswapBytes);
  8260.                }
  8261.                else {
  8262.                  halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
  8263.                                   elementSize,rowSize,groupSize);
  8264.                }
  8265.                break;
  8266.            case GL_BYTE:
  8267.                if (newDepth > 1) {
  8268.                halveImage3D(cmpts,extractSbyte,shoveSbyte,
  8269.                             newWidth,newHeight,newDepth,
  8270.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8271.                             imageSize,myswapBytes);
  8272.                }
  8273.                else {
  8274.                  halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
  8275.                                   elementSize,rowSize,groupSize);
  8276.                }
  8277.                break;
  8278.            case GL_UNSIGNED_SHORT:
  8279.                if (newDepth > 1) {
  8280.                halveImage3D(cmpts,extractUshort,shoveUshort,
  8281.                             newWidth,newHeight,newDepth,
  8282.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8283.                             imageSize,myswapBytes);
  8284.                }
  8285.                else {
  8286.                  halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
  8287.                                    elementSize,rowSize,groupSize,myswapBytes);
  8288.                }
  8289.                break;
  8290.            case GL_SHORT:
  8291.                if (newDepth > 1) {
  8292.                halveImage3D(cmpts,extractSshort,shoveSshort,
  8293.                             newWidth,newHeight,newDepth,
  8294.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8295.                             imageSize,myswapBytes);
  8296.                }
  8297.                else {
  8298.                  halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
  8299.                                   elementSize,rowSize,groupSize,myswapBytes);
  8300.                }
  8301.                break;
  8302.            case GL_UNSIGNED_INT:
  8303.                if (newDepth > 1) {
  8304.                halveImage3D(cmpts,extractUint,shoveUint,
  8305.                             newWidth,newHeight,newDepth,
  8306.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8307.                             imageSize,myswapBytes);
  8308.                }
  8309.                else {
  8310.                  halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
  8311.                                  elementSize,rowSize,groupSize,myswapBytes);
  8312.                }
  8313.                break;
  8314.            case GL_INT:
  8315.                if (newDepth > 1) {
  8316.                halveImage3D(cmpts,extractSint,shoveSint,
  8317.                             newWidth,newHeight,newDepth,
  8318.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8319.                             imageSize,myswapBytes);
  8320.                }
  8321.                else {
  8322.                  halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
  8323.                                 elementSize,rowSize,groupSize,myswapBytes);
  8324.                }
  8325.                break;
  8326.            case GL_FLOAT:
  8327.                if (newDepth > 1) {
  8328.                halveImage3D(cmpts,extractFloat,shoveFloat,
  8329.                             newWidth,newHeight,newDepth,
  8330.                             srcImage,dstImage,elementSize,groupSize,rowSize,
  8331.                             imageSize,myswapBytes);
  8332.                }
  8333.                else {
  8334.                  halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
  8335.                                   elementSize,rowSize,groupSize,myswapBytes);
  8336.                }
  8337.                break;
  8338.            case GL_UNSIGNED_BYTE_3_3_2:
  8339.                halveImagePackedPixel3D(3,extract332,shove332,
  8340.                                        newWidth,newHeight,newDepth,
  8341.                                        srcImage,dstImage,elementSize,rowSize,
  8342.                                        imageSize,myswapBytes);
  8343.                break;
  8344.            case GL_UNSIGNED_BYTE_2_3_3_REV:
  8345.                halveImagePackedPixel3D(3,extract233rev,shove233rev,
  8346.                                        newWidth,newHeight,newDepth,
  8347.                                        srcImage,dstImage,elementSize,rowSize,
  8348.                                        imageSize,myswapBytes);
  8349.                break;
  8350.            case GL_UNSIGNED_SHORT_5_6_5:
  8351.                halveImagePackedPixel3D(3,extract565,shove565,
  8352.                                        newWidth,newHeight,newDepth,
  8353.                                        srcImage,dstImage,elementSize,rowSize,
  8354.                                        imageSize,myswapBytes);
  8355.                break;
  8356.            case GL_UNSIGNED_SHORT_5_6_5_REV:
  8357.                halveImagePackedPixel3D(3,extract565rev,shove565rev,
  8358.                                        newWidth,newHeight,newDepth,
  8359.                                        srcImage,dstImage,elementSize,rowSize,
  8360.                                        imageSize,myswapBytes);
  8361.                break;
  8362.            case GL_UNSIGNED_SHORT_4_4_4_4:
  8363.                halveImagePackedPixel3D(4,extract4444,shove4444,
  8364.                                        newWidth,newHeight,newDepth,
  8365.                                        srcImage,dstImage,elementSize,rowSize,
  8366.                                        imageSize,myswapBytes);
  8367.                break;
  8368.            case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  8369.                halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
  8370.                                        newWidth,newHeight,newDepth,
  8371.                                        srcImage,dstImage,elementSize,rowSize,
  8372.                                        imageSize,myswapBytes);
  8373.                break;
  8374.            case GL_UNSIGNED_SHORT_5_5_5_1:             
  8375.                halveImagePackedPixel3D(4,extract5551,shove5551,
  8376.                                        newWidth,newHeight,newDepth,
  8377.                                        srcImage,dstImage,elementSize,rowSize,
  8378.                                        imageSize,myswapBytes);
  8379.                break;
  8380.            case GL_UNSIGNED_SHORT_1_5_5_5_REV:         
  8381.                halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
  8382.                                        newWidth,newHeight,newDepth,
  8383.                                        srcImage,dstImage,elementSize,rowSize,
  8384.                                        imageSize,myswapBytes);
  8385.                break;
  8386.            case GL_UNSIGNED_INT_8_8_8_8:
  8387.                halveImagePackedPixel3D(4,extract8888,shove8888,
  8388.                                        newWidth,newHeight,newDepth,
  8389.                                        srcImage,dstImage,elementSize,rowSize,
  8390.                                        imageSize,myswapBytes);
  8391.                break;
  8392.            case GL_UNSIGNED_INT_8_8_8_8_REV:
  8393.                halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
  8394.                                        newWidth,newHeight,newDepth,
  8395.                                        srcImage,dstImage,elementSize,rowSize,
  8396.                                        imageSize,myswapBytes);
  8397.                break;
  8398.            case GL_UNSIGNED_INT_10_10_10_2:
  8399.                halveImagePackedPixel3D(4,extract1010102,shove1010102,
  8400.                                        newWidth,newHeight,newDepth,
  8401.                                        srcImage,dstImage,elementSize,rowSize,
  8402.                                        imageSize,myswapBytes);
  8403.                break;
  8404.            case GL_UNSIGNED_INT_2_10_10_10_REV:
  8405.                halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
  8406.                                        newWidth,newHeight,newDepth,
  8407.                                        srcImage,dstImage,elementSize,rowSize,
  8408.                                        imageSize,myswapBytes);
  8409.                break;
  8410.            default:
  8411.                assert(0);
  8412.                break;
  8413.        }
  8414.  
  8415.        __GLU_SWAP_IMAGE(srcImage,dstImage);
  8416.  
  8417.        if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
  8418.        if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
  8419.        if (newDepth > 1) newDepth /= 2;
  8420.        {
  8421.           /* call tex image with srcImage untouched since it's not padded */
  8422.           if (baseLevel <= level && level <= maxLevel) {
  8423.             gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
  8424.                          newDepth,0, format, type, (void *) srcImage);
  8425.           }
  8426.        }
  8427.    } /* for level */
  8428.    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  8429.    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  8430.    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  8431.    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  8432.    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  8433.    glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
  8434.    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
  8435.  
  8436.    free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
  8437.    if (dstImage) { /* if it's non-rectangular and only 1 level */
  8438.      free(dstImage);
  8439.    }
  8440.    return 0;
  8441. } /* gluBuild3DMipmapLevelsCore() */
  8442.  
  8443. GLint GLAPIENTRY
  8444. gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
  8445.                              GLsizei width, GLsizei height, GLsizei depth,
  8446.                              GLenum format, GLenum type,
  8447.                              GLint userLevel, GLint baseLevel, GLint maxLevel,
  8448.                              const void *data)
  8449. {
  8450.    int level, levels;
  8451.  
  8452.    int rc= checkMipmapArgs(internalFormat,format,type);
  8453.    if (rc != 0) return rc;
  8454.  
  8455.    if (width < 1 || height < 1 || depth < 1) {
  8456.        return GLU_INVALID_VALUE;
  8457.    }
  8458.  
  8459.    if(type == GL_BITMAP) {
  8460.       return GLU_INVALID_ENUM;
  8461.    }
  8462.  
  8463.    levels = computeLog(width);
  8464.    level = computeLog(height);
  8465.    if (level > levels) levels=level;
  8466.    level = computeLog(depth);
  8467.    if (level > levels) levels=level;
  8468.  
  8469.    levels+= userLevel;
  8470.    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
  8471.       return GLU_INVALID_VALUE;
  8472.  
  8473.    return gluBuild3DMipmapLevelsCore(target, internalFormat,
  8474.                                      width, height, depth,
  8475.                                      width, height, depth,
  8476.                                      format, type,
  8477.                                      userLevel, baseLevel, maxLevel,
  8478.                                      data);
  8479. } /* gluBuild3DMipmapLevels() */
  8480.  
  8481. GLint GLAPIENTRY
  8482. gluBuild3DMipmaps(GLenum target, GLint internalFormat,
  8483.                         GLsizei width, GLsizei height, GLsizei depth,
  8484.                         GLenum format, GLenum type, const void *data)
  8485. {
  8486.    GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
  8487.    int level, levels;
  8488.  
  8489.    int rc= checkMipmapArgs(internalFormat,format,type);
  8490.    if (rc != 0) return rc;
  8491.  
  8492.    if (width < 1 || height < 1 || depth < 1) {
  8493.        return GLU_INVALID_VALUE;
  8494.    }
  8495.  
  8496.    if(type == GL_BITMAP) {
  8497.       return GLU_INVALID_ENUM;
  8498.    }
  8499.  
  8500.    closestFit3D(target,width,height,depth,internalFormat,format,type,
  8501.                 &widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
  8502.  
  8503.    levels = computeLog(widthPowerOf2);
  8504.    level = computeLog(heightPowerOf2);
  8505.    if (level > levels) levels=level;
  8506.    level = computeLog(depthPowerOf2);
  8507.    if (level > levels) levels=level;
  8508.  
  8509.    return gluBuild3DMipmapLevelsCore(target, internalFormat,
  8510.                                      width, height, depth,
  8511.                                      widthPowerOf2, heightPowerOf2,
  8512.                                      depthPowerOf2,
  8513.                                      format, type, 0, 0, levels,
  8514.                                      data);
  8515. } /* gluBuild3DMipmaps() */
  8516.  
  8517. static GLdouble extractUbyte(int isSwap, const void *ubyte)
  8518. {
  8519.    isSwap= isSwap;              /* turn off warnings */
  8520.  
  8521.    assert(*((const GLubyte *)ubyte) <= 255);
  8522.  
  8523.    return (GLdouble)(*((const GLubyte *)ubyte));
  8524. } /* extractUbyte() */
  8525.  
  8526. static void shoveUbyte(GLdouble value, int index, void *data)
  8527. {
  8528.    assert(0.0 <= value && value < 256.0);
  8529.  
  8530.    ((GLubyte *)data)[index]= (GLubyte)value;
  8531. } /* shoveUbyte() */
  8532.  
  8533. static GLdouble extractSbyte(int isSwap, const void *sbyte)
  8534. {
  8535.    isSwap= isSwap;              /* turn off warnings */
  8536.  
  8537.    assert(*((const GLbyte *)sbyte) <= 127);
  8538.  
  8539.    return (GLdouble)(*((const GLbyte *)sbyte));
  8540. } /* extractSbyte() */
  8541.  
  8542. static void shoveSbyte(GLdouble value, int index, void *data)
  8543. {
  8544.    ((GLbyte *)data)[index]= (GLbyte)value;
  8545. } /* shoveSbyte() */
  8546.  
  8547. static GLdouble extractUshort(int isSwap, const void *uitem)
  8548. {
  8549.    GLushort ushort;
  8550.  
  8551.    if (isSwap) {
  8552.      ushort= __GLU_SWAP_2_BYTES(uitem);
  8553.    }
  8554.    else {
  8555.      ushort= *(const GLushort *)uitem;
  8556.    }
  8557.  
  8558.    assert(ushort <= 65535);
  8559.  
  8560.    return (GLdouble)ushort;
  8561. } /* extractUshort() */
  8562.  
  8563. static void shoveUshort(GLdouble value, int index, void *data)
  8564. {
  8565.    assert(0.0 <= value && value < 65536.0);
  8566.  
  8567.    ((GLushort *)data)[index]= (GLushort)value;
  8568. } /* shoveUshort() */
  8569.  
  8570. static GLdouble extractSshort(int isSwap, const void *sitem)
  8571. {
  8572.    GLshort sshort;
  8573.  
  8574.    if (isSwap) {
  8575.      sshort= __GLU_SWAP_2_BYTES(sitem);
  8576.    }
  8577.    else {
  8578.      sshort= *(const GLshort *)sitem;
  8579.    }
  8580.  
  8581.    assert(sshort <= 32767);
  8582.  
  8583.    return (GLdouble)sshort;
  8584. } /* extractSshort() */
  8585.  
  8586. static void shoveSshort(GLdouble value, int index, void *data)
  8587. {
  8588.    assert(0.0 <= value && value < 32768.0);
  8589.  
  8590.    ((GLshort *)data)[index]= (GLshort)value;
  8591. } /* shoveSshort() */
  8592.  
  8593. static GLdouble extractUint(int isSwap, const void *uitem)
  8594. {
  8595.    GLuint uint;
  8596.  
  8597.    if (isSwap) {
  8598.      uint= __GLU_SWAP_4_BYTES(uitem);
  8599.    }
  8600.    else {
  8601.      uint= *(const GLuint *)uitem;
  8602.    }
  8603.  
  8604.    assert(uint <= 0xffffffff);
  8605.  
  8606.    return (GLdouble)uint;
  8607. } /* extractUint() */
  8608.  
  8609. static void shoveUint(GLdouble value, int index, void *data)
  8610. {
  8611.    assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
  8612.  
  8613.    ((GLuint *)data)[index]= (GLuint)value;
  8614. } /* shoveUint() */
  8615.  
  8616. static GLdouble extractSint(int isSwap, const void *sitem)
  8617. {
  8618.    GLint sint;
  8619.  
  8620.    if (isSwap) {
  8621.      sint= __GLU_SWAP_4_BYTES(sitem);
  8622.    }
  8623.    else {
  8624.      sint= *(const GLint *)sitem;
  8625.    }
  8626.  
  8627.    assert(sint <= 0x7fffffff);
  8628.  
  8629.    return (GLdouble)sint;
  8630. } /* extractSint() */
  8631.  
  8632. static void shoveSint(GLdouble value, int index, void *data)
  8633. {
  8634.    assert(0.0 <= value && value <= (GLdouble) INT_MAX);
  8635.  
  8636.    ((GLint *)data)[index]= (GLint)value;
  8637. } /* shoveSint() */
  8638.  
  8639. static GLdouble extractFloat(int isSwap, const void *item)
  8640. {
  8641.    GLfloat ffloat;
  8642.  
  8643.    if (isSwap) {
  8644.      ffloat= __GLU_SWAP_4_BYTES(item);
  8645.    }
  8646.    else {
  8647.      ffloat= *(const GLfloat *)item;
  8648.    }
  8649.  
  8650.    assert(ffloat <= 1.0);
  8651.  
  8652.    return (GLdouble)ffloat;
  8653. } /* extractFloat() */
  8654.  
  8655. static void shoveFloat(GLdouble value, int index, void *data)
  8656. {
  8657.    assert(0.0 <= value && value <= 1.0);
  8658.  
  8659.    ((GLfloat *)data)[index]= value;
  8660. } /* shoveFloat() */
  8661.  
  8662. static void halveImageSlice(int components,
  8663.                             GLdouble (*extract)(int, const void *),
  8664.                             void (*shove)(GLdouble, int, void *),
  8665.                             GLint width, GLint height, GLint depth,
  8666.                             const void *dataIn, void *dataOut,
  8667.                             GLint elementSizeInBytes,
  8668.                             GLint groupSizeInBytes,
  8669.                             GLint rowSizeInBytes,
  8670.                             GLint imageSizeInBytes,
  8671.                             GLint isSwap)
  8672. {
  8673.    int ii, jj;
  8674.    int halfWidth= width / 2;
  8675.    int halfHeight= height / 2;
  8676.    int halfDepth= depth / 2;
  8677.    const char *src= (const char *)dataIn;
  8678.    int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes);
  8679.    int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
  8680.    int outIndex= 0;
  8681.  
  8682.    assert((width == 1 || height == 1) && depth >= 2);
  8683.  
  8684.    if (width == height) {       /* a 1-pixel column viewed from top */
  8685.       /* printf("1-column\n");*/
  8686.       assert(width == 1 && height == 1);
  8687.       assert(depth >= 2);
  8688.  
  8689.       for (ii= 0; ii< halfDepth; ii++) {
  8690.          int cc;
  8691.  
  8692.          for (cc = 0; cc < components; cc++) {
  8693.             double totals[4];
  8694.             double extractTotals[BOX2][4];
  8695.             int kk;
  8696.  
  8697.             extractTotals[0][cc]= (*extract)(isSwap,src);
  8698.             extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
  8699.  
  8700.             /* average 2 pixels since only a column */
  8701.             totals[cc]= 0.0;
  8702.             /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
  8703.              * totals[RED]/= 2.0;
  8704.              */
  8705.             for (kk = 0; kk < BOX2; kk++) {
  8706.               totals[cc]+= extractTotals[kk][cc];
  8707.             }
  8708.             totals[cc]/= (double)BOX2;
  8709.  
  8710.             (*shove)(totals[cc],outIndex,dataOut);
  8711.             outIndex++;
  8712.             src+= elementSizeInBytes;
  8713.          } /* for cc */
  8714.  
  8715.          /* skip over to next group of 2 */
  8716.          src+= rowSizeInBytes;
  8717.       } /* for ii */
  8718.  
  8719.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
  8720.       assert(outIndex == halfDepth * components);
  8721.    }
  8722.    else if (height == 1) {      /* horizontal slice viewed from top */
  8723.       /* printf("horizontal slice\n"); */
  8724.       assert(width != 1);
  8725.  
  8726.       for (ii= 0; ii< halfDepth; ii++) {
  8727.          for (jj= 0; jj< halfWidth; jj++) {
  8728.             int cc;
  8729.  
  8730.             for (cc = 0; cc < components; cc++) {
  8731.                int kk;
  8732.                double totals[4];
  8733.                double extractTotals[BOX4][4];
  8734.  
  8735.                extractTotals[0][cc]=(*extract)(isSwap,src);
  8736.                extractTotals[1][cc]=(*extract)(isSwap,
  8737.                                                (src+groupSizeInBytes));
  8738.                extractTotals[2][cc]=(*extract)(isSwap,
  8739.                                                (src+imageSizeInBytes));
  8740.                extractTotals[3][cc]=(*extract)(isSwap,
  8741.                                                (src+imageSizeInBytes+groupSizeInBytes));
  8742.  
  8743.                /* grab 4 pixels to average */
  8744.                totals[cc]= 0.0;
  8745.                /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  8746.                 *              extractTotals[2][RED]+extractTotals[3][RED];
  8747.                 * totals[RED]/= 4.0;
  8748.                 */
  8749.                for (kk = 0; kk < BOX4; kk++) {
  8750.                   totals[cc]+= extractTotals[kk][cc];
  8751.                }
  8752.                totals[cc]/= (double)BOX4;
  8753.  
  8754.                (*shove)(totals[cc],outIndex,dataOut);
  8755.                outIndex++;
  8756.  
  8757.                src+= elementSizeInBytes;
  8758.             } /* for cc */
  8759.  
  8760.             /* skip over to next horizontal square of 4 */
  8761.             src+= groupSizeInBytes;
  8762.          } /* for jj */
  8763.          src+= rowPadBytes;
  8764.  
  8765.          src+= rowSizeInBytes;
  8766.       } /* for ii */
  8767.  
  8768.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
  8769.       assert(outIndex == halfWidth * halfDepth * components);
  8770.    }
  8771.    else if (width == 1) {       /* vertical slice viewed from top */
  8772.       /* printf("vertical slice\n"); */
  8773.       assert(height != 1);
  8774.  
  8775.       for (ii= 0; ii< halfDepth; ii++) {
  8776.          for (jj= 0; jj< halfHeight; jj++) {
  8777.             int cc;
  8778.  
  8779.             for (cc = 0; cc < components; cc++) {
  8780.                int kk;
  8781.                double totals[4];
  8782.                double extractTotals[BOX4][4];
  8783.  
  8784.                extractTotals[0][cc]=(*extract)(isSwap,src);
  8785.                extractTotals[1][cc]=(*extract)(isSwap,
  8786.                                                (src+rowSizeInBytes));
  8787.                extractTotals[2][cc]=(*extract)(isSwap,
  8788.                                                (src+imageSizeInBytes));
  8789.                extractTotals[3][cc]=(*extract)(isSwap,
  8790.                                                (src+imageSizeInBytes+rowSizeInBytes));
  8791.  
  8792.                /* grab 4 pixels to average */
  8793.                totals[cc]= 0.0;
  8794.                /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  8795.                 *              extractTotals[2][RED]+extractTotals[3][RED];
  8796.                 * totals[RED]/= 4.0;
  8797.                 */
  8798.                for (kk = 0; kk < BOX4; kk++) {
  8799.                   totals[cc]+= extractTotals[kk][cc];
  8800.                }
  8801.                totals[cc]/= (double)BOX4;
  8802.  
  8803.                (*shove)(totals[cc],outIndex,dataOut);
  8804.                outIndex++;
  8805.  
  8806.                src+= elementSizeInBytes;
  8807.             } /* for cc */
  8808.             src+= rowPadBytes;
  8809.  
  8810.             /* skip over to next vertical square of 4 */
  8811.             src+= rowSizeInBytes;
  8812.          } /* for jj */
  8813.          src+= imagePadBytes;
  8814.  
  8815.          src+= imageSizeInBytes;
  8816.       } /* for ii */
  8817.  
  8818.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
  8819.       assert(outIndex == halfHeight * halfDepth * components);
  8820.    }
  8821.  
  8822. } /* halveImageSlice() */
  8823.  
  8824. static void halveImage3D(int components,
  8825.                          GLdouble (*extract)(int, const void *),
  8826.                          void (*shove)(GLdouble, int, void *),
  8827.                          GLint width, GLint height, GLint depth,
  8828.                          const void *dataIn, void *dataOut,
  8829.                          GLint elementSizeInBytes,
  8830.                          GLint groupSizeInBytes,
  8831.                          GLint rowSizeInBytes,
  8832.                          GLint imageSizeInBytes,
  8833.                          GLint isSwap)
  8834. {
  8835.    assert(depth > 1);
  8836.  
  8837.    /* a horizontal/vertical/one-column slice viewed from top */
  8838.    if (width == 1 || height == 1) {
  8839.       assert(1 <= depth);
  8840.  
  8841.       halveImageSlice(components,extract,shove, width, height, depth,
  8842.                       dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
  8843.                       rowSizeInBytes, imageSizeInBytes, isSwap);
  8844.       return;
  8845.    }
  8846.    {
  8847.       int ii, jj, dd;
  8848.  
  8849.       int halfWidth= width / 2;
  8850.       int halfHeight= height / 2;
  8851.       int halfDepth= depth / 2;
  8852.       const char *src= (const char *) dataIn;
  8853.       int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes);
  8854.       int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
  8855.       int outIndex= 0;
  8856.  
  8857.       for (dd= 0; dd < halfDepth; dd++) {
  8858.          for (ii= 0; ii< halfHeight; ii++) {
  8859.             for (jj= 0; jj< halfWidth; jj++) {
  8860.                int cc;
  8861.  
  8862.                for (cc= 0; cc < components; cc++) {
  8863.                   int kk;
  8864. #define BOX8 8
  8865.                   double totals[4];     /* 4 is maximum components */
  8866.                   double extractTotals[BOX8][4]; /* 4 is maximum components */
  8867.  
  8868.                   extractTotals[0][cc]= (*extract)(isSwap,src);
  8869.                   extractTotals[1][cc]= (*extract)(isSwap,
  8870.                                                    (src+groupSizeInBytes));
  8871.                   extractTotals[2][cc]= (*extract)(isSwap,
  8872.                                                    (src+rowSizeInBytes));
  8873.                   extractTotals[3][cc]= (*extract)(isSwap,
  8874.                                                    (src+rowSizeInBytes+groupSizeInBytes));
  8875.  
  8876.                   extractTotals[4][cc]= (*extract)(isSwap,
  8877.                                                    (src+imageSizeInBytes));
  8878.  
  8879.                   extractTotals[5][cc]= (*extract)(isSwap,
  8880.                                                    (src+groupSizeInBytes+imageSizeInBytes));
  8881.                   extractTotals[6][cc]= (*extract)(isSwap,
  8882.                                                    (src+rowSizeInBytes+imageSizeInBytes));
  8883.                   extractTotals[7][cc]= (*extract)(isSwap,
  8884.                                                    (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
  8885.  
  8886.                   totals[cc]= 0.0;
  8887.  
  8888.                   /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
  8889.                    *              extractTotals[2][RED]+extractTotals[3][RED]+
  8890.                    *              extractTotals[4][RED]+extractTotals[5][RED]+
  8891.                    *              extractTotals[6][RED]+extractTotals[7][RED];
  8892.                    * totals[RED]/= 8.0;
  8893.                    */
  8894.                   for (kk = 0; kk < BOX8; kk++) {
  8895.                      totals[cc]+= extractTotals[kk][cc];
  8896.                   }
  8897.                   totals[cc]/= (double)BOX8;
  8898.  
  8899.                   (*shove)(totals[cc],outIndex,dataOut);
  8900.  
  8901.                   outIndex++;
  8902.  
  8903.                   src+= elementSizeInBytes; /* go to next component */
  8904.                } /* for cc */
  8905.  
  8906.                /* skip over to next square of 4 */
  8907.                src+= groupSizeInBytes;
  8908.             } /* for jj */
  8909.             /* skip past pad bytes, if any, to get to next row */
  8910.             src+= rowPadBytes;
  8911.  
  8912.             /* src is at beginning of a row here, but it's the second row of
  8913.              * the square block of 4 pixels that we just worked on so we
  8914.              * need to go one more row.
  8915.              * i.e.,
  8916.              *                   OO...
  8917.              *           here -->OO...
  8918.              *       but want -->OO...
  8919.              *                   OO...
  8920.              *                   ...
  8921.              */
  8922.             src+= rowSizeInBytes;
  8923.          } /* for ii */
  8924.  
  8925.          /* skip past pad bytes, if any, to get to next image */
  8926.          src+= imagePadBytes;
  8927.  
  8928.          src+= imageSizeInBytes;
  8929.       } /* for dd */
  8930.  
  8931.       /* both pointers must reach one byte after the end */
  8932.       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
  8933.       assert(outIndex == halfWidth * halfHeight * halfDepth * components);
  8934.    }
  8935. } /* halveImage3D() */
  8936.  
  8937.  
  8938.  
  8939. /*** mipmap.c ***/
  8940.  
  8941.