ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mipmap.c
Go to the documentation of this file.
00001 /*
00002 ** License Applicability. Except to the extent portions of this file are
00003 ** made subject to an alternative license as permitted in the SGI Free
00004 ** Software License B, Version 1.1 (the "License"), the contents of this
00005 ** file are subject only to the provisions of the License. You may not use
00006 ** this file except in compliance with the License. You may obtain a copy
00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
00009 **
00010 ** http://oss.sgi.com/projects/FreeB
00011 **
00012 ** Note that, as provided in the License, the Software is distributed on an
00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00017 **
00018 ** Original Code. The Original Code is: OpenGL Sample Implementation,
00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
00021 ** Copyright in any portions created by third parties is as indicated
00022 ** elsewhere herein. All Rights Reserved.
00023 **
00024 ** Additional Notice Provisions: The application programming interfaces
00025 ** established by SGI in conjunction with the Original Code are The
00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software
00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
00031 ** published by SGI, but has not been independently verified as being
00032 ** compliant with the OpenGL(R) version 1.2.1 Specification.
00033 **
00034 */
00035 
00036 #include "gluos.h"
00037 #include <assert.h>
00038 #include <GL/gl.h>
00039 #include <GL/glext.h>
00040 #include <GL/glu.h>
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <limits.h>     /* UINT_MAX */
00045 #include <math.h>
00046 #include "gluint.h"
00047 
00048 typedef union {
00049     unsigned char ub[4];
00050     unsigned short us[2];
00051     unsigned int ui;
00052     char b[4];
00053     short s[2];
00054     int i;
00055     float f;
00056 } Type_Widget;
00057 
00058 /* Pixel storage modes */
00059 typedef struct {
00060    GLint pack_alignment;
00061    GLint pack_row_length;
00062    GLint pack_skip_rows;
00063    GLint pack_skip_pixels;
00064    GLint pack_lsb_first;
00065    GLint pack_swap_bytes;
00066    GLint pack_skip_images;
00067    GLint pack_image_height;
00068 
00069    GLint unpack_alignment;
00070    GLint unpack_row_length;
00071    GLint unpack_skip_rows;
00072    GLint unpack_skip_pixels;
00073    GLint unpack_lsb_first;
00074    GLint unpack_swap_bytes;
00075    GLint unpack_skip_images;
00076    GLint unpack_image_height;
00077 } PixelStorageModes;
00078 
00079 static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
00080                       GLsizei,
00081                       GLsizei,
00082                       GLenum, GLenum, GLint, GLint, GLint,
00083                       const void *);
00084 static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
00085                       GLsizei, GLsizei,
00086                       GLsizei, GLsizei,
00087                       GLenum, GLenum, GLint, GLint, GLint,
00088                       const void *);
00089 static int gluBuild3DMipmapLevelsCore(GLenum, GLint,
00090                       GLsizei, GLsizei, GLsizei,
00091                       GLsizei, GLsizei, GLsizei,
00092                       GLenum, GLenum, GLint, GLint, GLint,
00093                       const void *);
00094 
00095 /*
00096  * internal function declarations
00097  */
00098 static GLfloat bytes_per_element(GLenum type);
00099 static GLint elements_per_group(GLenum format, GLenum type);
00100 static GLint is_index(GLenum format);
00101 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
00102 static void fill_image(const PixelStorageModes *,
00103                GLint width, GLint height, GLenum format,
00104                GLenum type, GLboolean index_format,
00105                const void *userdata, GLushort *newimage);
00106 static void empty_image(const PixelStorageModes *,
00107             GLint width, GLint height, GLenum format,
00108             GLenum type, GLboolean index_format,
00109             const GLushort *oldimage, void *userdata);
00110 static void scale_internal(GLint components, GLint widthin, GLint heightin,
00111                const GLushort *datain,
00112                GLint widthout, GLint heightout,
00113                GLushort *dataout);
00114 
00115 static void scale_internal_ubyte(GLint components, GLint widthin,
00116                GLint heightin, const GLubyte *datain,
00117                GLint widthout, GLint heightout,
00118                GLubyte *dataout, GLint element_size,
00119                GLint ysize, GLint group_size);
00120 static void scale_internal_byte(GLint components, GLint widthin,
00121                GLint heightin, const GLbyte *datain,
00122                GLint widthout, GLint heightout,
00123                GLbyte *dataout, GLint element_size,
00124                GLint ysize, GLint group_size);
00125 static void scale_internal_ushort(GLint components, GLint widthin,
00126                GLint heightin, const GLushort *datain,
00127                GLint widthout, GLint heightout,
00128                GLushort *dataout, GLint element_size,
00129                GLint ysize, GLint group_size,
00130                GLint myswap_bytes);
00131 static void scale_internal_short(GLint components, GLint widthin,
00132                GLint heightin, const GLshort *datain,
00133                GLint widthout, GLint heightout,
00134                GLshort *dataout, GLint element_size,
00135                GLint ysize, GLint group_size,
00136                GLint myswap_bytes);
00137 static void scale_internal_uint(GLint components, GLint widthin,
00138                GLint heightin, const GLuint *datain,
00139                GLint widthout, GLint heightout,
00140                GLuint *dataout, GLint element_size,
00141                GLint ysize, GLint group_size,
00142                GLint myswap_bytes);
00143 static void scale_internal_int(GLint components, GLint widthin,
00144                GLint heightin, const GLint *datain,
00145                GLint widthout, GLint heightout,
00146                GLint *dataout, GLint element_size,
00147                GLint ysize, GLint group_size,
00148                GLint myswap_bytes);
00149 static void scale_internal_float(GLint components, GLint widthin,
00150                GLint heightin, const GLfloat *datain,
00151                GLint widthout, GLint heightout,
00152                GLfloat *dataout, GLint element_size,
00153                GLint ysize, GLint group_size,
00154                GLint myswap_bytes);
00155 
00156 static int checkMipmapArgs(GLenum, GLenum, GLenum);
00157 static GLboolean legalFormat(GLenum);
00158 static GLboolean legalType(GLenum);
00159 static GLboolean isTypePackedPixel(GLenum);
00160 static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
00161 static GLboolean isLegalLevels(GLint, GLint, GLint, GLint);
00162 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
00163                GLint *, GLint *);
00164 
00165 /* all extract/shove routines must return double to handle unsigned ints */
00166 static GLdouble extractUbyte(int, const void *);
00167 static void shoveUbyte(GLdouble, int, void *);
00168 static GLdouble extractSbyte(int, const void *);
00169 static void shoveSbyte(GLdouble, int, void *);
00170 static GLdouble extractUshort(int, const void *);
00171 static void shoveUshort(GLdouble, int, void *);
00172 static GLdouble extractSshort(int, const void *);
00173 static void shoveSshort(GLdouble, int, void *);
00174 static GLdouble extractUint(int, const void *);
00175 static void shoveUint(GLdouble, int, void *);
00176 static GLdouble extractSint(int, const void *);
00177 static void shoveSint(GLdouble, int, void *);
00178 static GLdouble extractFloat(int, const void *);
00179 static void shoveFloat(GLdouble, int, void *);
00180 static void halveImageSlice(int, GLdouble (*)(int, const void *),
00181                 void (*)(GLdouble, int, void *),
00182                 GLint, GLint, GLint,
00183                 const void *, void *,
00184                 GLint, GLint, GLint, GLint, GLint);
00185 static void halveImage3D(int, GLdouble (*)(int, const void *),
00186              void (*)(GLdouble, int, void *),
00187              GLint, GLint, GLint,
00188              const void *, void *,
00189              GLint, GLint, GLint, GLint, GLint);
00190 
00191 /* packedpixel type scale routines */
00192 static void extract332(int,const void *, GLfloat []);
00193 static void shove332(const GLfloat [],int ,void *);
00194 static void extract233rev(int,const void *, GLfloat []);
00195 static void shove233rev(const GLfloat [],int ,void *);
00196 static void extract565(int,const void *, GLfloat []);
00197 static void shove565(const GLfloat [],int ,void *);
00198 static void extract565rev(int,const void *, GLfloat []);
00199 static void shove565rev(const GLfloat [],int ,void *);
00200 static void extract4444(int,const void *, GLfloat []);
00201 static void shove4444(const GLfloat [],int ,void *);
00202 static void extract4444rev(int,const void *, GLfloat []);
00203 static void shove4444rev(const GLfloat [],int ,void *);
00204 static void extract5551(int,const void *, GLfloat []);
00205 static void shove5551(const GLfloat [],int ,void *);
00206 static void extract1555rev(int,const void *, GLfloat []);
00207 static void shove1555rev(const GLfloat [],int ,void *);
00208 static void extract8888(int,const void *, GLfloat []);
00209 static void shove8888(const GLfloat [],int ,void *);
00210 static void extract8888rev(int,const void *, GLfloat []);
00211 static void shove8888rev(const GLfloat [],int ,void *);
00212 static void extract1010102(int,const void *, GLfloat []);
00213 static void shove1010102(const GLfloat [],int ,void *);
00214 static void extract2101010rev(int,const void *, GLfloat []);
00215 static void shove2101010rev(const GLfloat [],int ,void *);
00216 static void scaleInternalPackedPixel(int,
00217                      void (*)(int, const void *,GLfloat []),
00218                      void (*)(const GLfloat [],int, void *),
00219                      GLint,GLint, const void *,
00220                      GLint,GLint,void *,GLint,GLint,GLint);
00221 static void halveImagePackedPixel(int,
00222                   void (*)(int, const void *,GLfloat []),
00223                   void (*)(const GLfloat [],int, void *),
00224                   GLint, GLint, const void *,
00225                   void *, GLint, GLint, GLint);
00226 static void halve1DimagePackedPixel(int,
00227                     void (*)(int, const void *,GLfloat []),
00228                     void (*)(const GLfloat [],int, void *),
00229                     GLint, GLint, const void *,
00230                     void *, GLint, GLint, GLint);
00231 
00232 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
00233                    GLubyte *, GLint, GLint, GLint);
00234 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
00235                   GLint, GLint, GLint);
00236 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
00237                 GLushort *, GLint, GLint, GLint, GLint);
00238 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
00239                    GLint, GLint, GLint, GLint);
00240 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
00241                   GLint, GLint, GLint, GLint);
00242 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
00243                  GLint, GLint, GLint, GLint);
00244 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
00245                    GLint, GLint, GLint, GLint);
00246 
00247 static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum);
00248 static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
00249             GLenum, GLboolean, const void *, GLushort *);
00250 static void emptyImage3D(const PixelStorageModes *,
00251              GLint, GLint, GLint, GLenum,
00252              GLenum, GLboolean,
00253              const GLushort *, void *);
00254 static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
00255                 GLint, GLint, GLint, GLushort *);
00256 
00257 static void retrieveStoreModes(PixelStorageModes *psm)
00258 {
00259     glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
00260     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
00261     glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
00262     glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
00263     glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
00264     glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
00265 
00266     glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
00267     glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
00268     glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
00269     glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
00270     glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
00271     glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
00272 }
00273 
00274 static void retrieveStoreModes3D(PixelStorageModes *psm)
00275 {
00276     glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
00277     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
00278     glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
00279     glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
00280     glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
00281     glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
00282     glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images);
00283     glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height);
00284 
00285     glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
00286     glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
00287     glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
00288     glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
00289     glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
00290     glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
00291     glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
00292     glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
00293 }
00294 
00295 static int computeLog(GLuint value)
00296 {
00297     int i;
00298 
00299     i = 0;
00300 
00301     /* Error! */
00302     if (value == 0) return -1;
00303 
00304     for (;;) {
00305     if (value & 1) {
00306         /* Error ! */
00307         if (value != 1) return -1;
00308         return i;
00309     }
00310     value = value >> 1;
00311     i++;
00312     }
00313 }
00314 
00315 /*
00316 ** Compute the nearest power of 2 number.  This algorithm is a little
00317 ** strange, but it works quite well.
00318 */
00319 static int nearestPower(GLuint value)
00320 {
00321     int i;
00322 
00323     i = 1;
00324 
00325     /* Error! */
00326     if (value == 0) return -1;
00327 
00328     for (;;) {
00329     if (value == 1) {
00330         return i;
00331     } else if (value == 3) {
00332         return i*4;
00333     }
00334     value = value >> 1;
00335     i *= 2;
00336     }
00337 }
00338 
00339 #define __GLU_SWAP_2_BYTES(s)\
00340 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
00341 
00342 #define __GLU_SWAP_4_BYTES(s)\
00343 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
00344         ((GLuint)((const GLubyte*)(s))[2])<<16 | \
00345         ((GLuint)((const GLubyte*)(s))[1])<<8  | ((const GLubyte*)(s))[0])
00346 
00347 static void halveImage(GLint components, GLuint width, GLuint height,
00348                const GLushort *datain, GLushort *dataout)
00349 {
00350     int i, j, k;
00351     int newwidth, newheight;
00352     int delta;
00353     GLushort *s;
00354     const GLushort *t;
00355 
00356     newwidth = width / 2;
00357     newheight = height / 2;
00358     delta = width * components;
00359     s = dataout;
00360     t = datain;
00361 
00362     /* Piece o' cake! */
00363     for (i = 0; i < newheight; i++) {
00364     for (j = 0; j < newwidth; j++) {
00365         for (k = 0; k < components; k++) {
00366         s[0] = (t[0] + t[components] + t[delta] +
00367             t[delta+components] + 2) / 4;
00368         s++; t++;
00369         }
00370         t += components;
00371     }
00372     t += delta;
00373     }
00374 }
00375 
00376 static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
00377             const GLubyte *datain, GLubyte *dataout,
00378             GLint element_size, GLint ysize, GLint group_size)
00379 {
00380     int i, j, k;
00381     int newwidth, newheight;
00382     GLubyte *s;
00383     const char *t;
00384 
00385     /* handle case where there is only 1 column/row */
00386     if (width == 1 || height == 1) {
00387        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
00388        halve1Dimage_ubyte(components,width,height,datain,dataout,
00389               element_size,ysize,group_size);
00390        return;
00391     }
00392 
00393     newwidth = width / 2;
00394     newheight = height / 2;
00395     s = dataout;
00396     t = (const char *)datain;
00397 
00398     /* Piece o' cake! */
00399     for (i = 0; i < newheight; i++) {
00400     for (j = 0; j < newwidth; j++) {
00401         for (k = 0; k < components; k++) {
00402         s[0] = (*(const GLubyte*)t +
00403             *(const GLubyte*)(t+group_size) +
00404             *(const GLubyte*)(t+ysize) +
00405             *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
00406         s++; t += element_size;
00407         }
00408         t += group_size;
00409     }
00410     t += ysize;
00411     }
00412 }
00413 
00414 /* */
00415 static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
00416                    const GLubyte *dataIn, GLubyte *dataOut,
00417                    GLint element_size, GLint ysize,
00418                    GLint group_size)
00419 {
00420    GLint halfWidth= width / 2;
00421    GLint halfHeight= height / 2;
00422    const char *src= (const char *) dataIn;
00423    GLubyte *dest= dataOut;
00424    int jj;
00425 
00426    assert(width == 1 || height == 1); /* must be 1D */
00427    assert(width != height); /* can't be square */
00428 
00429    if (height == 1) {       /* 1 row */
00430       assert(width != 1);   /* widthxheight can't be 1x1 */
00431       halfHeight= 1;
00432 
00433       for (jj= 0; jj< halfWidth; jj++) {
00434      int kk;
00435      for (kk= 0; kk< components; kk++) {
00436         *dest= (*(const GLubyte*)src +
00437          *(const GLubyte*)(src+group_size)) / 2;
00438 
00439         src+= element_size;
00440         dest++;
00441      }
00442      src+= group_size;  /* skip to next 2 */
00443       }
00444       {
00445      int padBytes= ysize - (width*group_size);
00446      src+= padBytes;    /* for assertion only */
00447       }
00448    }
00449    else if (width == 1) {   /* 1 column */
00450       int padBytes= ysize - (width * group_size);
00451       assert(height != 1);  /* widthxheight can't be 1x1 */
00452       halfWidth= 1;
00453       /* one vertical column with possible pad bytes per row */
00454       /* average two at a time */
00455 
00456       for (jj= 0; jj< halfHeight; jj++) {
00457      int kk;
00458      for (kk= 0; kk< components; kk++) {
00459         *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
00460 
00461         src+= element_size;
00462         dest++;
00463      }
00464      src+= padBytes; /* add pad bytes, if any, to get to end to row */
00465      src+= ysize;
00466       }
00467    }
00468 
00469    assert(src == &((const char *)dataIn)[ysize*height]);
00470    assert((char *)dest == &((char *)dataOut)
00471       [components * element_size * halfWidth * halfHeight]);
00472 } /* halve1Dimage_ubyte() */
00473 
00474 static void halveImage_byte(GLint components, GLuint width, GLuint height,
00475             const GLbyte *datain, GLbyte *dataout,
00476             GLint element_size,
00477             GLint ysize, GLint group_size)
00478 {
00479     int i, j, k;
00480     int newwidth, newheight;
00481     GLbyte *s;
00482     const char *t;
00483 
00484     /* handle case where there is only 1 column/row */
00485     if (width == 1 || height == 1) {
00486        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
00487        halve1Dimage_byte(components,width,height,datain,dataout,
00488              element_size,ysize,group_size);
00489        return;
00490     }
00491 
00492     newwidth = width / 2;
00493     newheight = height / 2;
00494     s = dataout;
00495     t = (const char *)datain;
00496 
00497     /* Piece o' cake! */
00498     for (i = 0; i < newheight; i++) {
00499     for (j = 0; j < newwidth; j++) {
00500         for (k = 0; k < components; k++) {
00501         s[0] = (*(const GLbyte*)t +
00502             *(const GLbyte*)(t+group_size) +
00503             *(const GLbyte*)(t+ysize) +
00504             *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
00505         s++; t += element_size;
00506         }
00507         t += group_size;
00508     }
00509     t += ysize;
00510     }
00511 }
00512 
00513 static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
00514                   const GLbyte *dataIn, GLbyte *dataOut,
00515                   GLint element_size,GLint ysize, GLint group_size)
00516 {
00517    GLint halfWidth= width / 2;
00518    GLint halfHeight= height / 2;
00519    const char *src= (const char *) dataIn;
00520    GLbyte *dest= dataOut;
00521    int jj;
00522 
00523    assert(width == 1 || height == 1); /* must be 1D */
00524    assert(width != height); /* can't be square */
00525 
00526    if (height == 1) {       /* 1 row */
00527       assert(width != 1);   /* widthxheight can't be 1x1 */
00528       halfHeight= 1;
00529 
00530       for (jj= 0; jj< halfWidth; jj++) {
00531      int kk;
00532      for (kk= 0; kk< components; kk++) {
00533         *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
00534 
00535         src+= element_size;
00536         dest++;
00537      }
00538      src+= group_size;  /* skip to next 2 */
00539       }
00540       {
00541      int padBytes= ysize - (width*group_size);
00542      src+= padBytes;    /* for assertion only */
00543       }
00544    }
00545    else if (width == 1) {   /* 1 column */
00546       int padBytes= ysize - (width * group_size);
00547       assert(height != 1);  /* widthxheight can't be 1x1 */
00548       halfWidth= 1;
00549       /* one vertical column with possible pad bytes per row */
00550       /* average two at a time */
00551 
00552       for (jj= 0; jj< halfHeight; jj++) {
00553      int kk;
00554      for (kk= 0; kk< components; kk++) {
00555         *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
00556 
00557         src+= element_size;
00558         dest++;
00559      }
00560      src+= padBytes; /* add pad bytes, if any, to get to end to row */
00561      src+= ysize;
00562       }
00563 
00564       assert(src == &((const char *)dataIn)[ysize*height]);
00565    }
00566 
00567    assert((char *)dest == &((char *)dataOut)
00568       [components * element_size * halfWidth * halfHeight]);
00569 } /* halve1Dimage_byte() */
00570 
00571 static void halveImage_ushort(GLint components, GLuint width, GLuint height,
00572             const GLushort *datain, GLushort *dataout,
00573             GLint element_size, GLint ysize, GLint group_size,
00574             GLint myswap_bytes)
00575 {
00576     int i, j, k;
00577     int newwidth, newheight;
00578     GLushort *s;
00579     const char *t;
00580 
00581     /* handle case where there is only 1 column/row */
00582     if (width == 1 || height == 1) {
00583        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
00584        halve1Dimage_ushort(components,width,height,datain,dataout,
00585                element_size,ysize,group_size, myswap_bytes);
00586        return;
00587     }
00588 
00589     newwidth = width / 2;
00590     newheight = height / 2;
00591     s = dataout;
00592     t = (const char *)datain;
00593 
00594     /* Piece o' cake! */
00595     if (!myswap_bytes)
00596     for (i = 0; i < newheight; i++) {
00597     for (j = 0; j < newwidth; j++) {
00598         for (k = 0; k < components; k++) {
00599         s[0] = (*(const GLushort*)t +
00600             *(const GLushort*)(t+group_size) +
00601             *(const GLushort*)(t+ysize) +
00602             *(const GLushort*)(t+ysize+group_size) + 2) / 4;
00603         s++; t += element_size;
00604         }
00605         t += group_size;
00606     }
00607     t += ysize;
00608     }
00609     else
00610     for (i = 0; i < newheight; i++) {
00611     for (j = 0; j < newwidth; j++) {
00612         for (k = 0; k < components; k++) {
00613         s[0] = (__GLU_SWAP_2_BYTES(t) +
00614             __GLU_SWAP_2_BYTES(t+group_size) +
00615             __GLU_SWAP_2_BYTES(t+ysize) +
00616             __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
00617         s++; t += element_size;
00618         }
00619         t += group_size;
00620     }
00621     t += ysize;
00622     }
00623 }
00624 
00625 static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
00626                 const GLushort *dataIn, GLushort *dataOut,
00627                 GLint element_size, GLint ysize,
00628                 GLint group_size, GLint myswap_bytes)
00629 {
00630    GLint halfWidth= width / 2;
00631    GLint halfHeight= height / 2;
00632    const char *src= (const char *) dataIn;
00633    GLushort *dest= dataOut;
00634    int jj;
00635 
00636    assert(width == 1 || height == 1); /* must be 1D */
00637    assert(width != height); /* can't be square */
00638 
00639    if (height == 1) {       /* 1 row */
00640       assert(width != 1);   /* widthxheight can't be 1x1 */
00641       halfHeight= 1;
00642 
00643       for (jj= 0; jj< halfWidth; jj++) {
00644      int kk;
00645      for (kk= 0; kk< components; kk++) {
00646 #define BOX2 2
00647         GLushort ushort[BOX2];
00648         if (myswap_bytes) {
00649            ushort[0]= __GLU_SWAP_2_BYTES(src);
00650            ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
00651         }
00652         else {
00653            ushort[0]= *(const GLushort*)src;
00654            ushort[1]= *(const GLushort*)(src+group_size);
00655         }
00656 
00657         *dest= (ushort[0] + ushort[1]) / 2;
00658         src+= element_size;
00659         dest++;
00660      }
00661      src+= group_size;  /* skip to next 2 */
00662       }
00663       {
00664      int padBytes= ysize - (width*group_size);
00665      src+= padBytes;    /* for assertion only */
00666       }
00667    }
00668    else if (width == 1) {   /* 1 column */
00669       int padBytes= ysize - (width * group_size);
00670       assert(height != 1);  /* widthxheight can't be 1x1 */
00671       halfWidth= 1;
00672       /* one vertical column with possible pad bytes per row */
00673       /* average two at a time */
00674 
00675       for (jj= 0; jj< halfHeight; jj++) {
00676      int kk;
00677      for (kk= 0; kk< components; kk++) {
00678 #define BOX2 2
00679         GLushort ushort[BOX2];
00680         if (myswap_bytes) {
00681            ushort[0]= __GLU_SWAP_2_BYTES(src);
00682            ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
00683         }
00684         else {
00685            ushort[0]= *(const GLushort*)src;
00686            ushort[1]= *(const GLushort*)(src+ysize);
00687         }
00688         *dest= (ushort[0] + ushort[1]) / 2;
00689 
00690         src+= element_size;
00691         dest++;
00692      }
00693      src+= padBytes; /* add pad bytes, if any, to get to end to row */
00694      src+= ysize;
00695       }
00696 
00697       assert(src == &((const char *)dataIn)[ysize*height]);
00698    }
00699 
00700    assert((char *)dest == &((char *)dataOut)
00701       [components * element_size * halfWidth * halfHeight]);
00702 
00703 } /* halve1Dimage_ushort() */
00704 
00705 
00706 static void halveImage_short(GLint components, GLuint width, GLuint height,
00707             const GLshort *datain, GLshort *dataout,
00708             GLint element_size, GLint ysize, GLint group_size,
00709             GLint myswap_bytes)
00710 {
00711     int i, j, k;
00712     int newwidth, newheight;
00713     GLshort *s;
00714     const char *t;
00715 
00716     /* handle case where there is only 1 column/row */
00717     if (width == 1 || height == 1) {
00718        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
00719        halve1Dimage_short(components,width,height,datain,dataout,
00720               element_size,ysize,group_size, myswap_bytes);
00721        return;
00722     }
00723 
00724     newwidth = width / 2;
00725     newheight = height / 2;
00726     s = dataout;
00727     t = (const char *)datain;
00728 
00729     /* Piece o' cake! */
00730     if (!myswap_bytes)
00731     for (i = 0; i < newheight; i++) {
00732     for (j = 0; j < newwidth; j++) {
00733         for (k = 0; k < components; k++) {
00734         s[0] = (*(const GLshort*)t +
00735             *(const GLshort*)(t+group_size) +
00736             *(const GLshort*)(t+ysize) +
00737             *(const GLshort*)(t+ysize+group_size) + 2) / 4;
00738         s++; t += element_size;
00739         }
00740         t += group_size;
00741     }
00742     t += ysize;
00743     }
00744     else
00745     for (i = 0; i < newheight; i++) {
00746     for (j = 0; j < newwidth; j++) {
00747         for (k = 0; k < components; k++) {
00748         GLushort b;
00749         GLint buf;
00750         b = __GLU_SWAP_2_BYTES(t);
00751         buf = *(const GLshort*)&b;
00752         b = __GLU_SWAP_2_BYTES(t+group_size);
00753         buf += *(const GLshort*)&b;
00754         b = __GLU_SWAP_2_BYTES(t+ysize);
00755         buf += *(const GLshort*)&b;
00756         b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
00757         buf += *(const GLshort*)&b;
00758         s[0] = (GLshort)((buf+2)/4);
00759         s++; t += element_size;
00760         }
00761         t += group_size;
00762     }
00763     t += ysize;
00764     }
00765 }
00766 
00767 static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
00768                 const GLshort *dataIn, GLshort *dataOut,
00769                 GLint element_size, GLint ysize,
00770                 GLint group_size, GLint myswap_bytes)
00771 {
00772    GLint halfWidth= width / 2;
00773    GLint halfHeight= height / 2;
00774    const char *src= (const char *) dataIn;
00775    GLshort *dest= dataOut;
00776    int jj;
00777 
00778    assert(width == 1 || height == 1); /* must be 1D */
00779    assert(width != height); /* can't be square */
00780 
00781    if (height == 1) {       /* 1 row */
00782       assert(width != 1);   /* widthxheight can't be 1x1 */
00783       halfHeight= 1;
00784 
00785       for (jj= 0; jj< halfWidth; jj++) {
00786      int kk;
00787      for (kk= 0; kk< components; kk++) {
00788 #define BOX2 2
00789         GLshort sshort[BOX2];
00790         if (myswap_bytes) {
00791            sshort[0]= __GLU_SWAP_2_BYTES(src);
00792            sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
00793         }
00794         else {
00795            sshort[0]= *(const GLshort*)src;
00796            sshort[1]= *(const GLshort*)(src+group_size);
00797         }
00798 
00799         *dest= (sshort[0] + sshort[1]) / 2;
00800         src+= element_size;
00801         dest++;
00802      }
00803      src+= group_size;  /* skip to next 2 */
00804       }
00805       {
00806      int padBytes= ysize - (width*group_size);
00807      src+= padBytes;    /* for assertion only */
00808       }
00809    }
00810    else if (width == 1) {   /* 1 column */
00811       int padBytes= ysize - (width * group_size);
00812       assert(height != 1);  /* widthxheight can't be 1x1 */
00813       halfWidth= 1;
00814       /* one vertical column with possible pad bytes per row */
00815       /* average two at a time */
00816 
00817       for (jj= 0; jj< halfHeight; jj++) {
00818      int kk;
00819      for (kk= 0; kk< components; kk++) {
00820 #define BOX2 2
00821         GLshort sshort[BOX2];
00822         if (myswap_bytes) {
00823            sshort[0]= __GLU_SWAP_2_BYTES(src);
00824            sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
00825         }
00826         else {
00827            sshort[0]= *(const GLshort*)src;
00828            sshort[1]= *(const GLshort*)(src+ysize);
00829         }
00830         *dest= (sshort[0] + sshort[1]) / 2;
00831 
00832         src+= element_size;
00833         dest++;
00834      }
00835      src+= padBytes; /* add pad bytes, if any, to get to end to row */
00836      src+= ysize;
00837       }
00838 
00839       assert(src == &((const char *)dataIn)[ysize*height]);
00840    }
00841 
00842    assert((char *)dest == &((char *)dataOut)
00843       [components * element_size * halfWidth * halfHeight]);
00844 
00845 } /* halve1Dimage_short() */
00846 
00847 
00848 static void halveImage_uint(GLint components, GLuint width, GLuint height,
00849             const GLuint *datain, GLuint *dataout,
00850             GLint element_size, GLint ysize, GLint group_size,
00851             GLint myswap_bytes)
00852 {
00853     int i, j, k;
00854     int newwidth, newheight;
00855     GLuint *s;
00856     const char *t;
00857 
00858     /* handle case where there is only 1 column/row */
00859     if (width == 1 || height == 1) {
00860        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
00861        halve1Dimage_uint(components,width,height,datain,dataout,
00862              element_size,ysize,group_size, myswap_bytes);
00863        return;
00864     }
00865 
00866     newwidth = width / 2;
00867     newheight = height / 2;
00868     s = dataout;
00869     t = (const char *)datain;
00870 
00871     /* Piece o' cake! */
00872     if (!myswap_bytes)
00873     for (i = 0; i < newheight; i++) {
00874     for (j = 0; j < newwidth; j++) {
00875         for (k = 0; k < components; k++) {
00876         /* need to cast to double to hold large unsigned ints */
00877         s[0] = ((double)*(const GLuint*)t +
00878             (double)*(const GLuint*)(t+group_size) +
00879             (double)*(const GLuint*)(t+ysize) +
00880             (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
00881         s++; t += element_size;
00882 
00883         }
00884         t += group_size;
00885     }
00886     t += ysize;
00887     }
00888     else
00889     for (i = 0; i < newheight; i++) {
00890     for (j = 0; j < newwidth; j++) {
00891         for (k = 0; k < components; k++) {
00892         /* need to cast to double to hold large unsigned ints */
00893         GLdouble buf;
00894         buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
00895               (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
00896               (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
00897               (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
00898         s[0] = (GLuint)(buf/4 + 0.5);
00899 
00900         s++; t += element_size;
00901         }
00902         t += group_size;
00903     }
00904     t += ysize;
00905     }
00906 }
00907 
00908 /* */
00909 static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
00910                   const GLuint *dataIn, GLuint *dataOut,
00911                   GLint element_size, GLint ysize,
00912                   GLint group_size, GLint myswap_bytes)
00913 {
00914    GLint halfWidth= width / 2;
00915    GLint halfHeight= height / 2;
00916    const char *src= (const char *) dataIn;
00917    GLuint *dest= dataOut;
00918    int jj;
00919 
00920    assert(width == 1 || height == 1); /* must be 1D */
00921    assert(width != height); /* can't be square */
00922 
00923    if (height == 1) {       /* 1 row */
00924       assert(width != 1);   /* widthxheight can't be 1x1 */
00925       halfHeight= 1;
00926 
00927       for (jj= 0; jj< halfWidth; jj++) {
00928      int kk;
00929      for (kk= 0; kk< components; kk++) {
00930 #define BOX2 2
00931         GLuint uint[BOX2];
00932         if (myswap_bytes) {
00933            uint[0]= __GLU_SWAP_4_BYTES(src);
00934            uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
00935         }
00936         else {
00937            uint[0]= *(const GLuint*)src;
00938            uint[1]= *(const GLuint*)(src+group_size);
00939         }
00940         *dest= ((double)uint[0]+(double)uint[1])/2.0;
00941 
00942         src+= element_size;
00943         dest++;
00944      }
00945      src+= group_size;  /* skip to next 2 */
00946       }
00947       {
00948      int padBytes= ysize - (width*group_size);
00949      src+= padBytes;    /* for assertion only */
00950       }
00951    }
00952    else if (width == 1) {   /* 1 column */
00953       int padBytes= ysize - (width * group_size);
00954       assert(height != 1);  /* widthxheight can't be 1x1 */
00955       halfWidth= 1;
00956       /* one vertical column with possible pad bytes per row */
00957       /* average two at a time */
00958 
00959       for (jj= 0; jj< halfHeight; jj++) {
00960      int kk;
00961      for (kk= 0; kk< components; kk++) {
00962 #define BOX2 2
00963         GLuint uint[BOX2];
00964         if (myswap_bytes) {
00965            uint[0]= __GLU_SWAP_4_BYTES(src);
00966            uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
00967         }
00968         else {
00969            uint[0]= *(const GLuint*)src;
00970            uint[1]= *(const GLuint*)(src+ysize);
00971         }
00972         *dest= ((double)uint[0]+(double)uint[1])/2.0;
00973 
00974         src+= element_size;
00975         dest++;
00976      }
00977      src+= padBytes; /* add pad bytes, if any, to get to end to row */
00978      src+= ysize;
00979       }
00980 
00981       assert(src == &((const char *)dataIn)[ysize*height]);
00982    }
00983 
00984    assert((char *)dest == &((char *)dataOut)
00985       [components * element_size * halfWidth * halfHeight]);
00986 
00987 } /* halve1Dimage_uint() */
00988 
00989 static void halveImage_int(GLint components, GLuint width, GLuint height,
00990             const GLint *datain, GLint *dataout, GLint element_size,
00991             GLint ysize, GLint group_size, GLint myswap_bytes)
00992 {
00993     int i, j, k;
00994     int newwidth, newheight;
00995     GLint *s;
00996     const char *t;
00997 
00998     /* handle case where there is only 1 column/row */
00999     if (width == 1 || height == 1) {
01000        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
01001        halve1Dimage_int(components,width,height,datain,dataout,
01002             element_size,ysize,group_size, myswap_bytes);
01003        return;
01004     }
01005 
01006     newwidth = width / 2;
01007     newheight = height / 2;
01008     s = dataout;
01009     t = (const char *)datain;
01010 
01011     /* Piece o' cake! */
01012     if (!myswap_bytes)
01013     for (i = 0; i < newheight; i++) {
01014     for (j = 0; j < newwidth; j++) {
01015         for (k = 0; k < components; k++) {
01016         s[0] = ((float)*(const GLint*)t +
01017             (float)*(const GLint*)(t+group_size) +
01018             (float)*(const GLint*)(t+ysize) +
01019             (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
01020         s++; t += element_size;
01021         }
01022         t += group_size;
01023     }
01024     t += ysize;
01025     }
01026     else
01027     for (i = 0; i < newheight; i++) {
01028     for (j = 0; j < newwidth; j++) {
01029         for (k = 0; k < components; k++) {
01030         GLuint b;
01031         GLfloat buf;
01032         b = __GLU_SWAP_4_BYTES(t);
01033         buf = *(GLint*)&b;
01034         b = __GLU_SWAP_4_BYTES(t+group_size);
01035         buf += *(GLint*)&b;
01036         b = __GLU_SWAP_4_BYTES(t+ysize);
01037         buf += *(GLint*)&b;
01038         b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
01039         buf += *(GLint*)&b;
01040         s[0] = (GLint)(buf/4 + 0.5);
01041 
01042         s++; t += element_size;
01043         }
01044         t += group_size;
01045     }
01046     t += ysize;
01047     }
01048 }
01049 
01050 /* */
01051 static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
01052                  const GLint *dataIn, GLint *dataOut,
01053                  GLint element_size, GLint ysize,
01054                  GLint group_size, GLint myswap_bytes)
01055 {
01056    GLint halfWidth= width / 2;
01057    GLint halfHeight= height / 2;
01058    const char *src= (const char *) dataIn;
01059    GLint *dest= dataOut;
01060    int jj;
01061 
01062    assert(width == 1 || height == 1); /* must be 1D */
01063    assert(width != height); /* can't be square */
01064 
01065    if (height == 1) {       /* 1 row */
01066       assert(width != 1);   /* widthxheight can't be 1x1 */
01067       halfHeight= 1;
01068 
01069       for (jj= 0; jj< halfWidth; jj++) {
01070      int kk;
01071      for (kk= 0; kk< components; kk++) {
01072 #define BOX2 2
01073         GLuint uint[BOX2];
01074         if (myswap_bytes) {
01075            uint[0]= __GLU_SWAP_4_BYTES(src);
01076            uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
01077         }
01078         else {
01079            uint[0]= *(const GLuint*)src;
01080            uint[1]= *(const GLuint*)(src+group_size);
01081         }
01082         *dest= ((float)uint[0]+(float)uint[1])/2.0;
01083 
01084         src+= element_size;
01085         dest++;
01086      }
01087      src+= group_size;  /* skip to next 2 */
01088       }
01089       {
01090      int padBytes= ysize - (width*group_size);
01091      src+= padBytes;    /* for assertion only */
01092       }
01093    }
01094    else if (width == 1) {   /* 1 column */
01095       int padBytes= ysize - (width * group_size);
01096       assert(height != 1);  /* widthxheight can't be 1x1 */
01097       halfWidth= 1;
01098       /* one vertical column with possible pad bytes per row */
01099       /* average two at a time */
01100 
01101       for (jj= 0; jj< halfHeight; jj++) {
01102      int kk;
01103      for (kk= 0; kk< components; kk++) {
01104 #define BOX2 2
01105         GLuint uint[BOX2];
01106         if (myswap_bytes) {
01107            uint[0]= __GLU_SWAP_4_BYTES(src);
01108            uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
01109         }
01110         else {
01111            uint[0]= *(const GLuint*)src;
01112            uint[1]= *(const GLuint*)(src+ysize);
01113         }
01114         *dest= ((float)uint[0]+(float)uint[1])/2.0;
01115 
01116         src+= element_size;
01117         dest++;
01118      }
01119      src+= padBytes; /* add pad bytes, if any, to get to end to row */
01120      src+= ysize;
01121       }
01122 
01123       assert(src == &((const char *)dataIn)[ysize*height]);
01124    }
01125 
01126    assert((char *)dest == &((char *)dataOut)
01127       [components * element_size * halfWidth * halfHeight]);
01128 
01129 } /* halve1Dimage_int() */
01130 
01131 
01132 static void halveImage_float(GLint components, GLuint width, GLuint height,
01133             const GLfloat *datain, GLfloat *dataout,
01134             GLint element_size, GLint ysize, GLint group_size,
01135             GLint myswap_bytes)
01136 {
01137     int i, j, k;
01138     int newwidth, newheight;
01139     GLfloat *s;
01140     const char *t;
01141 
01142     /* handle case where there is only 1 column/row */
01143     if (width == 1 || height == 1) {
01144        assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
01145        halve1Dimage_float(components,width,height,datain,dataout,
01146               element_size,ysize,group_size, myswap_bytes);
01147        return;
01148     }
01149 
01150     newwidth = width / 2;
01151     newheight = height / 2;
01152     s = dataout;
01153     t = (const char *)datain;
01154 
01155     /* Piece o' cake! */
01156     if (!myswap_bytes)
01157     for (i = 0; i < newheight; i++) {
01158     for (j = 0; j < newwidth; j++) {
01159         for (k = 0; k < components; k++) {
01160         s[0] = (*(const GLfloat*)t +
01161             *(const GLfloat*)(t+group_size) +
01162             *(const GLfloat*)(t+ysize) +
01163             *(const GLfloat*)(t+ysize+group_size)) / 4;
01164         s++; t += element_size;
01165         }
01166         t += group_size;
01167     }
01168     t += ysize;
01169     }
01170     else
01171     for (i = 0; i < newheight; i++) {
01172     for (j = 0; j < newwidth; j++) {
01173         for (k = 0; k < components; k++) {
01174         GLuint b;
01175         b = __GLU_SWAP_4_BYTES(t);
01176         s[0] = *(GLfloat*)&b;
01177         b = __GLU_SWAP_4_BYTES(t+group_size);
01178         s[0] += *(GLfloat*)&b;
01179         b = __GLU_SWAP_4_BYTES(t+ysize);
01180         s[0] += *(GLfloat*)&b;
01181         b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
01182         s[0] += *(GLfloat*)&b;
01183         s[0] /= 4;
01184         s++; t += element_size;
01185         }
01186         t += group_size;
01187     }
01188     t += ysize;
01189     }
01190 }
01191 
01192 /* */
01193 static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
01194                    const GLfloat *dataIn, GLfloat *dataOut,
01195                    GLint element_size, GLint ysize,
01196                    GLint group_size, GLint myswap_bytes)
01197 {
01198    GLint halfWidth= width / 2;
01199    GLint halfHeight= height / 2;
01200    const char *src= (const char *) dataIn;
01201    GLfloat *dest= dataOut;
01202    int jj;
01203 
01204    assert(width == 1 || height == 1); /* must be 1D */
01205    assert(width != height); /* can't be square */
01206 
01207    if (height == 1) {       /* 1 row */
01208       assert(width != 1);   /* widthxheight can't be 1x1 */
01209       halfHeight= 1;
01210 
01211       for (jj= 0; jj< halfWidth; jj++) {
01212      int kk;
01213      for (kk= 0; kk< components; kk++) {
01214 #define BOX2 2
01215         GLfloat sfloat[BOX2];
01216         if (myswap_bytes) {
01217            sfloat[0]= __GLU_SWAP_4_BYTES(src);
01218            sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
01219         }
01220         else {
01221            sfloat[0]= *(const GLfloat*)src;
01222            sfloat[1]= *(const GLfloat*)(src+group_size);
01223         }
01224 
01225         *dest= (sfloat[0] + sfloat[1]) / 2.0;
01226         src+= element_size;
01227         dest++;
01228      }
01229      src+= group_size;  /* skip to next 2 */
01230       }
01231       {
01232      int padBytes= ysize - (width*group_size);
01233      src+= padBytes;    /* for assertion only */
01234       }
01235    }
01236    else if (width == 1) {   /* 1 column */
01237       int padBytes= ysize - (width * group_size);
01238       assert(height != 1);  /* widthxheight can't be 1x1 */
01239       halfWidth= 1;
01240       /* one vertical column with possible pad bytes per row */
01241       /* average two at a time */
01242 
01243       for (jj= 0; jj< halfHeight; jj++) {
01244      int kk;
01245      for (kk= 0; kk< components; kk++) {
01246 #define BOX2 2
01247         GLfloat sfloat[BOX2];
01248         if (myswap_bytes) {
01249            sfloat[0]= __GLU_SWAP_4_BYTES(src);
01250            sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
01251         }
01252         else {
01253            sfloat[0]= *(const GLfloat*)src;
01254            sfloat[1]= *(const GLfloat*)(src+ysize);
01255         }
01256         *dest= (sfloat[0] + sfloat[1]) / 2.0;
01257 
01258         src+= element_size;
01259         dest++;
01260      }
01261      src+= padBytes; /* add pad bytes, if any, to get to end to row */
01262      src+= ysize;       /* skip to odd row */
01263       }
01264    }
01265 
01266    assert(src == &((const char *)dataIn)[ysize*height]);
01267    assert((char *)dest == &((char *)dataOut)
01268       [components * element_size * halfWidth * halfHeight]);
01269 } /* halve1Dimage_float() */
01270 
01271 static void scale_internal(GLint components, GLint widthin, GLint heightin,
01272                const GLushort *datain,
01273                GLint widthout, GLint heightout,
01274                GLushort *dataout)
01275 {
01276     float x, lowx, highx, convx, halfconvx;
01277     float y, lowy, highy, convy, halfconvy;
01278     float xpercent,ypercent;
01279     float percent;
01280     /* Max components in a format is 4, so... */
01281     float totals[4];
01282     float area;
01283     int i,j,k,yint,xint,xindex,yindex;
01284     int temp;
01285 
01286     if (widthin == widthout*2 && heightin == heightout*2) {
01287     halveImage(components, widthin, heightin, datain, dataout);
01288     return;
01289     }
01290     convy = (float) heightin/heightout;
01291     convx = (float) widthin/widthout;
01292     halfconvx = convx/2;
01293     halfconvy = convy/2;
01294     for (i = 0; i < heightout; i++) {
01295     y = convy * (i+0.5);
01296     if (heightin > heightout) {
01297         highy = y + halfconvy;
01298         lowy = y - halfconvy;
01299     } else {
01300         highy = y + 0.5;
01301         lowy = y - 0.5;
01302     }
01303     for (j = 0; j < widthout; j++) {
01304         x = convx * (j+0.5);
01305         if (widthin > widthout) {
01306         highx = x + halfconvx;
01307         lowx = x - halfconvx;
01308         } else {
01309         highx = x + 0.5;
01310         lowx = x - 0.5;
01311         }
01312 
01313         /*
01314         ** Ok, now apply box filter to box that goes from (lowx, lowy)
01315         ** to (highx, highy) on input data into this pixel on output
01316         ** data.
01317         */
01318         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
01319         area = 0.0;
01320 
01321         y = lowy;
01322         yint = floor(y);
01323         while (y < highy) {
01324         yindex = (yint + heightin) % heightin;
01325         if (highy < yint+1) {
01326             ypercent = highy - y;
01327         } else {
01328             ypercent = yint+1 - y;
01329         }
01330 
01331         x = lowx;
01332         xint = floor(x);
01333 
01334         while (x < highx) {
01335             xindex = (xint + widthin) % widthin;
01336             if (highx < xint+1) {
01337             xpercent = highx - x;
01338             } else {
01339             xpercent = xint+1 - x;
01340             }
01341 
01342             percent = xpercent * ypercent;
01343             area += percent;
01344             temp = (xindex + (yindex * widthin)) * components;
01345             for (k = 0; k < components; k++) {
01346             totals[k] += datain[temp + k] * percent;
01347             }
01348 
01349             xint++;
01350             x = xint;
01351         }
01352         yint++;
01353         y = yint;
01354         }
01355 
01356         temp = (j + (i * widthout)) * components;
01357         for (k = 0; k < components; k++) {
01358         /* totals[] should be rounded in the case of enlarging an RGB
01359          * ramp when the type is 332 or 4444
01360          */
01361         dataout[temp + k] = (totals[k]+0.5)/area;
01362         }
01363     }
01364     }
01365 }
01366 
01367 static void scale_internal_ubyte(GLint components, GLint widthin,
01368                GLint heightin, const GLubyte *datain,
01369                GLint widthout, GLint heightout,
01370                GLubyte *dataout, GLint element_size,
01371                GLint ysize, GLint group_size)
01372 {
01373     float convx;
01374     float convy;
01375     float percent;
01376     /* Max components in a format is 4, so... */
01377     float totals[4];
01378     float area;
01379     int i,j,k,xindex;
01380 
01381     const char *temp, *temp0;
01382     const char *temp_index;
01383     int outindex;
01384 
01385     int lowx_int, highx_int, lowy_int, highy_int;
01386     float x_percent, y_percent;
01387     float lowx_float, highx_float, lowy_float, highy_float;
01388     float convy_float, convx_float;
01389     int convy_int, convx_int;
01390     int l, m;
01391     const char *left, *right;
01392 
01393     if (widthin == widthout*2 && heightin == heightout*2) {
01394     halveImage_ubyte(components, widthin, heightin,
01395     (const GLubyte *)datain, (GLubyte *)dataout,
01396     element_size, ysize, group_size);
01397     return;
01398     }
01399     convy = (float) heightin/heightout;
01400     convx = (float) widthin/widthout;
01401     convy_int = floor(convy);
01402     convy_float = convy - convy_int;
01403     convx_int = floor(convx);
01404     convx_float = convx - convx_int;
01405 
01406     area = convx * convy;
01407 
01408     lowy_int = 0;
01409     lowy_float = 0;
01410     highy_int = convy_int;
01411     highy_float = convy_float;
01412 
01413     for (i = 0; i < heightout; i++) {
01414     lowx_int = 0;
01415     lowx_float = 0;
01416     highx_int = convx_int;
01417     highx_float = convx_float;
01418 
01419     for (j = 0; j < widthout; j++) {
01420 
01421         /*
01422         ** Ok, now apply box filter to box that goes from (lowx, lowy)
01423         ** to (highx, highy) on input data into this pixel on output
01424         ** data.
01425         */
01426         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
01427 
01428         /* calculate the value for pixels in the 1st row */
01429         xindex = lowx_int*group_size;
01430         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
01431 
01432         y_percent = 1-lowy_float;
01433         temp = (const char *)datain + xindex + lowy_int * ysize;
01434         percent = y_percent * (1-lowx_float);
01435         for (k = 0, temp_index = temp; k < components;
01436              k++, temp_index += element_size) {
01437             totals[k] += (GLubyte)(*(temp_index)) * percent;
01438         }
01439         left = temp;
01440         for(l = lowx_int+1; l < highx_int; l++) {
01441             temp += group_size;
01442             for (k = 0, temp_index = temp; k < components;
01443              k++, temp_index += element_size) {
01444             totals[k] += (GLubyte)(*(temp_index)) * y_percent;
01445             }
01446         }
01447         temp += group_size;
01448         right = temp;
01449         percent = y_percent * highx_float;
01450         for (k = 0, temp_index = temp; k < components;
01451              k++, temp_index += element_size) {
01452             totals[k] += (GLubyte)(*(temp_index)) * percent;
01453         }
01454 
01455         /* calculate the value for pixels in the last row */
01456         y_percent = highy_float;
01457         percent = y_percent * (1-lowx_float);
01458         temp = (const char *)datain + xindex + highy_int * ysize;
01459         for (k = 0, temp_index = temp; k < components;
01460              k++, temp_index += element_size) {
01461             totals[k] += (GLubyte)(*(temp_index)) * percent;
01462         }
01463         for(l = lowx_int+1; l < highx_int; l++) {
01464             temp += group_size;
01465             for (k = 0, temp_index = temp; k < components;
01466              k++, temp_index += element_size) {
01467             totals[k] += (GLubyte)(*(temp_index)) * y_percent;
01468             }
01469         }
01470         temp += group_size;
01471         percent = y_percent * highx_float;
01472         for (k = 0, temp_index = temp; k < components;
01473              k++, temp_index += element_size) {
01474             totals[k] += (GLubyte)(*(temp_index)) * percent;
01475         }
01476 
01477 
01478         /* calculate the value for pixels in the 1st and last column */
01479         for(m = lowy_int+1; m < highy_int; m++) {
01480             left += ysize;
01481             right += ysize;
01482             for (k = 0; k < components;
01483              k++, left += element_size, right += element_size) {
01484             totals[k] += (GLubyte)(*(left))*(1-lowx_float)
01485                 +(GLubyte)(*(right))*highx_float;
01486             }
01487         }
01488         } else if (highy_int > lowy_int) {
01489         x_percent = highx_float - lowx_float;
01490         percent = (1-lowy_float)*x_percent;
01491         temp = (const char *)datain + xindex + lowy_int*ysize;
01492         for (k = 0, temp_index = temp; k < components;
01493              k++, temp_index += element_size) {
01494             totals[k] += (GLubyte)(*(temp_index)) * percent;
01495         }
01496         for(m = lowy_int+1; m < highy_int; m++) {
01497             temp += ysize;
01498             for (k = 0, temp_index = temp; k < components;
01499              k++, temp_index += element_size) {
01500             totals[k] += (GLubyte)(*(temp_index)) * x_percent;
01501             }
01502         }
01503         percent = x_percent * highy_float;
01504         temp += ysize;
01505         for (k = 0, temp_index = temp; k < components;
01506              k++, temp_index += element_size) {
01507             totals[k] += (GLubyte)(*(temp_index)) * percent;
01508         }
01509         } else if (highx_int > lowx_int) {
01510         y_percent = highy_float - lowy_float;
01511         percent = (1-lowx_float)*y_percent;
01512         temp = (const char *)datain + xindex + lowy_int*ysize;
01513         for (k = 0, temp_index = temp; k < components;
01514              k++, temp_index += element_size) {
01515             totals[k] += (GLubyte)(*(temp_index)) * percent;
01516         }
01517         for (l = lowx_int+1; l < highx_int; l++) {
01518             temp += group_size;
01519             for (k = 0, temp_index = temp; k < components;
01520              k++, temp_index += element_size) {
01521             totals[k] += (GLubyte)(*(temp_index)) * y_percent;
01522             }
01523         }
01524         temp += group_size;
01525         percent = y_percent * highx_float;
01526         for (k = 0, temp_index = temp; k < components;
01527              k++, temp_index += element_size) {
01528             totals[k] += (GLubyte)(*(temp_index)) * percent;
01529         }
01530         } else {
01531         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
01532         temp = (const char *)datain + xindex + lowy_int * ysize;
01533         for (k = 0, temp_index = temp; k < components;
01534              k++, temp_index += element_size) {
01535             totals[k] += (GLubyte)(*(temp_index)) * percent;
01536         }
01537         }
01538 
01539 
01540 
01541         /* this is for the pixels in the body */
01542         temp0 = (const char *)datain + xindex + group_size +
01543          (lowy_int+1)*ysize;
01544         for (m = lowy_int+1; m < highy_int; m++) {
01545         temp = temp0;
01546         for(l = lowx_int+1; l < highx_int; l++) {
01547             for (k = 0, temp_index = temp; k < components;
01548              k++, temp_index += element_size) {
01549             totals[k] += (GLubyte)(*(temp_index));
01550             }
01551             temp += group_size;
01552         }
01553         temp0 += ysize;
01554         }
01555 
01556         outindex = (j + (i * widthout)) * components;
01557         for (k = 0; k < components; k++) {
01558         dataout[outindex + k] = totals[k]/area;
01559         /*printf("totals[%d] = %f\n", k, totals[k]);*/
01560         }
01561         lowx_int = highx_int;
01562         lowx_float = highx_float;
01563         highx_int += convx_int;
01564         highx_float += convx_float;
01565         if(highx_float > 1) {
01566         highx_float -= 1.0;
01567         highx_int++;
01568         }
01569     }
01570     lowy_int = highy_int;
01571     lowy_float = highy_float;
01572     highy_int += convy_int;
01573     highy_float += convy_float;
01574     if(highy_float > 1) {
01575         highy_float -= 1.0;
01576         highy_int++;
01577     }
01578     }
01579 }
01580 
01581 static void scale_internal_byte(GLint components, GLint widthin,
01582                GLint heightin, const GLbyte *datain,
01583                GLint widthout, GLint heightout,
01584                GLbyte *dataout, GLint element_size,
01585                GLint ysize, GLint group_size)
01586 {
01587     float convx;
01588     float convy;
01589     float percent;
01590     /* Max components in a format is 4, so... */
01591     float totals[4];
01592     float area;
01593     int i,j,k,xindex;
01594 
01595     const char *temp, *temp0;
01596     const char *temp_index;
01597     int outindex;
01598 
01599     int lowx_int, highx_int, lowy_int, highy_int;
01600     float x_percent, y_percent;
01601     float lowx_float, highx_float, lowy_float, highy_float;
01602     float convy_float, convx_float;
01603     int convy_int, convx_int;
01604     int l, m;
01605     const char *left, *right;
01606 
01607     if (widthin == widthout*2 && heightin == heightout*2) {
01608     halveImage_byte(components, widthin, heightin,
01609     (const GLbyte *)datain, (GLbyte *)dataout,
01610     element_size, ysize, group_size);
01611     return;
01612     }
01613     convy = (float) heightin/heightout;
01614     convx = (float) widthin/widthout;
01615     convy_int = floor(convy);
01616     convy_float = convy - convy_int;
01617     convx_int = floor(convx);
01618     convx_float = convx - convx_int;
01619 
01620     area = convx * convy;
01621 
01622     lowy_int = 0;
01623     lowy_float = 0;
01624     highy_int = convy_int;
01625     highy_float = convy_float;
01626 
01627     for (i = 0; i < heightout; i++) {
01628     lowx_int = 0;
01629     lowx_float = 0;
01630     highx_int = convx_int;
01631     highx_float = convx_float;
01632 
01633     for (j = 0; j < widthout; j++) {
01634 
01635         /*
01636         ** Ok, now apply box filter to box that goes from (lowx, lowy)
01637         ** to (highx, highy) on input data into this pixel on output
01638         ** data.
01639         */
01640         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
01641 
01642         /* calculate the value for pixels in the 1st row */
01643         xindex = lowx_int*group_size;
01644         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
01645 
01646         y_percent = 1-lowy_float;
01647         temp = (const char *)datain + xindex + lowy_int * ysize;
01648         percent = y_percent * (1-lowx_float);
01649         for (k = 0, temp_index = temp; k < components;
01650              k++, temp_index += element_size) {
01651             totals[k] += (GLbyte)(*(temp_index)) * percent;
01652         }
01653         left = temp;
01654         for(l = lowx_int+1; l < highx_int; l++) {
01655             temp += group_size;
01656             for (k = 0, temp_index = temp; k < components;
01657              k++, temp_index += element_size) {
01658             totals[k] += (GLbyte)(*(temp_index)) * y_percent;
01659             }
01660         }
01661         temp += group_size;
01662         right = temp;
01663         percent = y_percent * highx_float;
01664         for (k = 0, temp_index = temp; k < components;
01665              k++, temp_index += element_size) {
01666             totals[k] += (GLbyte)(*(temp_index)) * percent;
01667         }
01668 
01669         /* calculate the value for pixels in the last row */
01670         y_percent = highy_float;
01671         percent = y_percent * (1-lowx_float);
01672         temp = (const char *)datain + xindex + highy_int * ysize;
01673         for (k = 0, temp_index = temp; k < components;
01674              k++, temp_index += element_size) {
01675             totals[k] += (GLbyte)(*(temp_index)) * percent;
01676         }
01677         for(l = lowx_int+1; l < highx_int; l++) {
01678             temp += group_size;
01679             for (k = 0, temp_index = temp; k < components;
01680              k++, temp_index += element_size) {
01681             totals[k] += (GLbyte)(*(temp_index)) * y_percent;
01682             }
01683         }
01684         temp += group_size;
01685         percent = y_percent * highx_float;
01686         for (k = 0, temp_index = temp; k < components;
01687              k++, temp_index += element_size) {
01688             totals[k] += (GLbyte)(*(temp_index)) * percent;
01689         }
01690 
01691 
01692         /* calculate the value for pixels in the 1st and last column */
01693         for(m = lowy_int+1; m < highy_int; m++) {
01694             left += ysize;
01695             right += ysize;
01696             for (k = 0; k < components;
01697              k++, left += element_size, right += element_size) {
01698             totals[k] += (GLbyte)(*(left))*(1-lowx_float)
01699                 +(GLbyte)(*(right))*highx_float;
01700             }
01701         }
01702         } else if (highy_int > lowy_int) {
01703         x_percent = highx_float - lowx_float;
01704         percent = (1-lowy_float)*x_percent;
01705         temp = (const char *)datain + xindex + lowy_int*ysize;
01706         for (k = 0, temp_index = temp; k < components;
01707              k++, temp_index += element_size) {
01708             totals[k] += (GLbyte)(*(temp_index)) * percent;
01709         }
01710         for(m = lowy_int+1; m < highy_int; m++) {
01711             temp += ysize;
01712             for (k = 0, temp_index = temp; k < components;
01713              k++, temp_index += element_size) {
01714             totals[k] += (GLbyte)(*(temp_index)) * x_percent;
01715             }
01716         }
01717         percent = x_percent * highy_float;
01718         temp += ysize;
01719         for (k = 0, temp_index = temp; k < components;
01720              k++, temp_index += element_size) {
01721             totals[k] += (GLbyte)(*(temp_index)) * percent;
01722         }
01723         } else if (highx_int > lowx_int) {
01724         y_percent = highy_float - lowy_float;
01725         percent = (1-lowx_float)*y_percent;
01726         temp = (const char *)datain + xindex + lowy_int*ysize;
01727         for (k = 0, temp_index = temp; k < components;
01728              k++, temp_index += element_size) {
01729             totals[k] += (GLbyte)(*(temp_index)) * percent;
01730         }
01731         for (l = lowx_int+1; l < highx_int; l++) {
01732             temp += group_size;
01733             for (k = 0, temp_index = temp; k < components;
01734              k++, temp_index += element_size) {
01735             totals[k] += (GLbyte)(*(temp_index)) * y_percent;
01736             }
01737         }
01738         temp += group_size;
01739         percent = y_percent * highx_float;
01740         for (k = 0, temp_index = temp; k < components;
01741              k++, temp_index += element_size) {
01742             totals[k] += (GLbyte)(*(temp_index)) * percent;
01743         }
01744         } else {
01745         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
01746         temp = (const char *)datain + xindex + lowy_int * ysize;
01747         for (k = 0, temp_index = temp; k < components;
01748              k++, temp_index += element_size) {
01749             totals[k] += (GLbyte)(*(temp_index)) * percent;
01750         }
01751         }
01752 
01753 
01754 
01755         /* this is for the pixels in the body */
01756         temp0 = (const char *)datain + xindex + group_size +
01757         (lowy_int+1)*ysize;
01758         for (m = lowy_int+1; m < highy_int; m++) {
01759         temp = temp0;
01760         for(l = lowx_int+1; l < highx_int; l++) {
01761             for (k = 0, temp_index = temp; k < components;
01762              k++, temp_index += element_size) {
01763             totals[k] += (GLbyte)(*(temp_index));
01764             }
01765             temp += group_size;
01766         }
01767         temp0 += ysize;
01768         }
01769 
01770         outindex = (j + (i * widthout)) * components;
01771         for (k = 0; k < components; k++) {
01772         dataout[outindex + k] = totals[k]/area;
01773         /*printf("totals[%d] = %f\n", k, totals[k]);*/
01774         }
01775         lowx_int = highx_int;
01776         lowx_float = highx_float;
01777         highx_int += convx_int;
01778         highx_float += convx_float;
01779         if(highx_float > 1) {
01780         highx_float -= 1.0;
01781         highx_int++;
01782         }
01783     }
01784     lowy_int = highy_int;
01785     lowy_float = highy_float;
01786     highy_int += convy_int;
01787     highy_float += convy_float;
01788     if(highy_float > 1) {
01789         highy_float -= 1.0;
01790         highy_int++;
01791     }
01792     }
01793 }
01794 
01795 static void scale_internal_ushort(GLint components, GLint widthin,
01796                GLint heightin, const GLushort *datain,
01797                GLint widthout, GLint heightout,
01798                GLushort *dataout, GLint element_size,
01799                GLint ysize, GLint group_size,
01800                GLint myswap_bytes)
01801 {
01802     float convx;
01803     float convy;
01804     float percent;
01805     /* Max components in a format is 4, so... */
01806     float totals[4];
01807     float area;
01808     int i,j,k,xindex;
01809 
01810     const char *temp, *temp0;
01811     const char *temp_index;
01812     int outindex;
01813 
01814     int lowx_int, highx_int, lowy_int, highy_int;
01815     float x_percent, y_percent;
01816     float lowx_float, highx_float, lowy_float, highy_float;
01817     float convy_float, convx_float;
01818     int convy_int, convx_int;
01819     int l, m;
01820     const char *left, *right;
01821 
01822     if (widthin == widthout*2 && heightin == heightout*2) {
01823     halveImage_ushort(components, widthin, heightin,
01824     (const GLushort *)datain, (GLushort *)dataout,
01825     element_size, ysize, group_size, myswap_bytes);
01826     return;
01827     }
01828     convy = (float) heightin/heightout;
01829     convx = (float) widthin/widthout;
01830     convy_int = floor(convy);
01831     convy_float = convy - convy_int;
01832     convx_int = floor(convx);
01833     convx_float = convx - convx_int;
01834 
01835     area = convx * convy;
01836 
01837     lowy_int = 0;
01838     lowy_float = 0;
01839     highy_int = convy_int;
01840     highy_float = convy_float;
01841 
01842     for (i = 0; i < heightout; i++) {
01843     lowx_int = 0;
01844     lowx_float = 0;
01845     highx_int = convx_int;
01846     highx_float = convx_float;
01847 
01848     for (j = 0; j < widthout; j++) {
01849         /*
01850         ** Ok, now apply box filter to box that goes from (lowx, lowy)
01851         ** to (highx, highy) on input data into this pixel on output
01852         ** data.
01853         */
01854         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
01855 
01856         /* calculate the value for pixels in the 1st row */
01857         xindex = lowx_int*group_size;
01858         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
01859 
01860         y_percent = 1-lowy_float;
01861         temp = (const char *)datain + xindex + lowy_int * ysize;
01862         percent = y_percent * (1-lowx_float);
01863         for (k = 0, temp_index = temp; k < components;
01864              k++, temp_index += element_size) {
01865             if (myswap_bytes) {
01866             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01867             } else {
01868             totals[k] += *(const GLushort*)temp_index * percent;
01869             }
01870         }
01871         left = temp;
01872         for(l = lowx_int+1; l < highx_int; l++) {
01873             temp += group_size;
01874             for (k = 0, temp_index = temp; k < components;
01875              k++, temp_index += element_size) {
01876             if (myswap_bytes) {
01877                 totals[k] +=
01878                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
01879             } else {
01880                 totals[k] += *(const GLushort*)temp_index * y_percent;
01881             }
01882             }
01883         }
01884         temp += group_size;
01885         right = temp;
01886         percent = y_percent * highx_float;
01887         for (k = 0, temp_index = temp; k < components;
01888              k++, temp_index += element_size) {
01889             if (myswap_bytes) {
01890             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01891             } else {
01892             totals[k] += *(const GLushort*)temp_index * percent;
01893             }
01894         }
01895 
01896         /* calculate the value for pixels in the last row */
01897         y_percent = highy_float;
01898         percent = y_percent * (1-lowx_float);
01899         temp = (const char *)datain + xindex + highy_int * ysize;
01900         for (k = 0, temp_index = temp; k < components;
01901              k++, temp_index += element_size) {
01902             if (myswap_bytes) {
01903             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01904             } else {
01905             totals[k] += *(const GLushort*)temp_index * percent;
01906             }
01907         }
01908         for(l = lowx_int+1; l < highx_int; l++) {
01909             temp += group_size;
01910             for (k = 0, temp_index = temp; k < components;
01911              k++, temp_index += element_size) {
01912             if (myswap_bytes) {
01913                 totals[k] +=
01914                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
01915             } else {
01916                 totals[k] += *(const GLushort*)temp_index * y_percent;
01917             }
01918             }
01919         }
01920         temp += group_size;
01921         percent = y_percent * highx_float;
01922         for (k = 0, temp_index = temp; k < components;
01923              k++, temp_index += element_size) {
01924             if (myswap_bytes) {
01925             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01926             } else {
01927             totals[k] += *(const GLushort*)temp_index * percent;
01928             }
01929         }
01930 
01931         /* calculate the value for pixels in the 1st and last column */
01932         for(m = lowy_int+1; m < highy_int; m++) {
01933             left += ysize;
01934             right += ysize;
01935             for (k = 0; k < components;
01936              k++, left += element_size, right += element_size) {
01937             if (myswap_bytes) {
01938                 totals[k] +=
01939                 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
01940                 __GLU_SWAP_2_BYTES(right) * highx_float;
01941             } else {
01942                 totals[k] += *(const GLushort*)left * (1-lowx_float)
01943                        + *(const GLushort*)right * highx_float;
01944             }
01945             }
01946         }
01947         } else if (highy_int > lowy_int) {
01948         x_percent = highx_float - lowx_float;
01949         percent = (1-lowy_float)*x_percent;
01950         temp = (const char *)datain + xindex + lowy_int*ysize;
01951         for (k = 0, temp_index = temp; k < components;
01952              k++, temp_index += element_size) {
01953             if (myswap_bytes) {
01954             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01955             } else {
01956             totals[k] += *(const GLushort*)temp_index * percent;
01957             }
01958         }
01959         for(m = lowy_int+1; m < highy_int; m++) {
01960             temp += ysize;
01961             for (k = 0, temp_index = temp; k < components;
01962              k++, temp_index += element_size) {
01963             if (myswap_bytes) {
01964                 totals[k] +=
01965                 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
01966             } else {
01967                 totals[k] += *(const GLushort*)temp_index * x_percent;
01968             }
01969             }
01970         }
01971         percent = x_percent * highy_float;
01972         temp += ysize;
01973         for (k = 0, temp_index = temp; k < components;
01974              k++, temp_index += element_size) {
01975             if (myswap_bytes) {
01976             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01977             } else {
01978             totals[k] += *(const GLushort*)temp_index * percent;
01979             }
01980         }
01981         } else if (highx_int > lowx_int) {
01982         y_percent = highy_float - lowy_float;
01983         percent = (1-lowx_float)*y_percent;
01984         temp = (const char *)datain + xindex + lowy_int*ysize;
01985         for (k = 0, temp_index = temp; k < components;
01986              k++, temp_index += element_size) {
01987             if (myswap_bytes) {
01988             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
01989             } else {
01990             totals[k] += *(const GLushort*)temp_index * percent;
01991             }
01992         }
01993         for (l = lowx_int+1; l < highx_int; l++) {
01994             temp += group_size;
01995             for (k = 0, temp_index = temp; k < components;
01996              k++, temp_index += element_size) {
01997             if (myswap_bytes) {
01998                 totals[k] +=
01999                 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
02000             } else {
02001                 totals[k] += *(const GLushort*)temp_index * y_percent;
02002             }
02003             }
02004         }
02005         temp += group_size;
02006         percent = y_percent * highx_float;
02007         for (k = 0, temp_index = temp; k < components;
02008              k++, temp_index += element_size) {
02009             if (myswap_bytes) {
02010             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
02011             } else {
02012             totals[k] += *(const GLushort*)temp_index * percent;
02013             }
02014         }
02015         } else {
02016         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
02017         temp = (const char *)datain + xindex + lowy_int * ysize;
02018         for (k = 0, temp_index = temp; k < components;
02019              k++, temp_index += element_size) {
02020             if (myswap_bytes) {
02021             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
02022             } else {
02023             totals[k] += *(const GLushort*)temp_index * percent;
02024             }
02025         }
02026         }
02027 
02028         /* this is for the pixels in the body */
02029         temp0 = (const char *)datain + xindex + group_size +
02030          (lowy_int+1)*ysize;
02031         for (m = lowy_int+1; m < highy_int; m++) {
02032         temp = temp0;
02033         for(l = lowx_int+1; l < highx_int; l++) {
02034             for (k = 0, temp_index = temp; k < components;
02035              k++, temp_index += element_size) {
02036             if (myswap_bytes) {
02037                 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
02038             } else {
02039                 totals[k] += *(const GLushort*)temp_index;
02040             }
02041             }
02042             temp += group_size;
02043         }
02044         temp0 += ysize;
02045         }
02046 
02047         outindex = (j + (i * widthout)) * components;
02048         for (k = 0; k < components; k++) {
02049         dataout[outindex + k] = totals[k]/area;
02050         /*printf("totals[%d] = %f\n", k, totals[k]);*/
02051         }
02052         lowx_int = highx_int;
02053         lowx_float = highx_float;
02054         highx_int += convx_int;
02055         highx_float += convx_float;
02056         if(highx_float > 1) {
02057         highx_float -= 1.0;
02058         highx_int++;
02059         }
02060     }
02061     lowy_int = highy_int;
02062     lowy_float = highy_float;
02063     highy_int += convy_int;
02064     highy_float += convy_float;
02065     if(highy_float > 1) {
02066         highy_float -= 1.0;
02067         highy_int++;
02068     }
02069     }
02070 }
02071 
02072 static void scale_internal_short(GLint components, GLint widthin,
02073                GLint heightin, const GLshort *datain,
02074                GLint widthout, GLint heightout,
02075                GLshort *dataout, GLint element_size,
02076                GLint ysize, GLint group_size,
02077                GLint myswap_bytes)
02078 {
02079     float convx;
02080     float convy;
02081     float percent;
02082     /* Max components in a format is 4, so... */
02083     float totals[4];
02084     float area;
02085     int i,j,k,xindex;
02086 
02087     const char *temp, *temp0;
02088     const char *temp_index;
02089     int outindex;
02090 
02091     int lowx_int, highx_int, lowy_int, highy_int;
02092     float x_percent, y_percent;
02093     float lowx_float, highx_float, lowy_float, highy_float;
02094     float convy_float, convx_float;
02095     int convy_int, convx_int;
02096     int l, m;
02097     const char *left, *right;
02098 
02099     GLushort swapbuf;   /* unsigned buffer */
02100 
02101     if (widthin == widthout*2 && heightin == heightout*2) {
02102     halveImage_short(components, widthin, heightin,
02103     (const GLshort *)datain, (GLshort *)dataout,
02104     element_size, ysize, group_size, myswap_bytes);
02105     return;
02106     }
02107     convy = (float) heightin/heightout;
02108     convx = (float) widthin/widthout;
02109     convy_int = floor(convy);
02110     convy_float = convy - convy_int;
02111     convx_int = floor(convx);
02112     convx_float = convx - convx_int;
02113 
02114     area = convx * convy;
02115 
02116     lowy_int = 0;
02117     lowy_float = 0;
02118     highy_int = convy_int;
02119     highy_float = convy_float;
02120 
02121     for (i = 0; i < heightout; i++) {
02122     lowx_int = 0;
02123     lowx_float = 0;
02124     highx_int = convx_int;
02125     highx_float = convx_float;
02126 
02127     for (j = 0; j < widthout; j++) {
02128         /*
02129         ** Ok, now apply box filter to box that goes from (lowx, lowy)
02130         ** to (highx, highy) on input data into this pixel on output
02131         ** data.
02132         */
02133         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
02134 
02135         /* calculate the value for pixels in the 1st row */
02136         xindex = lowx_int*group_size;
02137         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
02138 
02139         y_percent = 1-lowy_float;
02140         temp = (const char *)datain + xindex + lowy_int * ysize;
02141         percent = y_percent * (1-lowx_float);
02142         for (k = 0, temp_index = temp; k < components;
02143              k++, temp_index += element_size) {
02144             if (myswap_bytes) {
02145             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02146             totals[k] += *(const GLshort*)&swapbuf * percent;
02147             } else {
02148             totals[k] += *(const GLshort*)temp_index * percent;
02149             }
02150         }
02151         left = temp;
02152         for(l = lowx_int+1; l < highx_int; l++) {
02153             temp += group_size;
02154             for (k = 0, temp_index = temp; k < components;
02155              k++, temp_index += element_size) {
02156             if (myswap_bytes) {
02157                 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02158                 totals[k] += *(const GLshort*)&swapbuf * y_percent;
02159             } else {
02160                 totals[k] += *(const GLshort*)temp_index * y_percent;
02161             }
02162             }
02163         }
02164         temp += group_size;
02165         right = temp;
02166         percent = y_percent * highx_float;
02167         for (k = 0, temp_index = temp; k < components;
02168              k++, temp_index += element_size) {
02169             if (myswap_bytes) {
02170             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02171             totals[k] += *(const GLshort*)&swapbuf * percent;
02172             } else {
02173             totals[k] += *(const GLshort*)temp_index * percent;
02174             }
02175         }
02176 
02177         /* calculate the value for pixels in the last row */
02178         y_percent = highy_float;
02179         percent = y_percent * (1-lowx_float);
02180         temp = (const char *)datain + xindex + highy_int * ysize;
02181         for (k = 0, temp_index = temp; k < components;
02182              k++, temp_index += element_size) {
02183             if (myswap_bytes) {
02184             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02185             totals[k] += *(const GLshort*)&swapbuf * percent;
02186             } else {
02187             totals[k] += *(const GLshort*)temp_index * percent;
02188             }
02189         }
02190         for(l = lowx_int+1; l < highx_int; l++) {
02191             temp += group_size;
02192             for (k = 0, temp_index = temp; k < components;
02193              k++, temp_index += element_size) {
02194             if (myswap_bytes) {
02195                 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02196                 totals[k] += *(const GLshort*)&swapbuf * y_percent;
02197             } else {
02198                 totals[k] += *(const GLshort*)temp_index * y_percent;
02199             }
02200             }
02201         }
02202         temp += group_size;
02203         percent = y_percent * highx_float;
02204         for (k = 0, temp_index = temp; k < components;
02205              k++, temp_index += element_size) {
02206             if (myswap_bytes) {
02207             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02208             totals[k] += *(const GLshort*)&swapbuf * percent;
02209             } else {
02210             totals[k] += *(const GLshort*)temp_index * percent;
02211             }
02212         }
02213 
02214         /* calculate the value for pixels in the 1st and last column */
02215         for(m = lowy_int+1; m < highy_int; m++) {
02216             left += ysize;
02217             right += ysize;
02218             for (k = 0; k < components;
02219              k++, left += element_size, right += element_size) {
02220             if (myswap_bytes) {
02221                 swapbuf = __GLU_SWAP_2_BYTES(left);
02222                 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
02223                 swapbuf = __GLU_SWAP_2_BYTES(right);
02224                 totals[k] += *(const GLshort*)&swapbuf * highx_float;
02225             } else {
02226                 totals[k] += *(const GLshort*)left * (1-lowx_float)
02227                        + *(const GLshort*)right * highx_float;
02228             }
02229             }
02230         }
02231         } else if (highy_int > lowy_int) {
02232         x_percent = highx_float - lowx_float;
02233         percent = (1-lowy_float)*x_percent;
02234         temp = (const char *)datain + xindex + lowy_int*ysize;
02235         for (k = 0, temp_index = temp; k < components;
02236              k++, temp_index += element_size) {
02237             if (myswap_bytes) {
02238             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02239             totals[k] += *(const GLshort*)&swapbuf * percent;
02240             } else {
02241             totals[k] += *(const GLshort*)temp_index * percent;
02242             }
02243         }
02244         for(m = lowy_int+1; m < highy_int; m++) {
02245             temp += ysize;
02246             for (k = 0, temp_index = temp; k < components;
02247              k++, temp_index += element_size) {
02248             if (myswap_bytes) {
02249                 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02250                 totals[k] += *(const GLshort*)&swapbuf * x_percent;
02251             } else {
02252                 totals[k] += *(const GLshort*)temp_index * x_percent;
02253             }
02254             }
02255         }
02256         percent = x_percent * highy_float;
02257         temp += ysize;
02258         for (k = 0, temp_index = temp; k < components;
02259              k++, temp_index += element_size) {
02260             if (myswap_bytes) {
02261             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02262             totals[k] += *(const GLshort*)&swapbuf * percent;
02263             } else {
02264             totals[k] += *(const GLshort*)temp_index * percent;
02265             }
02266         }
02267         } else if (highx_int > lowx_int) {
02268         y_percent = highy_float - lowy_float;
02269         percent = (1-lowx_float)*y_percent;
02270 
02271          temp = (const char *)datain + xindex + lowy_int*ysize;
02272         for (k = 0, temp_index = temp; k < components;
02273              k++, temp_index += element_size) {
02274             if (myswap_bytes) {
02275             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02276             totals[k] += *(const GLshort*)&swapbuf * percent;
02277             } else {
02278             totals[k] += *(const GLshort*)temp_index * percent;
02279             }
02280         }
02281         for (l = lowx_int+1; l < highx_int; l++) {
02282             temp += group_size;
02283             for (k = 0, temp_index = temp; k < components;
02284              k++, temp_index += element_size) {
02285             if (myswap_bytes) {
02286                 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02287                 totals[k] += *(const GLshort*)&swapbuf * y_percent;
02288             } else {
02289                 totals[k] += *(const GLshort*)temp_index * y_percent;
02290             }
02291             }
02292         }
02293         temp += group_size;
02294         percent = y_percent * highx_float;
02295         for (k = 0, temp_index = temp; k < components;
02296              k++, temp_index += element_size) {
02297             if (myswap_bytes) {
02298             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02299             totals[k] += *(const GLshort*)&swapbuf * percent;
02300             } else {
02301             totals[k] += *(const GLshort*)temp_index * percent;
02302             }
02303         }
02304         } else {
02305         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
02306         temp = (const char *)datain + xindex + lowy_int * ysize;
02307         for (k = 0, temp_index = temp; k < components;
02308              k++, temp_index += element_size) {
02309             if (myswap_bytes) {
02310             swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02311             totals[k] += *(const GLshort*)&swapbuf * percent;
02312             } else {
02313             totals[k] += *(const GLshort*)temp_index * percent;
02314             }
02315         }
02316         }
02317 
02318         /* this is for the pixels in the body */
02319         temp0 = (const char *)datain + xindex + group_size +
02320          (lowy_int+1)*ysize;
02321         for (m = lowy_int+1; m < highy_int; m++) {
02322         temp = temp0;
02323         for(l = lowx_int+1; l < highx_int; l++) {
02324             for (k = 0, temp_index = temp; k < components;
02325              k++, temp_index += element_size) {
02326             if (myswap_bytes) {
02327                 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
02328                 totals[k] += *(const GLshort*)&swapbuf;
02329             } else {
02330                 totals[k] += *(const GLshort*)temp_index;
02331             }
02332             }
02333             temp += group_size;
02334         }
02335         temp0 += ysize;
02336         }
02337 
02338         outindex = (j + (i * widthout)) * components;
02339         for (k = 0; k < components; k++) {
02340         dataout[outindex + k] = totals[k]/area;
02341         /*printf("totals[%d] = %f\n", k, totals[k]);*/
02342         }
02343         lowx_int = highx_int;
02344         lowx_float = highx_float;
02345         highx_int += convx_int;
02346         highx_float += convx_float;
02347         if(highx_float > 1) {
02348         highx_float -= 1.0;
02349         highx_int++;
02350         }
02351     }
02352     lowy_int = highy_int;
02353     lowy_float = highy_float;
02354     highy_int += convy_int;
02355     highy_float += convy_float;
02356     if(highy_float > 1) {
02357         highy_float -= 1.0;
02358         highy_int++;
02359     }
02360     }
02361 }
02362 
02363 static void scale_internal_uint(GLint components, GLint widthin,
02364                GLint heightin, const GLuint *datain,
02365                GLint widthout, GLint heightout,
02366                GLuint *dataout, GLint element_size,
02367                GLint ysize, GLint group_size,
02368                GLint myswap_bytes)
02369 {
02370     float convx;
02371     float convy;
02372     float percent;
02373     /* Max components in a format is 4, so... */
02374     float totals[4];
02375     float area;
02376     int i,j,k,xindex;
02377 
02378     const char *temp, *temp0;
02379     const char *temp_index;
02380     int outindex;
02381 
02382     int lowx_int, highx_int, lowy_int, highy_int;
02383     float x_percent, y_percent;
02384     float lowx_float, highx_float, lowy_float, highy_float;
02385     float convy_float, convx_float;
02386     int convy_int, convx_int;
02387     int l, m;
02388     const char *left, *right;
02389 
02390     if (widthin == widthout*2 && heightin == heightout*2) {
02391     halveImage_uint(components, widthin, heightin,
02392     (const GLuint *)datain, (GLuint *)dataout,
02393     element_size, ysize, group_size, myswap_bytes);
02394     return;
02395     }
02396     convy = (float) heightin/heightout;
02397     convx = (float) widthin/widthout;
02398     convy_int = floor(convy);
02399     convy_float = convy - convy_int;
02400     convx_int = floor(convx);
02401     convx_float = convx - convx_int;
02402 
02403     area = convx * convy;
02404 
02405     lowy_int = 0;
02406     lowy_float = 0;
02407     highy_int = convy_int;
02408     highy_float = convy_float;
02409 
02410     for (i = 0; i < heightout; i++) {
02411     lowx_int = 0;
02412     lowx_float = 0;
02413     highx_int = convx_int;
02414     highx_float = convx_float;
02415 
02416     for (j = 0; j < widthout; j++) {
02417         /*
02418         ** Ok, now apply box filter to box that goes from (lowx, lowy)
02419         ** to (highx, highy) on input data into this pixel on output
02420         ** data.
02421         */
02422         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
02423 
02424         /* calculate the value for pixels in the 1st row */
02425         xindex = lowx_int*group_size;
02426         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
02427 
02428         y_percent = 1-lowy_float;
02429         temp = (const char *)datain + xindex + lowy_int * ysize;
02430         percent = y_percent * (1-lowx_float);
02431         for (k = 0, temp_index = temp; k < components;
02432              k++, temp_index += element_size) {
02433             if (myswap_bytes) {
02434             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02435             } else {
02436             totals[k] += *(const GLuint*)temp_index * percent;
02437             }
02438         }
02439         left = temp;
02440         for(l = lowx_int+1; l < highx_int; l++) {
02441             temp += group_size;
02442             for (k = 0, temp_index = temp; k < components;
02443              k++, temp_index += element_size) {
02444             if (myswap_bytes) {
02445                 totals[k] +=
02446                  __GLU_SWAP_4_BYTES(temp_index) * y_percent;
02447             } else {
02448                 totals[k] += *(const GLuint*)temp_index * y_percent;
02449             }
02450             }
02451         }
02452         temp += group_size;
02453         right = temp;
02454         percent = y_percent * highx_float;
02455         for (k = 0, temp_index = temp; k < components;
02456              k++, temp_index += element_size) {
02457             if (myswap_bytes) {
02458             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02459             } else {
02460             totals[k] += *(const GLuint*)temp_index * percent;
02461             }
02462         }
02463 
02464         /* calculate the value for pixels in the last row */
02465         y_percent = highy_float;
02466         percent = y_percent * (1-lowx_float);
02467         temp = (const char *)datain + xindex + highy_int * ysize;
02468         for (k = 0, temp_index = temp; k < components;
02469              k++, temp_index += element_size) {
02470             if (myswap_bytes) {
02471             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02472             } else {
02473             totals[k] += *(const GLuint*)temp_index * percent;
02474             }
02475         }
02476         for(l = lowx_int+1; l < highx_int; l++) {
02477             temp += group_size;
02478             for (k = 0, temp_index = temp; k < components;
02479              k++, temp_index += element_size) {
02480             if (myswap_bytes) {
02481                 totals[k] +=
02482                  __GLU_SWAP_4_BYTES(temp_index) * y_percent;
02483             } else {
02484                 totals[k] += *(const GLuint*)temp_index * y_percent;
02485             }
02486             }
02487         }
02488         temp += group_size;
02489         percent = y_percent * highx_float;
02490         for (k = 0, temp_index = temp; k < components;
02491              k++, temp_index += element_size) {
02492             if (myswap_bytes) {
02493             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02494             } else {
02495             totals[k] += *(const GLuint*)temp_index * percent;
02496             }
02497         }
02498 
02499         /* calculate the value for pixels in the 1st and last column */
02500         for(m = lowy_int+1; m < highy_int; m++) {
02501             left += ysize;
02502             right += ysize;
02503             for (k = 0; k < components;
02504              k++, left += element_size, right += element_size) {
02505             if (myswap_bytes) {
02506                 totals[k] +=
02507                 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
02508                   + __GLU_SWAP_4_BYTES(right) * highx_float;
02509             } else {
02510                 totals[k] += *(const GLuint*)left * (1-lowx_float)
02511                        + *(const GLuint*)right * highx_float;
02512             }
02513             }
02514         }
02515         } else if (highy_int > lowy_int) {
02516         x_percent = highx_float - lowx_float;
02517         percent = (1-lowy_float)*x_percent;
02518         temp = (const char *)datain + xindex + lowy_int*ysize;
02519         for (k = 0, temp_index = temp; k < components;
02520              k++, temp_index += element_size) {
02521             if (myswap_bytes) {
02522             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02523             } else {
02524             totals[k] += *(const GLuint*)temp_index * percent;
02525             }
02526         }
02527         for(m = lowy_int+1; m < highy_int; m++) {
02528             temp += ysize;
02529             for (k = 0, temp_index = temp; k < components;
02530              k++, temp_index += element_size) {
02531             if (myswap_bytes) {
02532                 totals[k] +=
02533                  __GLU_SWAP_4_BYTES(temp_index) * x_percent;
02534             } else {
02535                 totals[k] += *(const GLuint*)temp_index * x_percent;
02536             }
02537             }
02538         }
02539         percent = x_percent * highy_float;
02540         temp += ysize;
02541         for (k = 0, temp_index = temp; k < components;
02542              k++, temp_index += element_size) {
02543             if (myswap_bytes) {
02544             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02545             } else {
02546             totals[k] += *(const GLuint*)temp_index * percent;
02547             }
02548         }
02549         } else if (highx_int > lowx_int) {
02550         y_percent = highy_float - lowy_float;
02551         percent = (1-lowx_float)*y_percent;
02552 
02553          temp = (const char *)datain + xindex + lowy_int*ysize;
02554         for (k = 0, temp_index = temp; k < components;
02555              k++, temp_index += element_size) {
02556             if (myswap_bytes) {
02557             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02558             } else {
02559             totals[k] += *(const GLuint*)temp_index * percent;
02560             }
02561         }
02562         for (l = lowx_int+1; l < highx_int; l++) {
02563             temp += group_size;
02564             for (k = 0, temp_index = temp; k < components;
02565              k++, temp_index += element_size) {
02566             if (myswap_bytes) {
02567                 totals[k] +=
02568                  __GLU_SWAP_4_BYTES(temp_index) * y_percent;
02569             } else {
02570                 totals[k] += *(const GLuint*)temp_index * y_percent;
02571             }
02572             }
02573         }
02574         temp += group_size;
02575         percent = y_percent * highx_float;
02576         for (k = 0, temp_index = temp; k < components;
02577              k++, temp_index += element_size) {
02578             if (myswap_bytes) {
02579             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02580             } else {
02581             totals[k] += *(const GLuint*)temp_index * percent;
02582             }
02583         }
02584         } else {
02585         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
02586         temp = (const char *)datain + xindex + lowy_int * ysize;
02587         for (k = 0, temp_index = temp; k < components;
02588              k++, temp_index += element_size) {
02589             if (myswap_bytes) {
02590             totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
02591             } else {
02592             totals[k] += *(const GLuint*)temp_index * percent;
02593             }
02594         }
02595         }
02596 
02597         /* this is for the pixels in the body */
02598         temp0 = (const char *)datain + xindex + group_size +
02599          (lowy_int+1)*ysize;
02600         for (m = lowy_int+1; m < highy_int; m++) {
02601         temp = temp0;
02602         for(l = lowx_int+1; l < highx_int; l++) {
02603             for (k = 0, temp_index = temp; k < components;
02604              k++, temp_index += element_size) {
02605             if (myswap_bytes) {
02606                 totals[k] += __GLU_SWAP_4_BYTES(temp_index);
02607             } else {
02608                 totals[k] += *(const GLuint*)temp_index;
02609             }
02610             }
02611             temp += group_size;
02612         }
02613         temp0 += ysize;
02614         }
02615 
02616         outindex = (j + (i * widthout)) * components;
02617         for (k = 0; k < components; k++) {
02618         /* clamp at UINT_MAX */
02619         float value= totals[k]/area;
02620         if (value >= (float) UINT_MAX) {    /* need '=' */
02621           dataout[outindex + k] = UINT_MAX;
02622         }
02623         else dataout[outindex + k] = value;
02624         }
02625         lowx_int = highx_int;
02626         lowx_float = highx_float;
02627         highx_int += convx_int;
02628         highx_float += convx_float;
02629         if(highx_float > 1) {
02630         highx_float -= 1.0;
02631         highx_int++;
02632         }
02633     }
02634     lowy_int = highy_int;
02635     lowy_float = highy_float;
02636     highy_int += convy_int;
02637     highy_float += convy_float;
02638     if(highy_float > 1) {
02639         highy_float -= 1.0;
02640         highy_int++;
02641     }
02642     }
02643 }
02644 
02645 
02646 
02647 static void scale_internal_int(GLint components, GLint widthin,
02648                GLint heightin, const GLint *datain,
02649                GLint widthout, GLint heightout,
02650                GLint *dataout, GLint element_size,
02651                GLint ysize, GLint group_size,
02652                GLint myswap_bytes)
02653 {
02654     float convx;
02655     float convy;
02656     float percent;
02657     /* Max components in a format is 4, so... */
02658     float totals[4];
02659     float area;
02660     int i,j,k,xindex;
02661 
02662     const char *temp, *temp0;
02663     const char *temp_index;
02664     int outindex;
02665 
02666     int lowx_int, highx_int, lowy_int, highy_int;
02667     float x_percent, y_percent;
02668     float lowx_float, highx_float, lowy_float, highy_float;
02669     float convy_float, convx_float;
02670     int convy_int, convx_int;
02671     int l, m;
02672     const char *left, *right;
02673 
02674     GLuint swapbuf; /* unsigned buffer */
02675 
02676     if (widthin == widthout*2 && heightin == heightout*2) {
02677     halveImage_int(components, widthin, heightin,
02678     (const GLint *)datain, (GLint *)dataout,
02679     element_size, ysize, group_size, myswap_bytes);
02680     return;
02681     }
02682     convy = (float) heightin/heightout;
02683     convx = (float) widthin/widthout;
02684     convy_int = floor(convy);
02685     convy_float = convy - convy_int;
02686     convx_int = floor(convx);
02687     convx_float = convx - convx_int;
02688 
02689     area = convx * convy;
02690 
02691     lowy_int = 0;
02692     lowy_float = 0;
02693     highy_int = convy_int;
02694     highy_float = convy_float;
02695 
02696     for (i = 0; i < heightout; i++) {
02697     lowx_int = 0;
02698     lowx_float = 0;
02699     highx_int = convx_int;
02700     highx_float = convx_float;
02701 
02702     for (j = 0; j < widthout; j++) {
02703         /*
02704         ** Ok, now apply box filter to box that goes from (lowx, lowy)
02705         ** to (highx, highy) on input data into this pixel on output
02706         ** data.
02707         */
02708         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
02709 
02710         /* calculate the value for pixels in the 1st row */
02711         xindex = lowx_int*group_size;
02712         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
02713 
02714         y_percent = 1-lowy_float;
02715         temp = (const char *)datain + xindex + lowy_int * ysize;
02716         percent = y_percent * (1-lowx_float);
02717         for (k = 0, temp_index = temp; k < components;
02718              k++, temp_index += element_size) {
02719             if (myswap_bytes) {
02720             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02721             totals[k] += *(const GLint*)&swapbuf * percent;
02722             } else {
02723             totals[k] += *(const GLint*)temp_index * percent;
02724             }
02725         }
02726         left = temp;
02727         for(l = lowx_int+1; l < highx_int; l++) {
02728             temp += group_size;
02729             for (k = 0, temp_index = temp; k < components;
02730              k++, temp_index += element_size) {
02731             if (myswap_bytes) {
02732                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02733                 totals[k] += *(const GLint*)&swapbuf * y_percent;
02734             } else {
02735                 totals[k] += *(const GLint*)temp_index * y_percent;
02736             }
02737             }
02738         }
02739         temp += group_size;
02740         right = temp;
02741         percent = y_percent * highx_float;
02742         for (k = 0, temp_index = temp; k < components;
02743              k++, temp_index += element_size) {
02744             if (myswap_bytes) {
02745             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02746             totals[k] += *(const GLint*)&swapbuf * percent;
02747             } else {
02748             totals[k] += *(const GLint*)temp_index * percent;
02749             }
02750         }
02751 
02752         /* calculate the value for pixels in the last row */
02753         y_percent = highy_float;
02754         percent = y_percent * (1-lowx_float);
02755         temp = (const char *)datain + xindex + highy_int * ysize;
02756         for (k = 0, temp_index = temp; k < components;
02757              k++, temp_index += element_size) {
02758             if (myswap_bytes) {
02759             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02760             totals[k] += *(const GLint*)&swapbuf  * percent;
02761             } else {
02762             totals[k] += *(const GLint*)temp_index * percent;
02763             }
02764         }
02765         for(l = lowx_int+1; l < highx_int; l++) {
02766             temp += group_size;
02767             for (k = 0, temp_index = temp; k < components;
02768              k++, temp_index += element_size) {
02769             if (myswap_bytes) {
02770                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02771                 totals[k] += *(const GLint*)&swapbuf * y_percent;
02772             } else {
02773                 totals[k] += *(const GLint*)temp_index * y_percent;
02774             }
02775             }
02776         }
02777         temp += group_size;
02778         percent = y_percent * highx_float;
02779         for (k = 0, temp_index = temp; k < components;
02780              k++, temp_index += element_size) {
02781             if (myswap_bytes) {
02782             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02783             totals[k] += *(const GLint*)&swapbuf * percent;
02784             } else {
02785             totals[k] += *(const GLint*)temp_index * percent;
02786             }
02787         }
02788 
02789         /* calculate the value for pixels in the 1st and last column */
02790         for(m = lowy_int+1; m < highy_int; m++) {
02791             left += ysize;
02792             right += ysize;
02793             for (k = 0; k < components;
02794              k++, left += element_size, right += element_size) {
02795             if (myswap_bytes) {
02796                 swapbuf = __GLU_SWAP_4_BYTES(left);
02797                 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
02798                 swapbuf = __GLU_SWAP_4_BYTES(right);
02799                 totals[k] += *(const GLint*)&swapbuf * highx_float;
02800             } else {
02801                 totals[k] += *(const GLint*)left * (1-lowx_float)
02802                        + *(const GLint*)right * highx_float;
02803             }
02804             }
02805         }
02806         } else if (highy_int > lowy_int) {
02807         x_percent = highx_float - lowx_float;
02808         percent = (1-lowy_float)*x_percent;
02809         temp = (const char *)datain + xindex + lowy_int*ysize;
02810         for (k = 0, temp_index = temp; k < components;
02811              k++, temp_index += element_size) {
02812             if (myswap_bytes) {
02813             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02814             totals[k] += *(const GLint*)&swapbuf * percent;
02815             } else {
02816             totals[k] += *(const GLint*)temp_index * percent;
02817             }
02818         }
02819         for(m = lowy_int+1; m < highy_int; m++) {
02820             temp += ysize;
02821             for (k = 0, temp_index = temp; k < components;
02822              k++, temp_index += element_size) {
02823             if (myswap_bytes) {
02824                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02825                 totals[k] += *(const GLint*)&swapbuf * x_percent;
02826             } else {
02827                 totals[k] += *(const GLint*)temp_index * x_percent;
02828             }
02829             }
02830         }
02831         percent = x_percent * highy_float;
02832         temp += ysize;
02833         for (k = 0, temp_index = temp; k < components;
02834              k++, temp_index += element_size) {
02835             if (myswap_bytes) {
02836             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02837             totals[k] += *(const GLint*)&swapbuf * percent;
02838             } else {
02839             totals[k] += *(const GLint*)temp_index * percent;
02840             }
02841         }
02842         } else if (highx_int > lowx_int) {
02843         y_percent = highy_float - lowy_float;
02844         percent = (1-lowx_float)*y_percent;
02845 
02846          temp = (const char *)datain + xindex + lowy_int*ysize;
02847         for (k = 0, temp_index = temp; k < components;
02848              k++, temp_index += element_size) {
02849             if (myswap_bytes) {
02850             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02851             totals[k] += *(const GLint*)&swapbuf * percent;
02852             } else {
02853             totals[k] += *(const GLint*)temp_index * percent;
02854             }
02855         }
02856         for (l = lowx_int+1; l < highx_int; l++) {
02857             temp += group_size;
02858             for (k = 0, temp_index = temp; k < components;
02859              k++, temp_index += element_size) {
02860             if (myswap_bytes) {
02861                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02862                 totals[k] += *(const GLint*)&swapbuf * y_percent;
02863             } else {
02864                 totals[k] += *(const GLint*)temp_index * y_percent;
02865             }
02866             }
02867         }
02868         temp += group_size;
02869         percent = y_percent * highx_float;
02870         for (k = 0, temp_index = temp; k < components;
02871              k++, temp_index += element_size) {
02872             if (myswap_bytes) {
02873             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02874             totals[k] += *(const GLint*)&swapbuf * percent;
02875             } else {
02876             totals[k] += *(const GLint*)temp_index * percent;
02877             }
02878         }
02879         } else {
02880         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
02881         temp = (const char *)datain + xindex + lowy_int * ysize;
02882         for (k = 0, temp_index = temp; k < components;
02883              k++, temp_index += element_size) {
02884             if (myswap_bytes) {
02885             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02886             totals[k] += *(const GLint*)&swapbuf * percent;
02887             } else {
02888             totals[k] += *(const GLint*)temp_index * percent;
02889             }
02890         }
02891         }
02892 
02893         /* this is for the pixels in the body */
02894         temp0 = (const char *)datain + xindex + group_size +
02895          (lowy_int+1)*ysize;
02896         for (m = lowy_int+1; m < highy_int; m++) {
02897         temp = temp0;
02898         for(l = lowx_int+1; l < highx_int; l++) {
02899             for (k = 0, temp_index = temp; k < components;
02900              k++, temp_index += element_size) {
02901             if (myswap_bytes) {
02902                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
02903                 totals[k] += *(const GLint*)&swapbuf;
02904             } else {
02905                 totals[k] += *(const GLint*)temp_index;
02906             }
02907             }
02908             temp += group_size;
02909         }
02910         temp0 += ysize;
02911         }
02912 
02913         outindex = (j + (i * widthout)) * components;
02914         for (k = 0; k < components; k++) {
02915         dataout[outindex + k] = totals[k]/area;
02916         /*printf("totals[%d] = %f\n", k, totals[k]);*/
02917         }
02918         lowx_int = highx_int;
02919         lowx_float = highx_float;
02920         highx_int += convx_int;
02921         highx_float += convx_float;
02922         if(highx_float > 1) {
02923         highx_float -= 1.0;
02924         highx_int++;
02925         }
02926     }
02927     lowy_int = highy_int;
02928     lowy_float = highy_float;
02929     highy_int += convy_int;
02930     highy_float += convy_float;
02931     if(highy_float > 1) {
02932         highy_float -= 1.0;
02933         highy_int++;
02934     }
02935     }
02936 }
02937 
02938 
02939 
02940 static void scale_internal_float(GLint components, GLint widthin,
02941                GLint heightin, const GLfloat *datain,
02942                GLint widthout, GLint heightout,
02943                GLfloat *dataout, GLint element_size,
02944                GLint ysize, GLint group_size,
02945                GLint myswap_bytes)
02946 {
02947     float convx;
02948     float convy;
02949     float percent;
02950     /* Max components in a format is 4, so... */
02951     float totals[4];
02952     float area;
02953     int i,j,k,xindex;
02954 
02955     const char *temp, *temp0;
02956     const char *temp_index;
02957     int outindex;
02958 
02959     int lowx_int, highx_int, lowy_int, highy_int;
02960     float x_percent, y_percent;
02961     float lowx_float, highx_float, lowy_float, highy_float;
02962     float convy_float, convx_float;
02963     int convy_int, convx_int;
02964     int l, m;
02965     const char *left, *right;
02966 
02967     GLuint swapbuf; /* unsigned buffer */
02968 
02969     if (widthin == widthout*2 && heightin == heightout*2) {
02970     halveImage_float(components, widthin, heightin,
02971     (const GLfloat *)datain, (GLfloat *)dataout,
02972     element_size, ysize, group_size, myswap_bytes);
02973     return;
02974     }
02975     convy = (float) heightin/heightout;
02976     convx = (float) widthin/widthout;
02977     convy_int = floor(convy);
02978     convy_float = convy - convy_int;
02979     convx_int = floor(convx);
02980     convx_float = convx - convx_int;
02981 
02982     area = convx * convy;
02983 
02984     lowy_int = 0;
02985     lowy_float = 0;
02986     highy_int = convy_int;
02987     highy_float = convy_float;
02988 
02989     for (i = 0; i < heightout; i++) {
02990     lowx_int = 0;
02991     lowx_float = 0;
02992     highx_int = convx_int;
02993     highx_float = convx_float;
02994 
02995     for (j = 0; j < widthout; j++) {
02996         /*
02997         ** Ok, now apply box filter to box that goes from (lowx, lowy)
02998         ** to (highx, highy) on input data into this pixel on output
02999         ** data.
03000         */
03001         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
03002 
03003         /* calculate the value for pixels in the 1st row */
03004         xindex = lowx_int*group_size;
03005         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
03006 
03007         y_percent = 1-lowy_float;
03008         temp = (const char *)datain + xindex + lowy_int * ysize;
03009         percent = y_percent * (1-lowx_float);
03010         for (k = 0, temp_index = temp; k < components;
03011              k++, temp_index += element_size) {
03012             if (myswap_bytes) {
03013             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03014             totals[k] += *(const GLfloat*)&swapbuf * percent;
03015             } else {
03016             totals[k] += *(const GLfloat*)temp_index * percent;
03017             }
03018         }
03019         left = temp;
03020         for(l = lowx_int+1; l < highx_int; l++) {
03021             temp += group_size;
03022             for (k = 0, temp_index = temp; k < components;
03023              k++, temp_index += element_size) {
03024             if (myswap_bytes) {
03025                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03026                 totals[k] += *(const GLfloat*)&swapbuf * y_percent;
03027             } else {
03028                 totals[k] += *(const GLfloat*)temp_index * y_percent;
03029             }
03030             }
03031         }
03032         temp += group_size;
03033         right = temp;
03034         percent = y_percent * highx_float;
03035         for (k = 0, temp_index = temp; k < components;
03036              k++, temp_index += element_size) {
03037             if (myswap_bytes) {
03038             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03039             totals[k] += *(const GLfloat*)&swapbuf * percent;
03040             } else {
03041             totals[k] += *(const GLfloat*)temp_index * percent;
03042             }
03043         }
03044 
03045         /* calculate the value for pixels in the last row */
03046         y_percent = highy_float;
03047         percent = y_percent * (1-lowx_float);
03048         temp = (const char *)datain + xindex + highy_int * ysize;
03049         for (k = 0, temp_index = temp; k < components;
03050              k++, temp_index += element_size) {
03051             if (myswap_bytes) {
03052             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03053             totals[k] += *(const GLfloat*)&swapbuf * percent;
03054             } else {
03055             totals[k] += *(const GLfloat*)temp_index * percent;
03056             }
03057         }
03058         for(l = lowx_int+1; l < highx_int; l++) {
03059             temp += group_size;
03060             for (k = 0, temp_index = temp; k < components;
03061              k++, temp_index += element_size) {
03062             if (myswap_bytes) {
03063                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03064                 totals[k] += *(const GLfloat*)&swapbuf * y_percent;
03065             } else {
03066                 totals[k] += *(const GLfloat*)temp_index * y_percent;
03067             }
03068             }
03069         }
03070         temp += group_size;
03071         percent = y_percent * highx_float;
03072         for (k = 0, temp_index = temp; k < components;
03073              k++, temp_index += element_size) {
03074             if (myswap_bytes) {
03075             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03076             totals[k] += *(const GLfloat*)&swapbuf * percent;
03077             } else {
03078             totals[k] += *(const GLfloat*)temp_index * percent;
03079             }
03080         }
03081 
03082         /* calculate the value for pixels in the 1st and last column */
03083         for(m = lowy_int+1; m < highy_int; m++) {
03084             left += ysize;
03085             right += ysize;
03086             for (k = 0; k < components;
03087              k++, left += element_size, right += element_size) {
03088             if (myswap_bytes) {
03089                 swapbuf = __GLU_SWAP_4_BYTES(left);
03090                 totals[k] += *(const GLfloat*)&swapbuf * (1-lowx_float);
03091                 swapbuf = __GLU_SWAP_4_BYTES(right);
03092                 totals[k] += *(const GLfloat*)&swapbuf * highx_float;
03093             } else {
03094                 totals[k] += *(const GLfloat*)left * (1-lowx_float)
03095                        + *(const GLfloat*)right * highx_float;
03096             }
03097             }
03098         }
03099         } else if (highy_int > lowy_int) {
03100         x_percent = highx_float - lowx_float;
03101         percent = (1-lowy_float)*x_percent;
03102         temp = (const char *)datain + xindex + lowy_int*ysize;
03103         for (k = 0, temp_index = temp; k < components;
03104              k++, temp_index += element_size) {
03105             if (myswap_bytes) {
03106             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03107             totals[k] += *(const GLfloat*)&swapbuf * percent;
03108             } else {
03109             totals[k] += *(const GLfloat*)temp_index * percent;
03110             }
03111         }
03112         for(m = lowy_int+1; m < highy_int; m++) {
03113             temp += ysize;
03114             for (k = 0, temp_index = temp; k < components;
03115              k++, temp_index += element_size) {
03116             if (myswap_bytes) {
03117                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03118                 totals[k] += *(const GLfloat*)&swapbuf * x_percent;
03119             } else {
03120                 totals[k] += *(const GLfloat*)temp_index * x_percent;
03121             }
03122             }
03123         }
03124         percent = x_percent * highy_float;
03125         temp += ysize;
03126         for (k = 0, temp_index = temp; k < components;
03127              k++, temp_index += element_size) {
03128             if (myswap_bytes) {
03129             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03130             totals[k] += *(const GLfloat*)&swapbuf * percent;
03131             } else {
03132             totals[k] += *(const GLfloat*)temp_index * percent;
03133             }
03134         }
03135         } else if (highx_int > lowx_int) {
03136         y_percent = highy_float - lowy_float;
03137         percent = (1-lowx_float)*y_percent;
03138 
03139          temp = (const char *)datain + xindex + lowy_int*ysize;
03140         for (k = 0, temp_index = temp; k < components;
03141              k++, temp_index += element_size) {
03142             if (myswap_bytes) {
03143             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03144             totals[k] += *(const GLfloat*)&swapbuf * percent;
03145             } else {
03146             totals[k] += *(const GLfloat*)temp_index * percent;
03147             }
03148         }
03149         for (l = lowx_int+1; l < highx_int; l++) {
03150             temp += group_size;
03151             for (k = 0, temp_index = temp; k < components;
03152              k++, temp_index += element_size) {
03153             if (myswap_bytes) {
03154                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03155                 totals[k] += *(const GLfloat*)&swapbuf * y_percent;
03156             } else {
03157                 totals[k] += *(const GLfloat*)temp_index * y_percent;
03158             }
03159             }
03160         }
03161         temp += group_size;
03162         percent = y_percent * highx_float;
03163         for (k = 0, temp_index = temp; k < components;
03164              k++, temp_index += element_size) {
03165             if (myswap_bytes) {
03166             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03167             totals[k] += *(const GLfloat*)&swapbuf * percent;
03168             } else {
03169             totals[k] += *(const GLfloat*)temp_index * percent;
03170             }
03171         }
03172         } else {
03173         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
03174         temp = (const char *)datain + xindex + lowy_int * ysize;
03175         for (k = 0, temp_index = temp; k < components;
03176              k++, temp_index += element_size) {
03177             if (myswap_bytes) {
03178             swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03179             totals[k] += *(const GLfloat*)&swapbuf * percent;
03180             } else {
03181             totals[k] += *(const GLfloat*)temp_index * percent;
03182             }
03183         }
03184         }
03185 
03186         /* this is for the pixels in the body */
03187         temp0 = (const char *)datain + xindex + group_size +
03188          (lowy_int+1)*ysize;
03189         for (m = lowy_int+1; m < highy_int; m++) {
03190         temp = temp0;
03191         for(l = lowx_int+1; l < highx_int; l++) {
03192             for (k = 0, temp_index = temp; k < components;
03193              k++, temp_index += element_size) {
03194             if (myswap_bytes) {
03195                 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
03196                 totals[k] += *(const GLfloat*)&swapbuf;
03197             } else {
03198                 totals[k] += *(const GLfloat*)temp_index;
03199             }
03200             }
03201             temp += group_size;
03202         }
03203         temp0 += ysize;
03204         }
03205 
03206         outindex = (j + (i * widthout)) * components;
03207         for (k = 0; k < components; k++) {
03208         dataout[outindex + k] = totals[k]/area;
03209         /*printf("totals[%d] = %f\n", k, totals[k]);*/
03210         }
03211         lowx_int = highx_int;
03212         lowx_float = highx_float;
03213         highx_int += convx_int;
03214         highx_float += convx_float;
03215         if(highx_float > 1) {
03216         highx_float -= 1.0;
03217         highx_int++;
03218         }
03219     }
03220     lowy_int = highy_int;
03221     lowy_float = highy_float;
03222     highy_int += convy_int;
03223     highy_float += convy_float;
03224     if(highy_float > 1) {
03225         highy_float -= 1.0;
03226         highy_int++;
03227     }
03228     }
03229 }
03230 
03231 static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
03232 {
03233     if (!legalFormat(format) || !legalType(type)) {
03234     return GLU_INVALID_ENUM;
03235     }
03236     if (format == GL_STENCIL_INDEX) {
03237     return GLU_INVALID_ENUM;
03238     }
03239 
03240     if (!isLegalFormatForPackedPixelType(format, type)) {
03241     return GLU_INVALID_OPERATION;
03242     }
03243 
03244     return 0;
03245 } /* checkMipmapArgs() */
03246 
03247 static GLboolean legalFormat(GLenum format)
03248 {
03249     switch(format) {
03250       case GL_COLOR_INDEX:
03251       case GL_STENCIL_INDEX:
03252       case GL_DEPTH_COMPONENT:
03253       case GL_RED:
03254       case GL_GREEN:
03255       case GL_BLUE:
03256       case GL_ALPHA:
03257       case GL_RGB:
03258       case GL_RGBA:
03259       case GL_LUMINANCE:
03260       case GL_LUMINANCE_ALPHA:
03261       case GL_BGR:
03262       case GL_BGRA:
03263     return GL_TRUE;
03264       default:
03265     return GL_FALSE;
03266     }
03267 }
03268 
03269 
03270 static GLboolean legalType(GLenum type)
03271 {
03272     switch(type) {
03273       case GL_BITMAP:
03274       case GL_BYTE:
03275       case GL_UNSIGNED_BYTE:
03276       case GL_SHORT:
03277       case GL_UNSIGNED_SHORT:
03278       case GL_INT:
03279       case GL_UNSIGNED_INT:
03280       case GL_FLOAT:
03281       case GL_UNSIGNED_BYTE_3_3_2:
03282       case GL_UNSIGNED_BYTE_2_3_3_REV:
03283       case GL_UNSIGNED_SHORT_5_6_5:
03284       case GL_UNSIGNED_SHORT_5_6_5_REV:
03285       case GL_UNSIGNED_SHORT_4_4_4_4:
03286       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
03287       case GL_UNSIGNED_SHORT_5_5_5_1:
03288       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
03289       case GL_UNSIGNED_INT_8_8_8_8:
03290       case GL_UNSIGNED_INT_8_8_8_8_REV:
03291       case GL_UNSIGNED_INT_10_10_10_2:
03292       case GL_UNSIGNED_INT_2_10_10_10_REV:
03293      return GL_TRUE;
03294       default:
03295     return GL_FALSE;
03296     }
03297 }
03298 
03299 /* */
03300 static GLboolean isTypePackedPixel(GLenum type)
03301 {
03302    assert(legalType(type));
03303 
03304    if (type == GL_UNSIGNED_BYTE_3_3_2 ||
03305        type == GL_UNSIGNED_BYTE_2_3_3_REV ||
03306        type == GL_UNSIGNED_SHORT_5_6_5 ||
03307        type == GL_UNSIGNED_SHORT_5_6_5_REV ||
03308        type == GL_UNSIGNED_SHORT_4_4_4_4 ||
03309        type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
03310        type == GL_UNSIGNED_SHORT_5_5_5_1 ||
03311        type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
03312        type == GL_UNSIGNED_INT_8_8_8_8 ||
03313        type == GL_UNSIGNED_INT_8_8_8_8_REV ||
03314        type == GL_UNSIGNED_INT_10_10_10_2 ||
03315        type == GL_UNSIGNED_INT_2_10_10_10_REV) {
03316       return 1;
03317    }
03318    else return 0;
03319 } /* isTypePackedPixel() */
03320 
03321 /* Determines if the packed pixel type is compatible with the format */
03322 static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
03323 {
03324    /* if not a packed pixel type then return true */
03325    if (!isTypePackedPixel(type)) {
03326       return GL_TRUE;
03327    }
03328 
03329    /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
03330    if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
03331     type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
03332        && format != GL_RGB)
03333       return GL_FALSE;
03334 
03335    /* 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 &
03336     * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
03337     */
03338    if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
03339     type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
03340     type == GL_UNSIGNED_SHORT_5_5_5_1 ||
03341     type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
03342     type == GL_UNSIGNED_INT_8_8_8_8 ||
03343     type == GL_UNSIGNED_INT_8_8_8_8_REV ||
03344     type == GL_UNSIGNED_INT_10_10_10_2 ||
03345     type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
03346        (format != GL_RGBA &&
03347     format != GL_BGRA)) {
03348       return GL_FALSE;
03349    }
03350 
03351    return GL_TRUE;
03352 } /* isLegalFormatForPackedPixelType() */
03353 
03354 static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel,
03355                    GLint totalLevels)
03356 {
03357    if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel ||
03358        totalLevels < maxLevel)
03359       return GL_FALSE;
03360    else return GL_TRUE;
03361 } /* isLegalLevels() */
03362 
03363 /* Given user requested texture size, determine if it fits. If it
03364  * doesn't then halve both sides and make the determination again
03365  * until it does fit (for IR only).
03366  * Note that proxy textures are not implemented in RE* even though
03367  * they advertise the texture extension.
03368  * Note that proxy textures are implemented but not according to spec in
03369  * IMPACT*.
03370  */
03371 static void closestFit(GLenum target, GLint width, GLint height,
03372                GLint internalFormat, GLenum format, GLenum type,
03373                GLint *newWidth, GLint *newHeight)
03374 {
03375    /* Use proxy textures if OpenGL version is >= 1.1 */
03376    if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
03377     ) {
03378       GLint widthPowerOf2= nearestPower(width);
03379       GLint heightPowerOf2= nearestPower(height);
03380       GLint proxyWidth;
03381 
03382       do {
03383      /* compute level 1 width & height, clamping each at 1 */
03384      GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
03385                  widthPowerOf2 >> 1 :
03386                  widthPowerOf2;
03387      GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
03388                   heightPowerOf2 >> 1 :
03389                   heightPowerOf2;
03390      GLenum proxyTarget;
03391      assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
03392 
03393      /* does width x height at level 1 & all their mipmaps fit? */
03394      if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
03395         proxyTarget = GL_PROXY_TEXTURE_2D;
03396         glTexImage2D(proxyTarget, 1, /* must be non-zero */
03397              internalFormat,
03398              widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
03399      } else
03400 #if defined(GL_ARB_texture_cube_map)
03401      if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
03402          (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
03403          (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
03404          (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
03405          (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
03406          (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
03407          proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
03408          glTexImage2D(proxyTarget, 1, /* must be non-zero */
03409               internalFormat,
03410               widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
03411      } else
03412 #endif /* GL_ARB_texture_cube_map */
03413      {
03414         assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
03415         proxyTarget = GL_PROXY_TEXTURE_1D;
03416         glTexImage1D(proxyTarget, 1, /* must be non-zero */
03417              internalFormat,widthAtLevelOne,0,format,type,NULL);
03418      }
03419      glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
03420      /* does it fit??? */
03421      if (proxyWidth == 0) { /* nope, so try again with these sizes */
03422         if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
03423            /* An 1x1 texture couldn't fit for some reason, so
03424         * break out.  This should never happen. But things
03425         * happen.  The disadvantage with this if-statement is
03426         * that we will never be aware of when this happens
03427         * since it will silently branch out.
03428         */
03429            goto noProxyTextures;
03430         }
03431         widthPowerOf2= widthAtLevelOne;
03432         heightPowerOf2= heightAtLevelOne;
03433      }
03434      /* else it does fit */
03435       } while (proxyWidth == 0);
03436       /* loop must terminate! */
03437 
03438       /* return the width & height at level 0 that fits */
03439       *newWidth= widthPowerOf2;
03440       *newHeight= heightPowerOf2;
03441 /*printf("Proxy Textures\n");*/
03442    } /* if gluCheckExtension() */
03443    else {           /* no texture extension, so do this instead */
03444       GLint maxsize;
03445 
03446 noProxyTextures:
03447 
03448       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
03449       /* clamp user's texture sizes to maximum sizes, if necessary */
03450       *newWidth = nearestPower(width);
03451       if (*newWidth > maxsize) *newWidth = maxsize;
03452       *newHeight = nearestPower(height);
03453       if (*newHeight > maxsize) *newHeight = maxsize;
03454 /*printf("NO proxy textures\n");*/
03455    }
03456 } /* closestFit() */
03457 
03458 GLint GLAPIENTRY
03459 gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
03460             GLenum typein, const void *datain,
03461             GLsizei widthout, GLsizei heightout, GLenum typeout,
03462             void *dataout)
03463 {
03464     int components;
03465     GLushort *beforeImage;
03466     GLushort *afterImage;
03467     PixelStorageModes psm;
03468 
03469     if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
03470     return 0;
03471     }
03472     if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
03473     return GLU_INVALID_VALUE;
03474     }
03475     if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
03476     return GLU_INVALID_ENUM;
03477     }
03478     if (!isLegalFormatForPackedPixelType(format, typein)) {
03479        return GLU_INVALID_OPERATION;
03480     }
03481     if (!isLegalFormatForPackedPixelType(format, typeout)) {
03482        return GLU_INVALID_OPERATION;
03483     }
03484     beforeImage =
03485     malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
03486     if (beforeImage == NULL) {
03487         return GLU_OUT_OF_MEMORY;
03488     }
03489 
03490     afterImage =
03491     malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
03492     if (afterImage == NULL) {
03493         free(beforeImage);
03494         return GLU_OUT_OF_MEMORY;
03495     }
03496 
03497     retrieveStoreModes(&psm);
03498     fill_image(&psm,widthin, heightin, format, typein, is_index(format),
03499         datain, beforeImage);
03500     components = elements_per_group(format, 0);
03501     scale_internal(components, widthin, heightin, beforeImage,
03502         widthout, heightout, afterImage);
03503     empty_image(&psm,widthout, heightout, format, typeout,
03504         is_index(format), afterImage, dataout);
03505     free((GLbyte *) beforeImage);
03506     free((GLbyte *) afterImage);
03507 
03508     return 0;
03509 }
03510 
03511 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
03512                    GLsizei width,
03513                    GLsizei widthPowerOf2,
03514                    GLenum format, GLenum type,
03515                    GLint userLevel, GLint baseLevel,GLint maxLevel,
03516                    const void *data)
03517 {
03518     GLint newwidth;
03519     GLint level, levels;
03520     GLushort *newImage;
03521     GLint newImage_width;
03522     GLushort *otherImage;
03523     GLushort *imageTemp;
03524     GLint memreq;
03525     GLint cmpts;
03526     PixelStorageModes psm;
03527 
03528     assert(checkMipmapArgs(internalFormat,format,type) == 0);
03529     assert(width >= 1);
03530 
03531     otherImage = NULL;
03532 
03533     newwidth= widthPowerOf2;
03534     levels = computeLog(newwidth);
03535 
03536     levels+= userLevel;
03537 
03538     retrieveStoreModes(&psm);
03539     newImage = (GLushort *)
03540     malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
03541     newImage_width = width;
03542     if (newImage == NULL) {
03543     return GLU_OUT_OF_MEMORY;
03544     }
03545     fill_image(&psm,width, 1, format, type, is_index(format),
03546         data, newImage);
03547     cmpts = elements_per_group(format,type);
03548     glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
03549     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
03550     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
03551     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
03552     /*
03553     ** If swap_bytes was set, swapping occurred in fill_image.
03554     */
03555     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
03556 
03557     for (level = userLevel; level <= levels; level++) {
03558     if (newImage_width == newwidth) {
03559         /* Use newImage for this level */
03560         if (baseLevel <= level && level <= maxLevel) {
03561         glTexImage1D(target, level, internalFormat, newImage_width,
03562             0, format, GL_UNSIGNED_SHORT, (void *) newImage);
03563         }
03564     } else {
03565         if (otherImage == NULL) {
03566         memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
03567         otherImage = (GLushort *) malloc(memreq);
03568         if (otherImage == NULL) {
03569             glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
03570             glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
03571             glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
03572             glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
03573             glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
03574             return GLU_OUT_OF_MEMORY;
03575         }
03576         }
03577         scale_internal(cmpts, newImage_width, 1, newImage,
03578             newwidth, 1, otherImage);
03579         /* Swap newImage and otherImage */
03580         imageTemp = otherImage;
03581         otherImage = newImage;
03582         newImage = imageTemp;
03583 
03584         newImage_width = newwidth;
03585         if (baseLevel <= level && level <= maxLevel) {
03586         glTexImage1D(target, level, internalFormat, newImage_width,
03587             0, format, GL_UNSIGNED_SHORT, (void *) newImage);
03588         }
03589     }
03590     if (newwidth > 1) newwidth /= 2;
03591     }
03592     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
03593     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
03594     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
03595     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
03596     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
03597 
03598     free((GLbyte *) newImage);
03599     if (otherImage) {
03600     free((GLbyte *) otherImage);
03601     }
03602     return 0;
03603 }
03604 
03605 GLint GLAPIENTRY
03606 gluBuild1DMipmapLevels(GLenum target, GLint internalFormat,
03607                  GLsizei width,
03608                  GLenum format, GLenum type,
03609                  GLint userLevel, GLint baseLevel, GLint maxLevel,
03610                  const void *data)
03611 {
03612    int levels;
03613 
03614    int rc= checkMipmapArgs(internalFormat,format,type);
03615    if (rc != 0) return rc;
03616 
03617    if (width < 1) {
03618        return GLU_INVALID_VALUE;
03619    }
03620 
03621    levels = computeLog(width);
03622 
03623    levels+= userLevel;
03624    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
03625       return GLU_INVALID_VALUE;
03626 
03627    return gluBuild1DMipmapLevelsCore(target, internalFormat,
03628                      width,
03629                      width,format, type,
03630                      userLevel, baseLevel, maxLevel,
03631                      data);
03632 } /* gluBuild1DMipmapLevels() */
03633 
03634 GLint GLAPIENTRY
03635 gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
03636             GLenum format, GLenum type,
03637             const void *data)
03638 {
03639    GLint widthPowerOf2;
03640    int levels;
03641    GLint dummy;
03642 
03643    int rc= checkMipmapArgs(internalFormat,format,type);
03644    if (rc != 0) return rc;
03645 
03646    if (width < 1) {
03647        return GLU_INVALID_VALUE;
03648    }
03649 
03650    closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
03651    levels = computeLog(widthPowerOf2);
03652 
03653    return gluBuild1DMipmapLevelsCore(target,internalFormat,
03654                      width,
03655                      widthPowerOf2,
03656                      format,type,0,0,levels,data);
03657 }
03658 
03659 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
03660              GLint width, GLint height, GLenum format,
03661              GLenum type, const void *data)
03662 {
03663     GLint newwidth, newheight;
03664     GLint level, levels;
03665     GLushort *newImage;
03666     GLint newImage_width;
03667     GLint newImage_height;
03668     GLushort *otherImage;
03669     GLushort *imageTemp;
03670     GLint memreq;
03671     GLint cmpts;
03672     PixelStorageModes psm;
03673 
03674     retrieveStoreModes(&psm);
03675 
03676 #if 0
03677     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
03678     newwidth = nearestPower(width);
03679     if (newwidth > maxsize) newwidth = maxsize;
03680     newheight = nearestPower(height);
03681     if (newheight > maxsize) newheight = maxsize;
03682 #else
03683     closestFit(target,width,height,internalFormat,format,type,
03684            &newwidth,&newheight);
03685 #endif
03686     levels = computeLog(newwidth);
03687     level = computeLog(newheight);
03688     if (level > levels) levels=level;
03689 
03690     otherImage = NULL;
03691     newImage = (GLushort *)
03692     malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
03693     newImage_width = width;
03694     newImage_height = height;
03695     if (newImage == NULL) {
03696     return GLU_OUT_OF_MEMORY;
03697     }
03698 
03699     fill_image(&psm,width, height, format, type, is_index(format),
03700       data, newImage);
03701 
03702     cmpts = elements_per_group(format,type);
03703     glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
03704     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
03705     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
03706     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
03707     /*
03708     ** If swap_bytes was set, swapping occurred in fill_image.
03709     */
03710     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
03711 
03712     for (level = 0; level <= levels; level++) {
03713     if (newImage_width == newwidth && newImage_height == newheight) {        /* Use newImage for this level */
03714         glTexImage2D(target, level, internalFormat, newImage_width,
03715             newImage_height, 0, format, GL_UNSIGNED_SHORT,
03716             (void *) newImage);
03717     } else {
03718         if (otherImage == NULL) {
03719         memreq =
03720             image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
03721         otherImage = (GLushort *) malloc(memreq);
03722         if (otherImage == NULL) {
03723             glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
03724             glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
03725             glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
03726             glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
03727             glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
03728             return GLU_OUT_OF_MEMORY;
03729         }
03730         }
03731         scale_internal(cmpts, newImage_width, newImage_height, newImage,
03732             newwidth, newheight, otherImage);
03733         /* Swap newImage and otherImage */
03734         imageTemp = otherImage;
03735         otherImage = newImage;
03736         newImage = imageTemp;
03737 
03738         newImage_width = newwidth;
03739         newImage_height = newheight;
03740         glTexImage2D(target, level, internalFormat, newImage_width,
03741             newImage_height, 0, format, GL_UNSIGNED_SHORT,
03742             (void *) newImage);
03743     }
03744     if (newwidth > 1) newwidth /= 2;
03745     if (newheight > 1) newheight /= 2;
03746     }
03747     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
03748     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
03749     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
03750     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
03751     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
03752 
03753     free((GLbyte *) newImage);
03754     if (otherImage) {
03755     free((GLbyte *) otherImage);
03756     }
03757     return 0;
03758 }
03759 
03760 /* To make swapping images less error prone */
03761 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
03762 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
03763 
03764 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
03765                       GLsizei width, GLsizei height,
03766                       GLsizei widthPowerOf2,
03767                       GLsizei heightPowerOf2,
03768                       GLenum format, GLenum type,
03769                       GLint userLevel,
03770                       GLint baseLevel,GLint maxLevel,
03771                       const void *data)
03772 {
03773     GLint newwidth, newheight;
03774     GLint level, levels;
03775     const void *usersImage; /* passed from user. Don't touch! */
03776     void *srcImage, *dstImage; /* scratch area to build mipmapped images */
03777     __GLU_INIT_SWAP_IMAGE;
03778     GLint memreq;
03779     GLint cmpts;
03780 
03781     GLint myswap_bytes, groups_per_line, element_size, group_size;
03782     GLint rowsize, padding;
03783     PixelStorageModes psm;
03784 
03785     assert(checkMipmapArgs(internalFormat,format,type) == 0);
03786     assert(width >= 1 && height >= 1);
03787 
03788     if(type == GL_BITMAP) {
03789     return bitmapBuild2DMipmaps(target, internalFormat, width, height,
03790         format, type, data);
03791     }
03792 
03793     srcImage = dstImage = NULL;
03794 
03795     newwidth= widthPowerOf2;
03796     newheight= heightPowerOf2;
03797     levels = computeLog(newwidth);
03798     level = computeLog(newheight);
03799     if (level > levels) levels=level;
03800 
03801     levels+= userLevel;
03802 
03803     retrieveStoreModes(&psm);
03804     myswap_bytes = psm.unpack_swap_bytes;
03805     cmpts = elements_per_group(format,type);
03806     if (psm.unpack_row_length > 0) {
03807     groups_per_line = psm.unpack_row_length;
03808     } else {
03809     groups_per_line = width;
03810     }
03811 
03812     element_size = bytes_per_element(type);
03813     group_size = element_size * cmpts;
03814     if (element_size == 1) myswap_bytes = 0;
03815 
03816     rowsize = groups_per_line * group_size;
03817     padding = (rowsize % psm.unpack_alignment);
03818     if (padding) {
03819     rowsize += psm.unpack_alignment - padding;
03820     }
03821     usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
03822     psm.unpack_skip_pixels * group_size;
03823 
03824     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
03825     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
03826     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
03827 
03828     level = userLevel;
03829 
03830     /* already power-of-two square */
03831     if (width == newwidth && height == newheight) {
03832     /* Use usersImage for level userLevel */
03833     if (baseLevel <= level && level <= maxLevel) {
03834     glTexImage2D(target, level, internalFormat, width,
03835         height, 0, format, type,
03836         usersImage);
03837     }
03838     if(levels == 0) { /* we're done. clean up and return */
03839       glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
03840       glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
03841       glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
03842       glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
03843       glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
03844       return 0;
03845     }
03846     {
03847        int nextWidth= newwidth/2;
03848        int nextHeight= newheight/2;
03849 
03850        /* clamp to 1 */
03851        if (nextWidth < 1) nextWidth= 1;
03852        if (nextHeight < 1) nextHeight= 1;
03853     memreq = image_size(nextWidth, nextHeight, format, type);
03854     }
03855 
03856     switch(type) {
03857     case GL_UNSIGNED_BYTE:
03858       dstImage = (GLubyte *)malloc(memreq);
03859       break;
03860     case GL_BYTE:
03861       dstImage = (GLbyte *)malloc(memreq);
03862       break;
03863     case GL_UNSIGNED_SHORT:
03864       dstImage = (GLushort *)malloc(memreq);
03865       break;
03866     case GL_SHORT:
03867       dstImage = (GLshort *)malloc(memreq);
03868       break;
03869     case GL_UNSIGNED_INT:
03870       dstImage = (GLuint *)malloc(memreq);
03871       break;
03872     case GL_INT:
03873       dstImage = (GLint *)malloc(memreq);
03874       break;
03875     case GL_FLOAT:
03876       dstImage = (GLfloat *)malloc(memreq);
03877       break;
03878     case GL_UNSIGNED_BYTE_3_3_2:
03879     case GL_UNSIGNED_BYTE_2_3_3_REV:
03880       dstImage = (GLubyte *)malloc(memreq);
03881       break;
03882     case GL_UNSIGNED_SHORT_5_6_5:
03883     case GL_UNSIGNED_SHORT_5_6_5_REV:
03884     case GL_UNSIGNED_SHORT_4_4_4_4:
03885     case GL_UNSIGNED_SHORT_4_4_4_4_REV:
03886     case GL_UNSIGNED_SHORT_5_5_5_1:
03887     case GL_UNSIGNED_SHORT_1_5_5_5_REV:
03888       dstImage = (GLushort *)malloc(memreq);
03889       break;
03890     case GL_UNSIGNED_INT_8_8_8_8:
03891     case GL_UNSIGNED_INT_8_8_8_8_REV:
03892     case GL_UNSIGNED_INT_10_10_10_2:
03893     case GL_UNSIGNED_INT_2_10_10_10_REV:
03894       dstImage = (GLuint *)malloc(memreq);
03895       break;
03896     default:
03897       return GLU_INVALID_ENUM;
03898     }
03899     if (dstImage == NULL) {
03900       glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
03901       glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
03902       glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
03903       glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
03904       glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
03905       return GLU_OUT_OF_MEMORY;
03906     }
03907     else
03908       switch(type) {
03909       case GL_UNSIGNED_BYTE:
03910         halveImage_ubyte(cmpts, width, height,
03911                  (const GLubyte *)usersImage, (GLubyte *)dstImage,
03912                  element_size, rowsize, group_size);
03913         break;
03914       case GL_BYTE:
03915         halveImage_byte(cmpts, width, height,
03916                 (const GLbyte *)usersImage, (GLbyte *)dstImage,
03917                 element_size, rowsize, group_size);
03918         break;
03919       case GL_UNSIGNED_SHORT:
03920         halveImage_ushort(cmpts, width, height,
03921                   (const GLushort *)usersImage, (GLushort *)dstImage,
03922                   element_size, rowsize, group_size, myswap_bytes);
03923         break;
03924       case GL_SHORT:
03925         halveImage_short(cmpts, width, height,
03926                  (const GLshort *)usersImage, (GLshort *)dstImage,
03927                  element_size, rowsize, group_size, myswap_bytes);
03928         break;
03929       case GL_UNSIGNED_INT:
03930         halveImage_uint(cmpts, width, height,
03931                 (const GLuint *)usersImage, (GLuint *)dstImage,
03932                 element_size, rowsize, group_size, myswap_bytes);
03933         break;
03934       case GL_INT:
03935         halveImage_int(cmpts, width, height,
03936                (const GLint *)usersImage, (GLint *)dstImage,
03937                element_size, rowsize, group_size, myswap_bytes);
03938         break;
03939       case GL_FLOAT:
03940         halveImage_float(cmpts, width, height,
03941                  (const GLfloat *)usersImage, (GLfloat *)dstImage,
03942                  element_size, rowsize, group_size, myswap_bytes);
03943         break;
03944       case GL_UNSIGNED_BYTE_3_3_2:
03945         assert(format == GL_RGB);
03946         halveImagePackedPixel(3,extract332,shove332,
03947                   width,height,usersImage,dstImage,
03948                   element_size,rowsize,myswap_bytes);
03949         break;
03950       case GL_UNSIGNED_BYTE_2_3_3_REV:
03951         assert(format == GL_RGB);
03952         halveImagePackedPixel(3,extract233rev,shove233rev,
03953                   width,height,usersImage,dstImage,
03954                   element_size,rowsize,myswap_bytes);
03955         break;
03956       case GL_UNSIGNED_SHORT_5_6_5:
03957         halveImagePackedPixel(3,extract565,shove565,
03958                   width,height,usersImage,dstImage,
03959                   element_size,rowsize,myswap_bytes);
03960         break;
03961       case GL_UNSIGNED_SHORT_5_6_5_REV:
03962         halveImagePackedPixel(3,extract565rev,shove565rev,
03963                   width,height,usersImage,dstImage,
03964                   element_size,rowsize,myswap_bytes);
03965         break;
03966       case GL_UNSIGNED_SHORT_4_4_4_4:
03967         halveImagePackedPixel(4,extract4444,shove4444,
03968                   width,height,usersImage,dstImage,
03969                   element_size,rowsize,myswap_bytes);
03970         break;
03971       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
03972         halveImagePackedPixel(4,extract4444rev,shove4444rev,
03973                   width,height,usersImage,dstImage,
03974                   element_size,rowsize,myswap_bytes);
03975         break;
03976       case GL_UNSIGNED_SHORT_5_5_5_1:
03977         halveImagePackedPixel(4,extract5551,shove5551,
03978                   width,height,usersImage,dstImage,
03979                   element_size,rowsize,myswap_bytes);
03980         break;
03981       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
03982         halveImagePackedPixel(4,extract1555rev,shove1555rev,
03983                   width,height,usersImage,dstImage,
03984                   element_size,rowsize,myswap_bytes);
03985         break;
03986       case GL_UNSIGNED_INT_8_8_8_8:
03987         halveImagePackedPixel(4,extract8888,shove8888,
03988                   width,height,usersImage,dstImage,
03989                   element_size,rowsize,myswap_bytes);
03990         break;
03991       case GL_UNSIGNED_INT_8_8_8_8_REV:
03992         halveImagePackedPixel(4,extract8888rev,shove8888rev,
03993                   width,height,usersImage,dstImage,
03994                   element_size,rowsize,myswap_bytes);
03995         break;
03996       case GL_UNSIGNED_INT_10_10_10_2:
03997         halveImagePackedPixel(4,extract1010102,shove1010102,
03998                   width,height,usersImage,dstImage,
03999                   element_size,rowsize,myswap_bytes);
04000         break;
04001       case GL_UNSIGNED_INT_2_10_10_10_REV:
04002         halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
04003                   width,height,usersImage,dstImage,
04004                   element_size,rowsize,myswap_bytes);
04005         break;
04006       default:
04007         assert(0);
04008         break;
04009       }
04010     newwidth = width/2;
04011     newheight = height/2;
04012     /* clamp to 1 */
04013     if (newwidth < 1) newwidth= 1;
04014     if (newheight < 1) newheight= 1;
04015 
04016     myswap_bytes = 0;
04017     rowsize = newwidth * group_size;
04018     memreq = image_size(newwidth, newheight, format, type);
04019     /* Swap srcImage and dstImage */
04020     __GLU_SWAP_IMAGE(srcImage,dstImage);
04021     switch(type) {
04022     case GL_UNSIGNED_BYTE:
04023       dstImage = (GLubyte *)malloc(memreq);
04024       break;
04025     case GL_BYTE:
04026       dstImage = (GLbyte *)malloc(memreq);
04027       break;
04028     case GL_UNSIGNED_SHORT:
04029       dstImage = (GLushort *)malloc(memreq);
04030       break;
04031     case GL_SHORT:
04032       dstImage = (GLshort *)malloc(memreq);
04033       break;
04034     case GL_UNSIGNED_INT:
04035       dstImage = (GLuint *)malloc(memreq);
04036       break;
04037     case GL_INT:
04038       dstImage = (GLint *)malloc(memreq);
04039       break;
04040     case GL_FLOAT:
04041       dstImage = (GLfloat *)malloc(memreq);
04042       break;
04043     case GL_UNSIGNED_BYTE_3_3_2:
04044     case GL_UNSIGNED_BYTE_2_3_3_REV:
04045       dstImage = (GLubyte *)malloc(memreq);
04046       break;
04047     case GL_UNSIGNED_SHORT_5_6_5:
04048     case GL_UNSIGNED_SHORT_5_6_5_REV:
04049     case GL_UNSIGNED_SHORT_4_4_4_4:
04050     case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04051     case GL_UNSIGNED_SHORT_5_5_5_1:
04052     case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04053       dstImage = (GLushort *)malloc(memreq);
04054       break;
04055     case GL_UNSIGNED_INT_8_8_8_8:
04056     case GL_UNSIGNED_INT_8_8_8_8_REV:
04057     case GL_UNSIGNED_INT_10_10_10_2:
04058     case GL_UNSIGNED_INT_2_10_10_10_REV:
04059       dstImage = (GLuint *)malloc(memreq);
04060       break;
04061     default:
04062       return GLU_INVALID_ENUM;
04063     }
04064     if (dstImage == NULL) {
04065       glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
04066       glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
04067       glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
04068       glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
04069       glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
04070       return GLU_OUT_OF_MEMORY;
04071     }
04072     /* level userLevel+1 is in srcImage; level userLevel already saved */
04073     level = userLevel+1;
04074     } else { /* user's image is *not* nice power-of-2 sized square */
04075     memreq = image_size(newwidth, newheight, format, type);
04076     switch(type) {
04077         case GL_UNSIGNED_BYTE:
04078         dstImage = (GLubyte *)malloc(memreq);
04079         break;
04080         case GL_BYTE:
04081         dstImage = (GLbyte *)malloc(memreq);
04082         break;
04083         case GL_UNSIGNED_SHORT:
04084         dstImage = (GLushort *)malloc(memreq);
04085         break;
04086         case GL_SHORT:
04087         dstImage = (GLshort *)malloc(memreq);
04088         break;
04089         case GL_UNSIGNED_INT:
04090         dstImage = (GLuint *)malloc(memreq);
04091         break;
04092         case GL_INT:
04093         dstImage = (GLint *)malloc(memreq);
04094         break;
04095         case GL_FLOAT:
04096         dstImage = (GLfloat *)malloc(memreq);
04097         break;
04098         case GL_UNSIGNED_BYTE_3_3_2:
04099         case GL_UNSIGNED_BYTE_2_3_3_REV:
04100         dstImage = (GLubyte *)malloc(memreq);
04101         break;
04102         case GL_UNSIGNED_SHORT_5_6_5:
04103         case GL_UNSIGNED_SHORT_5_6_5_REV:
04104         case GL_UNSIGNED_SHORT_4_4_4_4:
04105         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04106         case GL_UNSIGNED_SHORT_5_5_5_1:
04107         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04108         dstImage = (GLushort *)malloc(memreq);
04109         break;
04110         case GL_UNSIGNED_INT_8_8_8_8:
04111         case GL_UNSIGNED_INT_8_8_8_8_REV:
04112         case GL_UNSIGNED_INT_10_10_10_2:
04113         case GL_UNSIGNED_INT_2_10_10_10_REV:
04114         dstImage = (GLuint *)malloc(memreq);
04115         break;
04116         default:
04117         return GLU_INVALID_ENUM;
04118     }
04119 
04120     if (dstImage == NULL) {
04121         glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
04122         glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
04123         glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
04124         glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
04125         glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
04126         return GLU_OUT_OF_MEMORY;
04127     }
04128 
04129     switch(type) {
04130     case GL_UNSIGNED_BYTE:
04131         scale_internal_ubyte(cmpts, width, height,
04132                  (const GLubyte *)usersImage, newwidth, newheight,
04133                  (GLubyte *)dstImage, element_size,
04134                  rowsize, group_size);
04135         break;
04136     case GL_BYTE:
04137         scale_internal_byte(cmpts, width, height,
04138                 (const GLbyte *)usersImage, newwidth, newheight,
04139                 (GLbyte *)dstImage, element_size,
04140                 rowsize, group_size);
04141         break;
04142     case GL_UNSIGNED_SHORT:
04143         scale_internal_ushort(cmpts, width, height,
04144                   (const GLushort *)usersImage, newwidth, newheight,
04145                   (GLushort *)dstImage, element_size,
04146                   rowsize, group_size, myswap_bytes);
04147         break;
04148     case GL_SHORT:
04149         scale_internal_short(cmpts, width, height,
04150                  (const GLshort *)usersImage, newwidth, newheight,
04151                  (GLshort *)dstImage, element_size,
04152                  rowsize, group_size, myswap_bytes);
04153         break;
04154     case GL_UNSIGNED_INT:
04155         scale_internal_uint(cmpts, width, height,
04156                 (const GLuint *)usersImage, newwidth, newheight,
04157                 (GLuint *)dstImage, element_size,
04158                 rowsize, group_size, myswap_bytes);
04159         break;
04160     case GL_INT:
04161         scale_internal_int(cmpts, width, height,
04162                    (const GLint *)usersImage, newwidth, newheight,
04163                    (GLint *)dstImage, element_size,
04164                    rowsize, group_size, myswap_bytes);
04165         break;
04166     case GL_FLOAT:
04167         scale_internal_float(cmpts, width, height,
04168                  (const GLfloat *)usersImage, newwidth, newheight,
04169                  (GLfloat *)dstImage, element_size,
04170                  rowsize, group_size, myswap_bytes);
04171         break;
04172     case GL_UNSIGNED_BYTE_3_3_2:
04173         scaleInternalPackedPixel(3,extract332,shove332,
04174                      width, height,usersImage,
04175                      newwidth,newheight,(void *)dstImage,
04176                      element_size,rowsize,myswap_bytes);
04177         break;
04178     case GL_UNSIGNED_BYTE_2_3_3_REV:
04179         scaleInternalPackedPixel(3,extract233rev,shove233rev,
04180                      width, height,usersImage,
04181                      newwidth,newheight,(void *)dstImage,
04182                      element_size,rowsize,myswap_bytes);
04183         break;
04184     case GL_UNSIGNED_SHORT_5_6_5:
04185         scaleInternalPackedPixel(3,extract565,shove565,
04186                      width, height,usersImage,
04187                      newwidth,newheight,(void *)dstImage,
04188                      element_size,rowsize,myswap_bytes);
04189         break;
04190     case GL_UNSIGNED_SHORT_5_6_5_REV:
04191         scaleInternalPackedPixel(3,extract565rev,shove565rev,
04192                      width, height,usersImage,
04193                      newwidth,newheight,(void *)dstImage,
04194                      element_size,rowsize,myswap_bytes);
04195         break;
04196     case GL_UNSIGNED_SHORT_4_4_4_4:
04197         scaleInternalPackedPixel(4,extract4444,shove4444,
04198                      width, height,usersImage,
04199                      newwidth,newheight,(void *)dstImage,
04200                      element_size,rowsize,myswap_bytes);
04201         break;
04202     case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04203         scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
04204                      width, height,usersImage,
04205                      newwidth,newheight,(void *)dstImage,
04206                      element_size,rowsize,myswap_bytes);
04207         break;
04208     case GL_UNSIGNED_SHORT_5_5_5_1:
04209         scaleInternalPackedPixel(4,extract5551,shove5551,
04210                      width, height,usersImage,
04211                      newwidth,newheight,(void *)dstImage,
04212                      element_size,rowsize,myswap_bytes);
04213         break;
04214     case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04215         scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
04216                      width, height,usersImage,
04217                      newwidth,newheight,(void *)dstImage,
04218                      element_size,rowsize,myswap_bytes);
04219         break;
04220     case GL_UNSIGNED_INT_8_8_8_8:
04221         scaleInternalPackedPixel(4,extract8888,shove8888,
04222                      width, height,usersImage,
04223                      newwidth,newheight,(void *)dstImage,
04224                      element_size,rowsize,myswap_bytes);
04225         break;
04226     case GL_UNSIGNED_INT_8_8_8_8_REV:
04227         scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
04228                      width, height,usersImage,
04229                      newwidth,newheight,(void *)dstImage,
04230                      element_size,rowsize,myswap_bytes);
04231         break;
04232     case GL_UNSIGNED_INT_10_10_10_2:
04233         scaleInternalPackedPixel(4,extract1010102,shove1010102,
04234                      width, height,usersImage,
04235                      newwidth,newheight,(void *)dstImage,
04236                      element_size,rowsize,myswap_bytes);
04237         break;
04238     case GL_UNSIGNED_INT_2_10_10_10_REV:
04239         scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
04240                      width, height,usersImage,
04241                      newwidth,newheight,(void *)dstImage,
04242                      element_size,rowsize,myswap_bytes);
04243         break;
04244     default:
04245         assert(0);
04246         break;
04247     }
04248     myswap_bytes = 0;
04249     rowsize = newwidth * group_size;
04250     /* Swap dstImage and srcImage */
04251     __GLU_SWAP_IMAGE(srcImage,dstImage);
04252 
04253     if(levels != 0) { /* use as little memory as possible */
04254       {
04255          int nextWidth= newwidth/2;
04256          int nextHeight= newheight/2;
04257          if (nextWidth < 1) nextWidth= 1;
04258          if (nextHeight < 1) nextHeight= 1;
04259 
04260       memreq = image_size(nextWidth, nextHeight, format, type);
04261       }
04262 
04263       switch(type) {
04264       case GL_UNSIGNED_BYTE:
04265         dstImage = (GLubyte *)malloc(memreq);
04266         break;
04267       case GL_BYTE:
04268         dstImage = (GLbyte *)malloc(memreq);
04269         break;
04270       case GL_UNSIGNED_SHORT:
04271         dstImage = (GLushort *)malloc(memreq);
04272         break;
04273       case GL_SHORT:
04274         dstImage = (GLshort *)malloc(memreq);
04275         break;
04276       case GL_UNSIGNED_INT:
04277         dstImage = (GLuint *)malloc(memreq);
04278         break;
04279       case GL_INT:
04280         dstImage = (GLint *)malloc(memreq);
04281         break;
04282       case GL_FLOAT:
04283         dstImage = (GLfloat *)malloc(memreq);
04284         break;
04285       case GL_UNSIGNED_BYTE_3_3_2:
04286       case GL_UNSIGNED_BYTE_2_3_3_REV:
04287         dstImage = (GLubyte *)malloc(memreq);
04288         break;
04289       case GL_UNSIGNED_SHORT_5_6_5:
04290       case GL_UNSIGNED_SHORT_5_6_5_REV:
04291       case GL_UNSIGNED_SHORT_4_4_4_4:
04292       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04293       case GL_UNSIGNED_SHORT_5_5_5_1:
04294       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04295         dstImage = (GLushort *)malloc(memreq);
04296         break;
04297       case GL_UNSIGNED_INT_8_8_8_8:
04298       case GL_UNSIGNED_INT_8_8_8_8_REV:
04299       case GL_UNSIGNED_INT_10_10_10_2:
04300       case GL_UNSIGNED_INT_2_10_10_10_REV:
04301         dstImage = (GLuint *)malloc(memreq);
04302         break;
04303       default:
04304         return GLU_INVALID_ENUM;
04305       }
04306       if (dstImage == NULL) {
04307         glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
04308         glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
04309         glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
04310         glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
04311         glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
04312         return GLU_OUT_OF_MEMORY;
04313       }
04314     }
04315     /* level userLevel is in srcImage; nothing saved yet */
04316     level = userLevel;
04317     }
04318 
04319     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
04320     if (baseLevel <= level && level <= maxLevel) {
04321     glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
04322          format, type, (void *)srcImage);
04323     }
04324 
04325     level++; /* update current level for the loop */
04326     for (; level <= levels; level++) {
04327     switch(type) {
04328         case GL_UNSIGNED_BYTE:
04329         halveImage_ubyte(cmpts, newwidth, newheight,
04330         (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
04331         rowsize, group_size);
04332         break;
04333         case GL_BYTE:
04334         halveImage_byte(cmpts, newwidth, newheight,
04335         (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
04336         rowsize, group_size);
04337         break;
04338         case GL_UNSIGNED_SHORT:
04339         halveImage_ushort(cmpts, newwidth, newheight,
04340         (GLushort *)srcImage, (GLushort *)dstImage, element_size,
04341         rowsize, group_size, myswap_bytes);
04342         break;
04343         case GL_SHORT:
04344         halveImage_short(cmpts, newwidth, newheight,
04345         (GLshort *)srcImage, (GLshort *)dstImage, element_size,
04346         rowsize, group_size, myswap_bytes);
04347         break;
04348         case GL_UNSIGNED_INT:
04349         halveImage_uint(cmpts, newwidth, newheight,
04350         (GLuint *)srcImage, (GLuint *)dstImage, element_size,
04351         rowsize, group_size, myswap_bytes);
04352         break;
04353         case GL_INT:
04354         halveImage_int(cmpts, newwidth, newheight,
04355         (GLint *)srcImage, (GLint *)dstImage, element_size,
04356         rowsize, group_size, myswap_bytes);
04357         break;
04358         case GL_FLOAT:
04359         halveImage_float(cmpts, newwidth, newheight,
04360         (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
04361         rowsize, group_size, myswap_bytes);
04362         break;
04363         case GL_UNSIGNED_BYTE_3_3_2:
04364         halveImagePackedPixel(3,extract332,shove332,
04365                       newwidth,newheight,
04366                       srcImage,dstImage,element_size,rowsize,
04367                       myswap_bytes);
04368         break;
04369         case GL_UNSIGNED_BYTE_2_3_3_REV:
04370         halveImagePackedPixel(3,extract233rev,shove233rev,
04371                       newwidth,newheight,
04372                       srcImage,dstImage,element_size,rowsize,
04373                       myswap_bytes);
04374         break;
04375         case GL_UNSIGNED_SHORT_5_6_5:
04376         halveImagePackedPixel(3,extract565,shove565,
04377                       newwidth,newheight,
04378                       srcImage,dstImage,element_size,rowsize,
04379                       myswap_bytes);
04380         break;
04381         case GL_UNSIGNED_SHORT_5_6_5_REV:
04382         halveImagePackedPixel(3,extract565rev,shove565rev,
04383                       newwidth,newheight,
04384                       srcImage,dstImage,element_size,rowsize,
04385                       myswap_bytes);
04386         break;
04387         case GL_UNSIGNED_SHORT_4_4_4_4:
04388         halveImagePackedPixel(4,extract4444,shove4444,
04389                       newwidth,newheight,
04390                       srcImage,dstImage,element_size,rowsize,
04391                       myswap_bytes);
04392         break;
04393         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04394         halveImagePackedPixel(4,extract4444rev,shove4444rev,
04395                       newwidth,newheight,
04396                       srcImage,dstImage,element_size,rowsize,
04397                       myswap_bytes);
04398         break;
04399         case GL_UNSIGNED_SHORT_5_5_5_1:
04400         halveImagePackedPixel(4,extract5551,shove5551,
04401                       newwidth,newheight,
04402                       srcImage,dstImage,element_size,rowsize,
04403                       myswap_bytes);
04404         break;
04405         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04406         halveImagePackedPixel(4,extract1555rev,shove1555rev,
04407                       newwidth,newheight,
04408                       srcImage,dstImage,element_size,rowsize,
04409                       myswap_bytes);
04410         break;
04411         case GL_UNSIGNED_INT_8_8_8_8:
04412         halveImagePackedPixel(4,extract8888,shove8888,
04413                       newwidth,newheight,
04414                       srcImage,dstImage,element_size,rowsize,
04415                       myswap_bytes);
04416         break;
04417         case GL_UNSIGNED_INT_8_8_8_8_REV:
04418         halveImagePackedPixel(4,extract8888rev,shove8888rev,
04419                       newwidth,newheight,
04420                       srcImage,dstImage,element_size,rowsize,
04421                       myswap_bytes);
04422         break;
04423         case GL_UNSIGNED_INT_10_10_10_2:
04424         halveImagePackedPixel(4,extract1010102,shove1010102,
04425                       newwidth,newheight,
04426                       srcImage,dstImage,element_size,rowsize,
04427                       myswap_bytes);
04428         break;
04429         case GL_UNSIGNED_INT_2_10_10_10_REV:
04430         halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
04431                       newwidth,newheight,
04432                       srcImage,dstImage,element_size,rowsize,
04433                       myswap_bytes);
04434         break;
04435         default:
04436         assert(0);
04437         break;
04438     }
04439 
04440     __GLU_SWAP_IMAGE(srcImage,dstImage);
04441 
04442     if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
04443     if (newheight > 1) newheight /= 2;
04444       {
04445        /* compute amount to pad per row, if any */
04446        int rowPad= rowsize % psm.unpack_alignment;
04447 
04448        /* should row be padded? */
04449        if (rowPad == 0) {   /* nope, row should not be padded */
04450        /* call tex image with srcImage untouched since it's not padded */
04451        if (baseLevel <= level && level <= maxLevel) {
04452        glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
04453        format, type, (void *) srcImage);
04454        }
04455        }
04456        else {           /* yes, row should be padded */
04457       /* compute length of new row in bytes, including padding */
04458       int newRowLength= rowsize + psm.unpack_alignment - rowPad;
04459       int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
04460 
04461       /* allocate new image for mipmap of size newRowLength x newheight */
04462       void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
04463       if (newMipmapImage == NULL) {
04464          /* out of memory so return */
04465          glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
04466          glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
04467          glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
04468          glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
04469          glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
04470          return GLU_OUT_OF_MEMORY;
04471       }
04472 
04473       /* copy image from srcImage into newMipmapImage by rows */
04474       for (ii= 0,
04475            dstTrav= (unsigned char *) newMipmapImage,
04476            srcTrav= (unsigned char *) srcImage;
04477            ii< newheight;
04478            ii++,
04479            dstTrav+= newRowLength, /* make sure the correct distance... */
04480            srcTrav+= rowsize) {    /* ...is skipped */
04481          memcpy(dstTrav,srcTrav,rowsize);
04482          /* note that the pad bytes are not visited and will contain
04483           * garbage, which is ok.
04484           */
04485       }
04486 
04487       /* ...and use this new image for mipmapping instead */
04488       if (baseLevel <= level && level <= maxLevel) {
04489       glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
04490                format, type, newMipmapImage);
04491       }
04492       free(newMipmapImage); /* don't forget to free it! */
04493        } /* else */
04494       }
04495     } /* for level */
04496     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
04497     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
04498     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
04499     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
04500     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
04501 
04502     free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
04503     if (dstImage) { /* if it's non-rectangular and only 1 level */
04504       free(dstImage);
04505     }
04506     return 0;
04507 } /* gluBuild2DMipmapLevelsCore() */
04508 
04509 GLint GLAPIENTRY
04510 gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
04511                  GLsizei width, GLsizei height,
04512                  GLenum format, GLenum type,
04513                  GLint userLevel, GLint baseLevel, GLint maxLevel,
04514                  const void *data)
04515 {
04516    int level, levels;
04517 
04518    int rc= checkMipmapArgs(internalFormat,format,type);
04519    if (rc != 0) return rc;
04520 
04521    if (width < 1 || height < 1) {
04522        return GLU_INVALID_VALUE;
04523    }
04524 
04525    levels = computeLog(width);
04526    level = computeLog(height);
04527    if (level > levels) levels=level;
04528 
04529    levels+= userLevel;
04530    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
04531       return GLU_INVALID_VALUE;
04532 
04533    return gluBuild2DMipmapLevelsCore(target, internalFormat,
04534                      width, height,
04535                      width, height,
04536                      format, type,
04537                      userLevel, baseLevel, maxLevel,
04538                      data);
04539 } /* gluBuild2DMipmapLevels() */
04540 
04541 GLint GLAPIENTRY
04542 gluBuild2DMipmaps(GLenum target, GLint internalFormat,
04543             GLsizei width, GLsizei height,
04544             GLenum format, GLenum type,
04545             const void *data)
04546 {
04547    GLint widthPowerOf2, heightPowerOf2;
04548    int level, levels;
04549 
04550    int rc= checkMipmapArgs(internalFormat,format,type);
04551    if (rc != 0) return rc;
04552 
04553    if (width < 1 || height < 1) {
04554        return GLU_INVALID_VALUE;
04555    }
04556 
04557    closestFit(target,width,height,internalFormat,format,type,
04558           &widthPowerOf2,&heightPowerOf2);
04559 
04560    levels = computeLog(widthPowerOf2);
04561    level = computeLog(heightPowerOf2);
04562    if (level > levels) levels=level;
04563 
04564    return gluBuild2DMipmapLevelsCore(target,internalFormat,
04565                      width, height,
04566                      widthPowerOf2,heightPowerOf2,
04567                      format,type,
04568                      0,0,levels,data);
04569 }  /* gluBuild2DMipmaps() */
04570 
04571 #if 0
04572 /*
04573 ** This routine is for the limited case in which
04574 **  type == GL_UNSIGNED_BYTE && format != index  &&
04575 **  unpack_alignment = 1 && unpack_swap_bytes == false
04576 **
04577 ** so all of the work data can be kept as ubytes instead of shorts.
04578 */
04579 static int fastBuild2DMipmaps(const PixelStorageModes *psm,
04580                GLenum target, GLint components, GLint width,
04581              GLint height, GLenum format,
04582              GLenum type, void *data)
04583 {
04584     GLint newwidth, newheight;
04585     GLint level, levels;
04586     GLubyte *newImage;
04587     GLint newImage_width;
04588     GLint newImage_height;
04589     GLubyte *otherImage;
04590     GLubyte *imageTemp;
04591     GLint memreq;
04592     GLint cmpts;
04593 
04594 
04595 #if 0
04596     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
04597     newwidth = nearestPower(width);
04598     if (newwidth > maxsize) newwidth = maxsize;
04599     newheight = nearestPower(height);
04600     if (newheight > maxsize) newheight = maxsize;
04601 #else
04602     closestFit(target,width,height,components,format,type,
04603            &newwidth,&newheight);
04604 #endif
04605     levels = computeLog(newwidth);
04606     level = computeLog(newheight);
04607     if (level > levels) levels=level;
04608 
04609     cmpts = elements_per_group(format,type);
04610 
04611     otherImage = NULL;
04616     if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
04617     newImage = (GLubyte *)data;
04618     newImage_width = width;
04619     newImage_height = height;
04620     } else {
04621     GLint rowsize;
04622     GLint groups_per_line;
04623     GLint elements_per_line;
04624     const GLubyte *start;
04625     const GLubyte *iter;
04626     GLubyte *iter2;
04627     GLint i, j;
04628 
04629     newImage = (GLubyte *)
04630         malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
04631     newImage_width = width;
04632     newImage_height = height;
04633     if (newImage == NULL) {
04634         return GLU_OUT_OF_MEMORY;
04635     }
04636 
04637     /*
04638     ** Abbreviated version of fill_image for this restricted case.
04639     */
04640     if (psm->unpack_row_length > 0) {
04641         groups_per_line = psm->unpack_row_length;
04642     } else {
04643         groups_per_line = width;
04644     }
04645     rowsize = groups_per_line * cmpts;
04646     elements_per_line = width * cmpts;
04647     start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
04648         psm->unpack_skip_pixels * cmpts;
04649     iter2 = newImage;
04650 
04651     for (i = 0; i < height; i++) {
04652         iter = start;
04653         for (j = 0; j < elements_per_line; j++) {
04654         *iter2 = *iter;
04655         iter++;
04656         iter2++;
04657         }
04658         start += rowsize;
04659     }
04660     }
04661 
04662 
04663     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
04664     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
04665     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
04666     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
04667     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
04668 
04669     for (level = 0; level <= levels; level++) {
04670     if (newImage_width == newwidth && newImage_height == newheight) {
04671         /* Use newImage for this level */
04672         glTexImage2D(target, level, components, newImage_width,
04673             newImage_height, 0, format, GL_UNSIGNED_BYTE,
04674             (void *) newImage);
04675     } else {
04676         if (otherImage == NULL) {
04677         memreq =
04678             image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
04679         otherImage = (GLubyte *) malloc(memreq);
04680         if (otherImage == NULL) {
04681             glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
04682             glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
04683             glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
04684             glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
04685             glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
04686             return GLU_OUT_OF_MEMORY;
04687         }
04688         }
04689 /*
04690         scale_internal_ubyte(cmpts, newImage_width, newImage_height,
04691             newImage, newwidth, newheight, otherImage);
04692 */
04693         /* Swap newImage and otherImage */
04694         imageTemp = otherImage;
04695         otherImage = newImage;
04696         newImage = imageTemp;
04697 
04698         newImage_width = newwidth;
04699         newImage_height = newheight;
04700         glTexImage2D(target, level, components, newImage_width,
04701             newImage_height, 0, format, GL_UNSIGNED_BYTE,
04702             (void *) newImage);
04703     }
04704     if (newwidth > 1) newwidth /= 2;
04705     if (newheight > 1) newheight /= 2;
04706     }
04707     glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
04708     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
04709     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
04710     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
04711     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
04712 
04713     if (newImage != (const GLubyte *)data) {
04714     free((GLbyte *) newImage);
04715     }
04716     if (otherImage && otherImage != (const GLubyte *)data) {
04717     free((GLbyte *) otherImage);
04718     }
04719     return 0;
04720 }
04721 #endif
04722 
04723 /*
04724  * Utility Routines
04725  */
04726 static GLint elements_per_group(GLenum format, GLenum type)
04727 {
04728     /*
04729      * Return the number of elements per group of a specified format
04730      */
04731 
04732     /* If the type is packedpixels then answer is 1 (ignore format) */
04733     if (type == GL_UNSIGNED_BYTE_3_3_2 ||
04734     type == GL_UNSIGNED_BYTE_2_3_3_REV ||
04735     type == GL_UNSIGNED_SHORT_5_6_5 ||
04736     type == GL_UNSIGNED_SHORT_5_6_5_REV ||
04737     type == GL_UNSIGNED_SHORT_4_4_4_4 ||
04738     type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
04739     type == GL_UNSIGNED_SHORT_5_5_5_1  ||
04740     type == GL_UNSIGNED_SHORT_1_5_5_5_REV  ||
04741     type == GL_UNSIGNED_INT_8_8_8_8 ||
04742     type == GL_UNSIGNED_INT_8_8_8_8_REV ||
04743     type == GL_UNSIGNED_INT_10_10_10_2 ||
04744     type == GL_UNSIGNED_INT_2_10_10_10_REV) {
04745     return 1;
04746     }
04747 
04748     /* Types are not packed pixels, so get elements per group */
04749     switch(format) {
04750       case GL_RGB:
04751       case GL_BGR:
04752     return 3;
04753       case GL_LUMINANCE_ALPHA:
04754     return 2;
04755       case GL_RGBA:
04756       case GL_BGRA:
04757     return 4;
04758       default:
04759     return 1;
04760     }
04761 }
04762 
04763 static GLfloat bytes_per_element(GLenum type)
04764 {
04765     /*
04766      * Return the number of bytes per element, based on the element type
04767      */
04768     switch(type) {
04769       case GL_BITMAP:
04770     return 1.0 / 8.0;
04771       case GL_UNSIGNED_SHORT:
04772     return(sizeof(GLushort));
04773       case GL_SHORT:
04774     return(sizeof(GLshort));
04775       case GL_UNSIGNED_BYTE:
04776     return(sizeof(GLubyte));
04777       case GL_BYTE:
04778     return(sizeof(GLbyte));
04779       case GL_INT:
04780     return(sizeof(GLint));
04781       case GL_UNSIGNED_INT:
04782     return(sizeof(GLuint));
04783       case GL_FLOAT:
04784     return(sizeof(GLfloat));
04785       case GL_UNSIGNED_BYTE_3_3_2:
04786       case GL_UNSIGNED_BYTE_2_3_3_REV:
04787     return(sizeof(GLubyte));
04788       case GL_UNSIGNED_SHORT_5_6_5:
04789       case GL_UNSIGNED_SHORT_5_6_5_REV:
04790       case GL_UNSIGNED_SHORT_4_4_4_4:
04791       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04792       case GL_UNSIGNED_SHORT_5_5_5_1:
04793       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04794     return(sizeof(GLushort));
04795       case GL_UNSIGNED_INT_8_8_8_8:
04796       case GL_UNSIGNED_INT_8_8_8_8_REV:
04797       case GL_UNSIGNED_INT_10_10_10_2:
04798       case GL_UNSIGNED_INT_2_10_10_10_REV:
04799     return(sizeof(GLuint));
04800       default:
04801     return 4;
04802     }
04803 }
04804 
04805 static GLint is_index(GLenum format)
04806 {
04807     return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
04808 }
04809 
04810 /*
04811 ** Compute memory required for internal packed array of data of given type
04812 ** and format.
04813 */
04814 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
04815 {
04816     int bytes_per_row;
04817     int components;
04818 
04819 assert(width > 0);
04820 assert(height > 0);
04821     components = elements_per_group(format,type);
04822     if (type == GL_BITMAP) {
04823     bytes_per_row = (width + 7) / 8;
04824     } else {
04825     bytes_per_row = bytes_per_element(type) * width;
04826     }
04827     return bytes_per_row * height * components;
04828 }
04829 
04830 /*
04831 ** Extract array from user's data applying all pixel store modes.
04832 ** The internal format used is an array of unsigned shorts.
04833 */
04834 static void fill_image(const PixelStorageModes *psm,
04835                GLint width, GLint height, GLenum format,
04836                GLenum type, GLboolean index_format,
04837                const void *userdata, GLushort *newimage)
04838 {
04839     GLint components;
04840     GLint element_size;
04841     GLint rowsize;
04842     GLint padding;
04843     GLint groups_per_line;
04844     GLint group_size;
04845     GLint elements_per_line;
04846     const GLubyte *start;
04847     const GLubyte *iter = NULL;
04848     GLushort *iter2;
04849     GLint i, j, k;
04850     GLint myswap_bytes;
04851 
04852     myswap_bytes = psm->unpack_swap_bytes;
04853     components = elements_per_group(format,type);
04854     if (psm->unpack_row_length > 0) {
04855     groups_per_line = psm->unpack_row_length;
04856     } else {
04857     groups_per_line = width;
04858     }
04859 
04860     /* All formats except GL_BITMAP fall out trivially */
04861     if (type == GL_BITMAP) {
04862     GLint bit_offset;
04863     GLint current_bit;
04864 
04865     rowsize = (groups_per_line * components + 7) / 8;
04866     padding = (rowsize % psm->unpack_alignment);
04867     if (padding) {
04868         rowsize += psm->unpack_alignment - padding;
04869     }
04870 
04871     start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
04872         (psm->unpack_skip_pixels * components / 8);
04873     elements_per_line = width * components;
04874     iter2 = newimage;
04875     for (i = 0; i < height; i++) {
04876         iter = start;
04877         bit_offset = (psm->unpack_skip_pixels * components) % 8;
04878         for (j = 0; j < elements_per_line; j++) {
04879         /* Retrieve bit */
04880         if (psm->unpack_lsb_first) {
04881             current_bit = iter[0] & (1 << bit_offset);
04882         } else {
04883             current_bit = iter[0] & (1 << (7 - bit_offset));
04884         }
04885         if (current_bit) {
04886             if (index_format) {
04887             *iter2 = 1;
04888             } else {
04889             *iter2 = 65535;
04890             }
04891         } else {
04892             *iter2 = 0;
04893         }
04894         bit_offset++;
04895         if (bit_offset == 8) {
04896             bit_offset = 0;
04897             iter++;
04898         }
04899         iter2++;
04900         }
04901         start += rowsize;
04902     }
04903     } else {
04904     element_size = bytes_per_element(type);
04905     group_size = element_size * components;
04906     if (element_size == 1) myswap_bytes = 0;
04907 
04908     rowsize = groups_per_line * group_size;
04909     padding = (rowsize % psm->unpack_alignment);
04910     if (padding) {
04911         rowsize += psm->unpack_alignment - padding;
04912     }
04913     start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
04914         psm->unpack_skip_pixels * group_size;
04915     elements_per_line = width * components;
04916 
04917     iter2 = newimage;
04918     for (i = 0; i < height; i++) {
04919         iter = start;
04920         for (j = 0; j < elements_per_line; j++) {
04921         Type_Widget widget;
04922         float extractComponents[4];
04923 
04924         switch(type) {
04925           case GL_UNSIGNED_BYTE_3_3_2:
04926             extract332(0,iter,extractComponents);
04927             for (k = 0; k < 3; k++) {
04928               *iter2++ = (GLushort)(extractComponents[k]*65535);
04929             }
04930             break;
04931           case GL_UNSIGNED_BYTE_2_3_3_REV:
04932             extract233rev(0,iter,extractComponents);
04933             for (k = 0; k < 3; k++) {
04934               *iter2++ = (GLushort)(extractComponents[k]*65535);
04935             }
04936             break;
04937           case GL_UNSIGNED_BYTE:
04938             if (index_format) {
04939             *iter2++ = *iter;
04940             } else {
04941             *iter2++ = (*iter) * 257;
04942             }
04943             break;
04944           case GL_BYTE:
04945             if (index_format) {
04946             *iter2++ = *((const GLbyte *) iter);
04947             } else {
04948             /* rough approx */
04949             *iter2++ = (*((const GLbyte *) iter)) * 516;
04950             }
04951             break;
04952           case GL_UNSIGNED_SHORT_5_6_5:
04953             extract565(myswap_bytes,iter,extractComponents);
04954             for (k = 0; k < 3; k++) {
04955               *iter2++ = (GLushort)(extractComponents[k]*65535);
04956             }
04957             break;
04958           case GL_UNSIGNED_SHORT_5_6_5_REV:
04959             extract565rev(myswap_bytes,iter,extractComponents);
04960             for (k = 0; k < 3; k++) {
04961               *iter2++ = (GLushort)(extractComponents[k]*65535);
04962             }
04963             break;
04964           case GL_UNSIGNED_SHORT_4_4_4_4:
04965             extract4444(myswap_bytes,iter,extractComponents);
04966             for (k = 0; k < 4; k++) {
04967               *iter2++ = (GLushort)(extractComponents[k]*65535);
04968             }
04969             break;
04970           case GL_UNSIGNED_SHORT_4_4_4_4_REV:
04971             extract4444rev(myswap_bytes,iter,extractComponents);
04972             for (k = 0; k < 4; k++) {
04973               *iter2++ = (GLushort)(extractComponents[k]*65535);
04974             }
04975             break;
04976           case GL_UNSIGNED_SHORT_5_5_5_1:
04977             extract5551(myswap_bytes,iter,extractComponents);
04978             for (k = 0; k < 4; k++) {
04979               *iter2++ = (GLushort)(extractComponents[k]*65535);
04980             }
04981             break;
04982           case GL_UNSIGNED_SHORT_1_5_5_5_REV:
04983             extract1555rev(myswap_bytes,iter,extractComponents);
04984             for (k = 0; k < 4; k++) {
04985               *iter2++ = (GLushort)(extractComponents[k]*65535);
04986             }
04987             break;
04988           case GL_UNSIGNED_SHORT:
04989           case GL_SHORT:
04990             if (myswap_bytes) {
04991             widget.ub[0] = iter[1];
04992             widget.ub[1] = iter[0];
04993             } else {
04994             widget.ub[0] = iter[0];
04995             widget.ub[1] = iter[1];
04996             }
04997             if (type == GL_SHORT) {
04998             if (index_format) {
04999                 *iter2++ = widget.s[0];
05000             } else {
05001                 /* rough approx */
05002                 *iter2++ = widget.s[0]*2;
05003             }
05004             } else {
05005             *iter2++ = widget.us[0];
05006             }
05007             break;
05008           case GL_UNSIGNED_INT_8_8_8_8:
05009             extract8888(myswap_bytes,iter,extractComponents);
05010             for (k = 0; k < 4; k++) {
05011               *iter2++ = (GLushort)(extractComponents[k]*65535);
05012             }
05013             break;
05014           case GL_UNSIGNED_INT_8_8_8_8_REV:
05015             extract8888rev(myswap_bytes,iter,extractComponents);
05016             for (k = 0; k < 4; k++) {
05017               *iter2++ = (GLushort)(extractComponents[k]*65535);
05018             }
05019             break;
05020           case GL_UNSIGNED_INT_10_10_10_2:
05021             extract1010102(myswap_bytes,iter,extractComponents);
05022             for (k = 0; k < 4; k++) {
05023               *iter2++ = (GLushort)(extractComponents[k]*65535);
05024             }
05025             break;
05026           case GL_UNSIGNED_INT_2_10_10_10_REV:
05027             extract2101010rev(myswap_bytes,iter,extractComponents);
05028             for (k = 0; k < 4; k++) {
05029               *iter2++ = (GLushort)(extractComponents[k]*65535);
05030             }
05031             break;
05032           case GL_INT:
05033           case GL_UNSIGNED_INT:
05034           case GL_FLOAT:
05035             if (myswap_bytes) {
05036             widget.ub[0] = iter[3];
05037             widget.ub[1] = iter[2];
05038             widget.ub[2] = iter[1];
05039             widget.ub[3] = iter[0];
05040             } else {
05041             widget.ub[0] = iter[0];
05042             widget.ub[1] = iter[1];
05043             widget.ub[2] = iter[2];
05044             widget.ub[3] = iter[3];
05045             }
05046             if (type == GL_FLOAT) {
05047             if (index_format) {
05048                 *iter2++ = widget.f;
05049             } else {
05050                 *iter2++ = 65535 * widget.f;
05051             }
05052             } else if (type == GL_UNSIGNED_INT) {
05053             if (index_format) {
05054                 *iter2++ = widget.ui;
05055             } else {
05056                 *iter2++ = widget.ui >> 16;
05057             }
05058             } else {
05059             if (index_format) {
05060                 *iter2++ = widget.i;
05061             } else {
05062                 *iter2++ = widget.i >> 15;
05063             }
05064             }
05065             break;
05066         }
05067         iter += element_size;
05068         } /* for j */
05069         start += rowsize;
05070 #if 1
05071         /* want 'iter' pointing at start, not within, row for assertion
05072          * purposes
05073          */
05074         iter= start;
05075 #endif
05076     } /* for i */
05077 
05078        /* iterators should be one byte past end */
05079        if (!isTypePackedPixel(type)) {
05080       assert(iter2 == &newimage[width*height*components]);
05081        }
05082        else {
05083       assert(iter2 == &newimage[width*height*
05084                     elements_per_group(format,0)]);
05085        }
05086        assert( iter == &((const GLubyte *)userdata)[rowsize*height +
05087                     psm->unpack_skip_rows * rowsize +
05088                     psm->unpack_skip_pixels * group_size] );
05089 
05090     } /* else */
05091 } /* fill_image() */
05092 
05093 /*
05094 ** Insert array into user's data applying all pixel store modes.
05095 ** The internal format is an array of unsigned shorts.
05096 ** empty_image() because it is the opposite of fill_image().
05097 */
05098 static void empty_image(const PixelStorageModes *psm,
05099             GLint width, GLint height, GLenum format,
05100             GLenum type, GLboolean index_format,
05101             const GLushort *oldimage, void *userdata)
05102 {
05103     GLint components;
05104     GLint element_size;
05105     GLint rowsize;
05106     GLint padding;
05107     GLint groups_per_line;
05108     GLint group_size;
05109     GLint elements_per_line;
05110     GLubyte *start;
05111     GLubyte *iter = NULL;
05112     const GLushort *iter2;
05113     GLint i, j, k;
05114     GLint myswap_bytes;
05115 
05116     myswap_bytes = psm->pack_swap_bytes;
05117     components = elements_per_group(format,type);
05118     if (psm->pack_row_length > 0) {
05119     groups_per_line = psm->pack_row_length;
05120     } else {
05121     groups_per_line = width;
05122     }
05123 
05124     /* All formats except GL_BITMAP fall out trivially */
05125     if (type == GL_BITMAP) {
05126     GLint bit_offset;
05127     GLint current_bit;
05128 
05129     rowsize = (groups_per_line * components + 7) / 8;
05130     padding = (rowsize % psm->pack_alignment);
05131     if (padding) {
05132         rowsize += psm->pack_alignment - padding;
05133     }
05134     start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
05135         (psm->pack_skip_pixels * components / 8);
05136     elements_per_line = width * components;
05137     iter2 = oldimage;
05138     for (i = 0; i < height; i++) {
05139         iter = start;
05140         bit_offset = (psm->pack_skip_pixels * components) % 8;
05141         for (j = 0; j < elements_per_line; j++) {
05142         if (index_format) {
05143             current_bit = iter2[0] & 1;
05144         } else {
05145             if (iter2[0] > 32767) {
05146             current_bit = 1;
05147             } else {
05148             current_bit = 0;
05149             }
05150         }
05151 
05152         if (current_bit) {
05153             if (psm->pack_lsb_first) {
05154             *iter |= (1 << bit_offset);
05155             } else {
05156             *iter |= (1 << (7 - bit_offset));
05157             }
05158         } else {
05159             if (psm->pack_lsb_first) {
05160             *iter &= ~(1 << bit_offset);
05161             } else {
05162             *iter &= ~(1 << (7 - bit_offset));
05163             }
05164         }
05165 
05166         bit_offset++;
05167         if (bit_offset == 8) {
05168             bit_offset = 0;
05169             iter++;
05170         }
05171         iter2++;
05172         }
05173         start += rowsize;
05174     }
05175     } else {
05176     float shoveComponents[4];
05177 
05178     element_size = bytes_per_element(type);
05179     group_size = element_size * components;
05180     if (element_size == 1) myswap_bytes = 0;
05181 
05182     rowsize = groups_per_line * group_size;
05183     padding = (rowsize % psm->pack_alignment);
05184     if (padding) {
05185         rowsize += psm->pack_alignment - padding;
05186     }
05187     start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
05188         psm->pack_skip_pixels * group_size;
05189     elements_per_line = width * components;
05190 
05191     iter2 = oldimage;
05192     for (i = 0; i < height; i++) {
05193         iter = start;
05194         for (j = 0; j < elements_per_line; j++) {
05195         Type_Widget widget;
05196 
05197         switch(type) {
05198           case GL_UNSIGNED_BYTE_3_3_2:
05199             for (k = 0; k < 3; k++) {
05200                shoveComponents[k]= *iter2++ / 65535.0;
05201             }
05202             shove332(shoveComponents,0,(void *)iter);
05203             break;
05204           case GL_UNSIGNED_BYTE_2_3_3_REV:
05205             for (k = 0; k < 3; k++) {
05206                shoveComponents[k]= *iter2++ / 65535.0;
05207             }
05208             shove233rev(shoveComponents,0,(void *)iter);
05209             break;
05210           case GL_UNSIGNED_BYTE:
05211             if (index_format) {
05212             *iter = *iter2++;
05213             } else {
05214             *iter = *iter2++ >> 8;
05215             }
05216             break;
05217           case GL_BYTE:
05218             if (index_format) {
05219             *((GLbyte *) iter) = *iter2++;
05220             } else {
05221             *((GLbyte *) iter) = *iter2++ >> 9;
05222             }
05223             break;
05224           case GL_UNSIGNED_SHORT_5_6_5:
05225             for (k = 0; k < 3; k++) {
05226                shoveComponents[k]= *iter2++ / 65535.0;
05227             }
05228             shove565(shoveComponents,0,(void *)&widget.us[0]);
05229             if (myswap_bytes) {
05230                iter[0] = widget.ub[1];
05231                iter[1] = widget.ub[0];
05232             }
05233             else {
05234                *(GLushort *)iter = widget.us[0];
05235             }
05236             break;
05237           case GL_UNSIGNED_SHORT_5_6_5_REV:
05238             for (k = 0; k < 3; k++) {
05239                shoveComponents[k]= *iter2++ / 65535.0;
05240             }
05241             shove565rev(shoveComponents,0,(void *)&widget.us[0]);
05242             if (myswap_bytes) {
05243                iter[0] = widget.ub[1];
05244                iter[1] = widget.ub[0];
05245             }
05246             else {
05247                *(GLushort *)iter = widget.us[0];
05248             }
05249             break;
05250           case GL_UNSIGNED_SHORT_4_4_4_4:
05251             for (k = 0; k < 4; k++) {
05252                shoveComponents[k]= *iter2++ / 65535.0;
05253             }
05254             shove4444(shoveComponents,0,(void *)&widget.us[0]);
05255             if (myswap_bytes) {
05256                iter[0] = widget.ub[1];
05257                iter[1] = widget.ub[0];
05258             } else {
05259                *(GLushort *)iter = widget.us[0];
05260             }
05261             break;
05262           case GL_UNSIGNED_SHORT_4_4_4_4_REV:
05263             for (k = 0; k < 4; k++) {
05264                shoveComponents[k]= *iter2++ / 65535.0;
05265             }
05266             shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
05267             if (myswap_bytes) {
05268                iter[0] = widget.ub[1];
05269                iter[1] = widget.ub[0];
05270             } else {
05271                *(GLushort *)iter = widget.us[0];
05272             }
05273             break;
05274           case GL_UNSIGNED_SHORT_5_5_5_1:
05275             for (k = 0; k < 4; k++) {
05276                shoveComponents[k]= *iter2++ / 65535.0;
05277             }
05278             shove5551(shoveComponents,0,(void *)&widget.us[0]);
05279             if (myswap_bytes) {
05280                iter[0] = widget.ub[1];
05281                iter[1] = widget.ub[0];
05282             } else {
05283                *(GLushort *)iter = widget.us[0];
05284             }
05285             break;
05286           case GL_UNSIGNED_SHORT_1_5_5_5_REV:
05287             for (k = 0; k < 4; k++) {
05288                shoveComponents[k]= *iter2++ / 65535.0;
05289             }
05290             shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
05291             if (myswap_bytes) {
05292                iter[0] = widget.ub[1];
05293                iter[1] = widget.ub[0];
05294             } else {
05295                *(GLushort *)iter = widget.us[0];
05296             }
05297             break;
05298           case GL_UNSIGNED_SHORT:
05299           case GL_SHORT:
05300             if (type == GL_SHORT) {
05301             if (index_format) {
05302                 widget.s[0] = *iter2++;
05303             } else {
05304                 widget.s[0] = *iter2++ >> 1;
05305             }
05306             } else {
05307             widget.us[0] = *iter2++;
05308             }
05309             if (myswap_bytes) {
05310             iter[0] = widget.ub[1];
05311             iter[1] = widget.ub[0];
05312             } else {
05313             iter[0] = widget.ub[0];
05314             iter[1] = widget.ub[1];
05315             }
05316             break;
05317           case GL_UNSIGNED_INT_8_8_8_8:
05318             for (k = 0; k < 4; k++) {
05319                shoveComponents[k]= *iter2++ / 65535.0;
05320             }
05321             shove8888(shoveComponents,0,(void *)&widget.ui);
05322             if (myswap_bytes) {
05323             iter[3] = widget.ub[0];
05324             iter[2] = widget.ub[1];
05325             iter[1] = widget.ub[2];
05326             iter[0] = widget.ub[3];
05327             } else {
05328             *(GLuint *)iter= widget.ui;
05329             }
05330 
05331             break;
05332           case GL_UNSIGNED_INT_8_8_8_8_REV:
05333             for (k = 0; k < 4; k++) {
05334                shoveComponents[k]= *iter2++ / 65535.0;
05335             }
05336             shove8888rev(shoveComponents,0,(void *)&widget.ui);
05337             if (myswap_bytes) {
05338             iter[3] = widget.ub[0];
05339             iter[2] = widget.ub[1];
05340             iter[1] = widget.ub[2];
05341             iter[0] = widget.ub[3];
05342             } else {
05343             *(GLuint *)iter= widget.ui;
05344             }
05345             break;
05346           case GL_UNSIGNED_INT_10_10_10_2:
05347             for (k = 0; k < 4; k++) {
05348                shoveComponents[k]= *iter2++ / 65535.0;
05349             }
05350             shove1010102(shoveComponents,0,(void *)&widget.ui);
05351             if (myswap_bytes) {
05352             iter[3] = widget.ub[0];
05353             iter[2] = widget.ub[1];
05354             iter[1] = widget.ub[2];
05355             iter[0] = widget.ub[3];
05356             } else {
05357             *(GLuint *)iter= widget.ui;
05358             }
05359             break;
05360           case GL_UNSIGNED_INT_2_10_10_10_REV:
05361             for (k = 0; k < 4; k++) {
05362                shoveComponents[k]= *iter2++ / 65535.0;
05363             }
05364             shove2101010rev(shoveComponents,0,(void *)&widget.ui);
05365             if (myswap_bytes) {
05366             iter[3] = widget.ub[0];
05367             iter[2] = widget.ub[1];
05368             iter[1] = widget.ub[2];
05369             iter[0] = widget.ub[3];
05370             } else {
05371             *(GLuint *)iter= widget.ui;
05372             }
05373             break;
05374           case GL_INT:
05375           case GL_UNSIGNED_INT:
05376           case GL_FLOAT:
05377             if (type == GL_FLOAT) {
05378             if (index_format) {
05379                 widget.f = *iter2++;
05380             } else {
05381                 widget.f = *iter2++ / (float) 65535.0;
05382             }
05383             } else if (type == GL_UNSIGNED_INT) {
05384             if (index_format) {
05385                 widget.ui = *iter2++;
05386             } else {
05387                 widget.ui = (unsigned int) *iter2++ * 65537;
05388             }
05389             } else {
05390             if (index_format) {
05391                 widget.i = *iter2++;
05392             } else {
05393                 widget.i = ((unsigned int) *iter2++ * 65537)/2;
05394             }
05395             }
05396             if (myswap_bytes) {
05397             iter[3] = widget.ub[0];
05398             iter[2] = widget.ub[1];
05399             iter[1] = widget.ub[2];
05400             iter[0] = widget.ub[3];
05401             } else {
05402             iter[0] = widget.ub[0];
05403             iter[1] = widget.ub[1];
05404             iter[2] = widget.ub[2];
05405             iter[3] = widget.ub[3];
05406             }
05407             break;
05408         }
05409         iter += element_size;
05410         } /* for j */
05411         start += rowsize;
05412 #if 1
05413         /* want 'iter' pointing at start, not within, row for assertion
05414          * purposes
05415          */
05416         iter= start;
05417 #endif
05418     } /* for i */
05419 
05420     /* iterators should be one byte past end */
05421     if (!isTypePackedPixel(type)) {
05422        assert(iter2 == &oldimage[width*height*components]);
05423     }
05424     else {
05425        assert(iter2 == &oldimage[width*height*
05426                      elements_per_group(format,0)]);
05427     }
05428     assert( iter == &((GLubyte *)userdata)[rowsize*height +
05429                     psm->pack_skip_rows * rowsize +
05430                     psm->pack_skip_pixels * group_size] );
05431 
05432     } /* else */
05433 } /* empty_image() */
05434 
05435 /*--------------------------------------------------------------------------
05436  * Decimation of packed pixel types
05437  *--------------------------------------------------------------------------
05438  */
05439 static void extract332(int isSwap,
05440                const void *packedPixel, GLfloat extractComponents[])
05441 {
05442    GLubyte ubyte= *(const GLubyte *)packedPixel;
05443 
05444    isSwap= isSwap;      /* turn off warnings */
05445 
05446    /* 11100000 == 0xe0 */
05447    /* 00011100 == 0x1c */
05448    /* 00000011 == 0x03 */
05449 
05450    extractComponents[0]=   (float)((ubyte & 0xe0)  >> 5) / 7.0;
05451    extractComponents[1]=   (float)((ubyte & 0x1c)  >> 2) / 7.0; /* 7 = 2^3-1 */
05452    extractComponents[2]=   (float)((ubyte & 0x03)      ) / 3.0; /* 3 = 2^2-1 */
05453 } /* extract332() */
05454 
05455 static void shove332(const GLfloat shoveComponents[],
05456              int index, void *packedPixel)
05457 {
05458    /* 11100000 == 0xe0 */
05459    /* 00011100 == 0x1c */
05460    /* 00000011 == 0x03 */
05461 
05462    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05463    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05464    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05465 
05466    /* due to limited precision, need to round before shoving */
05467    ((GLubyte *)packedPixel)[index]  =
05468      ((GLubyte)((shoveComponents[0] * 7)+0.5)  << 5) & 0xe0;
05469    ((GLubyte *)packedPixel)[index] |=
05470      ((GLubyte)((shoveComponents[1] * 7)+0.5)  << 2) & 0x1c;
05471    ((GLubyte *)packedPixel)[index]  |=
05472      ((GLubyte)((shoveComponents[2] * 3)+0.5)      ) & 0x03;
05473 } /* shove332() */
05474 
05475 static void extract233rev(int isSwap,
05476               const void *packedPixel, GLfloat extractComponents[])
05477 {
05478    GLubyte ubyte= *(const GLubyte *)packedPixel;
05479 
05480    isSwap= isSwap;      /* turn off warnings */
05481 
05482    /* 0000,0111 == 0x07 */
05483    /* 0011,1000 == 0x38 */
05484    /* 1100,0000 == 0xC0 */
05485 
05486    extractComponents[0]= (float)((ubyte & 0x07)     ) / 7.0;
05487    extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
05488    extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
05489 } /* extract233rev() */
05490 
05491 static void shove233rev(const GLfloat shoveComponents[],
05492             int index, void *packedPixel)
05493 {
05494    /* 0000,0111 == 0x07 */
05495    /* 0011,1000 == 0x38 */
05496    /* 1100,0000 == 0xC0 */
05497 
05498    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05499    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05500    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05501 
05502    /* due to limited precision, need to round before shoving */
05503    ((GLubyte *)packedPixel)[index] =
05504      ((GLubyte)((shoveComponents[0] * 7.0)+0.5)     ) & 0x07;
05505    ((GLubyte *)packedPixel)[index]|=
05506      ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
05507    ((GLubyte *)packedPixel)[index]|=
05508      ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
05509 } /* shove233rev() */
05510 
05511 static void extract565(int isSwap,
05512                const void *packedPixel, GLfloat extractComponents[])
05513 {
05514    GLushort ushort= *(const GLushort *)packedPixel;
05515 
05516    if (isSwap) {
05517      ushort= __GLU_SWAP_2_BYTES(packedPixel);
05518    }
05519    else {
05520      ushort= *(const GLushort *)packedPixel;
05521    }
05522 
05523    /* 11111000,00000000 == 0xf800 */
05524    /* 00000111,11100000 == 0x07e0 */
05525    /* 00000000,00011111 == 0x001f */
05526 
05527    extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
05528    extractComponents[1]=(float)((ushort & 0x07e0) >>  5) / 63.0;/* 63 = 2^6-1*/
05529    extractComponents[2]=(float)((ushort & 0x001f)      ) / 31.0;
05530 } /* extract565() */
05531 
05532 static void shove565(const GLfloat shoveComponents[],
05533              int index,void *packedPixel)
05534 {
05535    /* 11111000,00000000 == 0xf800 */
05536    /* 00000111,11100000 == 0x07e0 */
05537    /* 00000000,00011111 == 0x001f */
05538 
05539    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05540    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05541    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05542 
05543    /* due to limited precision, need to round before shoving */
05544    ((GLushort *)packedPixel)[index] =
05545      ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
05546    ((GLushort *)packedPixel)[index]|=
05547      ((GLushort)((shoveComponents[1] * 63)+0.5) <<  5) & 0x07e0;
05548    ((GLushort *)packedPixel)[index]|=
05549      ((GLushort)((shoveComponents[2] * 31)+0.5)      ) & 0x001f;
05550 } /* shove565() */
05551 
05552 static void extract565rev(int isSwap,
05553               const void *packedPixel, GLfloat extractComponents[])
05554 {
05555    GLushort ushort= *(const GLushort *)packedPixel;
05556 
05557    if (isSwap) {
05558      ushort= __GLU_SWAP_2_BYTES(packedPixel);
05559    }
05560    else {
05561      ushort= *(const GLushort *)packedPixel;
05562    }
05563 
05564    /* 00000000,00011111 == 0x001f */
05565    /* 00000111,11100000 == 0x07e0 */
05566    /* 11111000,00000000 == 0xf800 */
05567 
05568    extractComponents[0]= (float)((ushort & 0x001F)  ) / 31.0;
05569    extractComponents[1]= (float)((ushort & 0x07E0) >>  5) / 63.0;
05570    extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
05571 } /* extract565rev() */
05572 
05573 static void shove565rev(const GLfloat shoveComponents[],
05574             int index,void *packedPixel)
05575 {
05576    /* 00000000,00011111 == 0x001f */
05577    /* 00000111,11100000 == 0x07e0 */
05578    /* 11111000,00000000 == 0xf800 */
05579 
05580    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05581    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05582    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05583 
05584    /* due to limited precision, need to round before shoving */
05585    ((GLushort *)packedPixel)[index] =
05586      ((GLushort)((shoveComponents[0] * 31.0)+0.5)      ) & 0x001F;
05587    ((GLushort *)packedPixel)[index]|=
05588      ((GLushort)((shoveComponents[1] * 63.0)+0.5) <<  5) & 0x07E0;
05589    ((GLushort *)packedPixel)[index]|=
05590      ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
05591 } /* shove565rev() */
05592 
05593 static void extract4444(int isSwap,const void *packedPixel,
05594             GLfloat extractComponents[])
05595 {
05596    GLushort ushort;
05597 
05598    if (isSwap) {
05599      ushort= __GLU_SWAP_2_BYTES(packedPixel);
05600    }
05601    else {
05602      ushort= *(const GLushort *)packedPixel;
05603    }
05604 
05605    /* 11110000,00000000 == 0xf000 */
05606    /* 00001111,00000000 == 0x0f00 */
05607    /* 00000000,11110000 == 0x00f0 */
05608    /* 00000000,00001111 == 0x000f */
05609 
05610    extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
05611    extractComponents[1]= (float)((ushort & 0x0f00) >>  8) / 15.0;
05612    extractComponents[2]= (float)((ushort & 0x00f0) >>  4) / 15.0;
05613    extractComponents[3]= (float)((ushort & 0x000f)  ) / 15.0;
05614 } /* extract4444() */
05615 
05616 static void shove4444(const GLfloat shoveComponents[],
05617               int index,void *packedPixel)
05618 {
05619    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05620    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05621    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05622    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05623 
05624    /* due to limited precision, need to round before shoving */
05625    ((GLushort *)packedPixel)[index] =
05626      ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
05627    ((GLushort *)packedPixel)[index]|=
05628      ((GLushort)((shoveComponents[1] * 15)+0.5) <<  8) & 0x0f00;
05629    ((GLushort *)packedPixel)[index]|=
05630      ((GLushort)((shoveComponents[2] * 15)+0.5) <<  4) & 0x00f0;
05631    ((GLushort *)packedPixel)[index]|=
05632      ((GLushort)((shoveComponents[3] * 15)+0.5)      ) & 0x000f;
05633 } /* shove4444() */
05634 
05635 static void extract4444rev(int isSwap,const void *packedPixel,
05636                GLfloat extractComponents[])
05637 {
05638    GLushort ushort;
05639 
05640    if (isSwap) {
05641      ushort= __GLU_SWAP_2_BYTES(packedPixel);
05642    }
05643    else {
05644      ushort= *(const GLushort *)packedPixel;
05645    }
05646 
05647    /* 00000000,00001111 == 0x000f */
05648    /* 00000000,11110000 == 0x00f0 */
05649    /* 00001111,00000000 == 0x0f00 */
05650    /* 11110000,00000000 == 0xf000 */
05651 
05652    /* 15 = 2^4-1 */
05653    extractComponents[0]= (float)((ushort & 0x000F)  ) / 15.0;
05654    extractComponents[1]= (float)((ushort & 0x00F0) >>  4) / 15.0;
05655    extractComponents[2]= (float)((ushort & 0x0F00) >>  8) / 15.0;
05656    extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
05657 } /* extract4444rev() */
05658 
05659 static void shove4444rev(const GLfloat shoveComponents[],
05660              int index,void *packedPixel)
05661 {
05662    /* 00000000,00001111 == 0x000f */
05663    /* 00000000,11110000 == 0x00f0 */
05664    /* 00001111,00000000 == 0x0f00 */
05665    /* 11110000,00000000 == 0xf000 */
05666 
05667    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05668    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05669    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05670    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05671 
05672    /* due to limited precision, need to round before shoving */
05673    ((GLushort *)packedPixel)[index] =
05674      ((GLushort)((shoveComponents[0] * 15)+0.5)      ) & 0x000F;
05675    ((GLushort *)packedPixel)[index]|=
05676      ((GLushort)((shoveComponents[1] * 15)+0.5) <<  4) & 0x00F0;
05677    ((GLushort *)packedPixel)[index]|=
05678      ((GLushort)((shoveComponents[2] * 15)+0.5) <<  8) & 0x0F00;
05679    ((GLushort *)packedPixel)[index]|=
05680      ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
05681 } /* shove4444rev() */
05682 
05683 static void extract5551(int isSwap,const void *packedPixel,
05684             GLfloat extractComponents[])
05685 {
05686    GLushort ushort;
05687 
05688    if (isSwap) {
05689      ushort= __GLU_SWAP_2_BYTES(packedPixel);
05690    }
05691    else {
05692      ushort= *(const GLushort *)packedPixel;
05693    }
05694 
05695    /* 11111000,00000000 == 0xf800 */
05696    /* 00000111,11000000 == 0x07c0 */
05697    /* 00000000,00111110 == 0x003e */
05698    /* 00000000,00000001 == 0x0001 */
05699 
05700    extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
05701    extractComponents[1]=(float)((ushort & 0x07c0) >>  6) / 31.0;
05702    extractComponents[2]=(float)((ushort & 0x003e) >>  1) / 31.0;
05703    extractComponents[3]=(float)((ushort & 0x0001)      );
05704 } /* extract5551() */
05705 
05706 static void shove5551(const GLfloat shoveComponents[],
05707               int index,void *packedPixel)
05708 {
05709    /* 11111000,00000000 == 0xf800 */
05710    /* 00000111,11000000 == 0x07c0 */
05711    /* 00000000,00111110 == 0x003e */
05712    /* 00000000,00000001 == 0x0001 */
05713 
05714    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05715    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05716    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05717    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05718 
05719    /* due to limited precision, need to round before shoving */
05720    ((GLushort *)packedPixel)[index]  =
05721      ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
05722    ((GLushort *)packedPixel)[index]|=
05723      ((GLushort)((shoveComponents[1] * 31)+0.5) <<  6) & 0x07c0;
05724    ((GLushort *)packedPixel)[index]|=
05725      ((GLushort)((shoveComponents[2] * 31)+0.5) <<  1) & 0x003e;
05726    ((GLushort *)packedPixel)[index]|=
05727      ((GLushort)((shoveComponents[3])+0.5)       ) & 0x0001;
05728 } /* shove5551() */
05729 
05730 static void extract1555rev(int isSwap,const void *packedPixel,
05731                GLfloat extractComponents[])
05732 {
05733    GLushort ushort;
05734 
05735    if (isSwap) {
05736      ushort= __GLU_SWAP_2_BYTES(packedPixel);
05737    }
05738    else {
05739      ushort= *(const GLushort *)packedPixel;
05740    }
05741 
05742    /* 00000000,00011111 == 0x001F */
05743    /* 00000011,11100000 == 0x03E0 */
05744    /* 01111100,00000000 == 0x7C00 */
05745    /* 10000000,00000000 == 0x8000 */
05746 
05747    /* 31 = 2^5-1 */
05748    extractComponents[0]= (float)((ushort & 0x001F)  ) / 31.0;
05749    extractComponents[1]= (float)((ushort & 0x03E0) >>  5) / 31.0;
05750    extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
05751    extractComponents[3]= (float)((ushort & 0x8000) >> 15);
05752 } /* extract1555rev() */
05753 
05754 static void shove1555rev(const GLfloat shoveComponents[],
05755              int index,void *packedPixel)
05756 {
05757    /* 00000000,00011111 == 0x001F */
05758    /* 00000011,11100000 == 0x03E0 */
05759    /* 01111100,00000000 == 0x7C00 */
05760    /* 10000000,00000000 == 0x8000 */
05761 
05762    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05763    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05764    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05765    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05766 
05767    /* due to limited precision, need to round before shoving */
05768    ((GLushort *)packedPixel)[index] =
05769      ((GLushort)((shoveComponents[0] * 31)+0.5)      ) & 0x001F;
05770    ((GLushort *)packedPixel)[index]|=
05771      ((GLushort)((shoveComponents[1] * 31)+0.5) <<  5) & 0x03E0;
05772    ((GLushort *)packedPixel)[index]|=
05773      ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
05774    ((GLushort *)packedPixel)[index]|=
05775      ((GLushort)((shoveComponents[3])+0.5)  << 15) & 0x8000;
05776 } /* shove1555rev() */
05777 
05778 static void extract8888(int isSwap,
05779             const void *packedPixel, GLfloat extractComponents[])
05780 {
05781    GLuint uint;
05782 
05783    if (isSwap) {
05784      uint= __GLU_SWAP_4_BYTES(packedPixel);
05785    }
05786    else {
05787      uint= *(const GLuint *)packedPixel;
05788    }
05789 
05790    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
05791    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
05792    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
05793    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
05794 
05795    /* 255 = 2^8-1 */
05796    extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
05797    extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
05798    extractComponents[2]= (float)((uint & 0x0000ff00) >>  8) / 255.0;
05799    extractComponents[3]= (float)((uint & 0x000000ff)      ) / 255.0;
05800 } /* extract8888() */
05801 
05802 static void shove8888(const GLfloat shoveComponents[],
05803               int index,void *packedPixel)
05804 {
05805    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
05806    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
05807    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
05808    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
05809 
05810    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05811    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05812    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05813    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05814 
05815    /* due to limited precision, need to round before shoving */
05816    ((GLuint *)packedPixel)[index] =
05817      ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
05818    ((GLuint *)packedPixel)[index]|=
05819      ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
05820    ((GLuint *)packedPixel)[index]|=
05821      ((GLuint)((shoveComponents[2] * 255)+0.5) <<  8) & 0x0000ff00;
05822    ((GLuint *)packedPixel)[index]|=
05823      ((GLuint)((shoveComponents[3] * 255)+0.5)      ) & 0x000000ff;
05824 } /* shove8888() */
05825 
05826 static void extract8888rev(int isSwap,
05827                const void *packedPixel,GLfloat extractComponents[])
05828 {
05829    GLuint uint;
05830 
05831    if (isSwap) {
05832      uint= __GLU_SWAP_4_BYTES(packedPixel);
05833    }
05834    else {
05835      uint= *(const GLuint *)packedPixel;
05836    }
05837 
05838    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
05839    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
05840    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
05841    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
05842 
05843    /* 255 = 2^8-1 */
05844    extractComponents[0]= (float)((uint & 0x000000FF)      ) / 255.0;
05845    extractComponents[1]= (float)((uint & 0x0000FF00) >>  8) / 255.0;
05846    extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
05847    extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
05848 } /* extract8888rev() */
05849 
05850 static void shove8888rev(const GLfloat shoveComponents[],
05851              int index,void *packedPixel)
05852 {
05853    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
05854    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
05855    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
05856    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
05857 
05858    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05859    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05860    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05861    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05862 
05863    /* due to limited precision, need to round before shoving */
05864    ((GLuint *)packedPixel)[index] =
05865      ((GLuint)((shoveComponents[0] * 255)+0.5)      ) & 0x000000FF;
05866    ((GLuint *)packedPixel)[index]|=
05867      ((GLuint)((shoveComponents[1] * 255)+0.5) <<  8) & 0x0000FF00;
05868    ((GLuint *)packedPixel)[index]|=
05869      ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
05870    ((GLuint *)packedPixel)[index]|=
05871      ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
05872 } /* shove8888rev() */
05873 
05874 static void extract1010102(int isSwap,
05875                const void *packedPixel,GLfloat extractComponents[])
05876 {
05877    GLuint uint;
05878 
05879    if (isSwap) {
05880      uint= __GLU_SWAP_4_BYTES(packedPixel);
05881    }
05882    else {
05883      uint= *(const GLuint *)packedPixel;
05884    }
05885 
05886    /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
05887    /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
05888    /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
05889    /* 00000000,00000000,00000000,00000011 == 0x00000003 */
05890 
05891    /* 1023 = 2^10-1 */
05892    extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
05893    extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
05894    extractComponents[2]= (float)((uint & 0x00000ffc) >>  2) / 1023.0;
05895    extractComponents[3]= (float)((uint & 0x00000003)      ) / 3.0;
05896 } /* extract1010102() */
05897 
05898 static void shove1010102(const GLfloat shoveComponents[],
05899              int index,void *packedPixel)
05900 {
05901    /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
05902    /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
05903    /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
05904    /* 00000000,00000000,00000000,00000011 == 0x00000003 */
05905 
05906    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05907    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05908    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05909    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05910 
05911    /* due to limited precision, need to round before shoving */
05912    ((GLuint *)packedPixel)[index] =
05913      ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
05914    ((GLuint *)packedPixel)[index]|=
05915      ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
05916    ((GLuint *)packedPixel)[index]|=
05917      ((GLuint)((shoveComponents[2] * 1023)+0.5) <<  2) & 0x00000ffc;
05918    ((GLuint *)packedPixel)[index]|=
05919      ((GLuint)((shoveComponents[3] * 3)+0.5)         ) & 0x00000003;
05920 } /* shove1010102() */
05921 
05922 static void extract2101010rev(int isSwap,
05923                   const void *packedPixel,
05924                   GLfloat extractComponents[])
05925 {
05926    GLuint uint;
05927 
05928    if (isSwap) {
05929      uint= __GLU_SWAP_4_BYTES(packedPixel);
05930    }
05931    else {
05932      uint= *(const GLuint *)packedPixel;
05933    }
05934 
05935    /* 00000000,00000000,00000011,11111111 == 0x000003FF */
05936    /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
05937    /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
05938    /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
05939 
05940    /* 1023 = 2^10-1 */
05941    extractComponents[0]= (float)((uint & 0x000003FF)      ) / 1023.0;
05942    extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
05943    extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
05944    extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
05945    /* 3 = 2^2-1 */
05946 } /* extract2101010rev() */
05947 
05948 static void shove2101010rev(const GLfloat shoveComponents[],
05949                 int index,void *packedPixel)
05950 {
05951    /* 00000000,00000000,00000011,11111111 == 0x000003FF */
05952    /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
05953    /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
05954    /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
05955 
05956    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
05957    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
05958    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
05959    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
05960 
05961    /* due to limited precision, need to round before shoving */
05962    ((GLuint *)packedPixel)[index] =
05963      ((GLuint)((shoveComponents[0] * 1023)+0.5)      ) & 0x000003FF;
05964    ((GLuint *)packedPixel)[index]|=
05965      ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
05966    ((GLuint *)packedPixel)[index]|=
05967      ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
05968    ((GLuint *)packedPixel)[index]|=
05969      ((GLuint)((shoveComponents[3] * 3)+0.5)    << 30) & 0xC0000000;
05970 } /* shove2101010rev() */
05971 
05972 static void scaleInternalPackedPixel(int components,
05973                      void (*extractPackedPixel)
05974                      (int, const void *,GLfloat []),
05975                      void (*shovePackedPixel)
05976                      (const GLfloat [], int, void *),
05977                      GLint widthIn,GLint heightIn,
05978                      const void *dataIn,
05979                      GLint widthOut,GLint heightOut,
05980                      void *dataOut,
05981                      GLint pixelSizeInBytes,
05982                      GLint rowSizeInBytes,GLint isSwap)
05983 {
05984     float convx;
05985     float convy;
05986     float percent;
05987 
05988     /* Max components in a format is 4, so... */
05989     float totals[4];
05990     float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
05991 
05992     float area;
05993     int i,j,k,xindex;
05994 
05995     const char *temp, *temp0;
05996     int outindex = 0;
05997 
05998     int lowx_int, highx_int, lowy_int, highy_int;
05999     float x_percent, y_percent;
06000     float lowx_float, highx_float, lowy_float, highy_float;
06001     float convy_float, convx_float;
06002     int convy_int, convx_int;
06003     int l, m;
06004     const char *left, *right;
06005 
06006     if (widthIn == widthOut*2 && heightIn == heightOut*2) {
06007     halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
06008                   widthIn, heightIn, dataIn, dataOut,
06009                   pixelSizeInBytes,rowSizeInBytes,isSwap);
06010     return;
06011     }
06012     convy = (float) heightIn/heightOut;
06013     convx = (float) widthIn/widthOut;
06014     convy_int = floor(convy);
06015     convy_float = convy - convy_int;
06016     convx_int = floor(convx);
06017     convx_float = convx - convx_int;
06018 
06019     area = convx * convy;
06020 
06021     lowy_int = 0;
06022     lowy_float = 0;
06023     highy_int = convy_int;
06024     highy_float = convy_float;
06025 
06026     for (i = 0; i < heightOut; i++) {
06027     lowx_int = 0;
06028     lowx_float = 0;
06029     highx_int = convx_int;
06030     highx_float = convx_float;
06031 
06032     for (j = 0; j < widthOut; j++) {
06033         /*
06034         ** Ok, now apply box filter to box that goes from (lowx, lowy)
06035         ** to (highx, highy) on input data into this pixel on output
06036         ** data.
06037         */
06038         totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
06039 
06040         /* calculate the value for pixels in the 1st row */
06041         xindex = lowx_int*pixelSizeInBytes;
06042         if((highy_int>lowy_int) && (highx_int>lowx_int)) {
06043 
06044         y_percent = 1-lowy_float;
06045         temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
06046         percent = y_percent * (1-lowx_float);
06047 #if 0
06048         for (k = 0, temp_index = temp; k < components;
06049              k++, temp_index += element_size) {
06050             if (myswap_bytes) {
06051             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06052             } else {
06053             totals[k] += *(const GLushort*)temp_index * percent;
06054             }
06055         }
06056 #else
06057         (*extractPackedPixel)(isSwap,temp,extractTotals);
06058         for (k = 0; k < components; k++) {
06059            totals[k]+= extractTotals[k] * percent;
06060         }
06061 #endif
06062         left = temp;
06063         for(l = lowx_int+1; l < highx_int; l++) {
06064             temp += pixelSizeInBytes;
06065 #if 0
06066             for (k = 0, temp_index = temp; k < components;
06067              k++, temp_index += element_size) {
06068             if (myswap_bytes) {
06069                 totals[k] +=
06070                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
06071             } else {
06072                 totals[k] += *(const GLushort*)temp_index * y_percent;
06073             }
06074             }
06075 #else
06076             (*extractPackedPixel)(isSwap,temp,extractTotals);
06077             for (k = 0; k < components; k++) {
06078                totals[k]+= extractTotals[k] * y_percent;
06079             }
06080 #endif
06081         }
06082         temp += pixelSizeInBytes;
06083         right = temp;
06084         percent = y_percent * highx_float;
06085 #if 0
06086         for (k = 0, temp_index = temp; k < components;
06087              k++, temp_index += element_size) {
06088             if (myswap_bytes) {
06089             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06090             } else {
06091             totals[k] += *(const GLushort*)temp_index * percent;
06092             }
06093         }
06094 #else
06095         (*extractPackedPixel)(isSwap,temp,extractTotals);
06096         for (k = 0; k < components; k++) {
06097            totals[k]+= extractTotals[k] * percent;
06098         }
06099 #endif
06100 
06101         /* calculate the value for pixels in the last row */
06102 
06103         y_percent = highy_float;
06104         percent = y_percent * (1-lowx_float);
06105         temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
06106 #if 0
06107         for (k = 0, temp_index = temp; k < components;
06108              k++, temp_index += element_size) {
06109             if (myswap_bytes) {
06110             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06111             } else {
06112             totals[k] += *(const GLushort*)temp_index * percent;
06113             }
06114         }
06115 #else
06116         (*extractPackedPixel)(isSwap,temp,extractTotals);
06117         for (k = 0; k < components; k++) {
06118            totals[k]+= extractTotals[k] * percent;
06119         }
06120 #endif
06121         for(l = lowx_int+1; l < highx_int; l++) {
06122             temp += pixelSizeInBytes;
06123 #if 0
06124             for (k = 0, temp_index = temp; k < components;
06125              k++, temp_index += element_size) {
06126             if (myswap_bytes) {
06127                 totals[k] +=
06128                  __GLU_SWAP_2_BYTES(temp_index) * y_percent;
06129             } else {
06130                 totals[k] += *(const GLushort*)temp_index * y_percent;
06131             }
06132             }
06133 #else
06134             (*extractPackedPixel)(isSwap,temp,extractTotals);
06135             for (k = 0; k < components; k++) {
06136                totals[k]+= extractTotals[k] * y_percent;
06137             }
06138 #endif
06139 
06140         }
06141         temp += pixelSizeInBytes;
06142         percent = y_percent * highx_float;
06143 #if 0
06144         for (k = 0, temp_index = temp; k < components;
06145              k++, temp_index += element_size) {
06146             if (myswap_bytes) {
06147             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06148             } else {
06149             totals[k] += *(const GLushort*)temp_index * percent;
06150             }
06151         }
06152 #else
06153         (*extractPackedPixel)(isSwap,temp,extractTotals);
06154         for (k = 0; k < components; k++) {
06155            totals[k]+= extractTotals[k] * percent;
06156         }
06157 #endif
06158 
06159         /* calculate the value for pixels in the 1st and last column */
06160         for(m = lowy_int+1; m < highy_int; m++) {
06161             left += rowSizeInBytes;
06162             right += rowSizeInBytes;
06163 #if 0
06164             for (k = 0; k < components;
06165              k++, left += element_size, right += element_size) {
06166             if (myswap_bytes) {
06167                 totals[k] +=
06168                 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
06169                 __GLU_SWAP_2_BYTES(right) * highx_float;
06170             } else {
06171                 totals[k] += *(const GLushort*)left * (1-lowx_float)
06172                        + *(const GLushort*)right * highx_float;
06173             }
06174             }
06175 #else
06176             (*extractPackedPixel)(isSwap,left,extractTotals);
06177             (*extractPackedPixel)(isSwap,right,extractMoreTotals);
06178             for (k = 0; k < components; k++) {
06179                totals[k]+= (extractTotals[k]*(1-lowx_float) +
06180                    extractMoreTotals[k]*highx_float);
06181             }
06182 #endif
06183         }
06184         } else if (highy_int > lowy_int) {
06185         x_percent = highx_float - lowx_float;
06186         percent = (1-lowy_float)*x_percent;
06187         temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
06188 #if 0
06189         for (k = 0, temp_index = temp; k < components;
06190              k++, temp_index += element_size) {
06191             if (myswap_bytes) {
06192             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06193             } else {
06194             totals[k] += *(const GLushort*)temp_index * percent;
06195             }
06196         }
06197 #else
06198         (*extractPackedPixel)(isSwap,temp,extractTotals);
06199         for (k = 0; k < components; k++) {
06200            totals[k]+= extractTotals[k] * percent;
06201         }
06202 #endif
06203         for(m = lowy_int+1; m < highy_int; m++) {
06204             temp += rowSizeInBytes;
06205 #if 0
06206             for (k = 0, temp_index = temp; k < components;
06207              k++, temp_index += element_size) {
06208             if (myswap_bytes) {
06209                 totals[k] +=
06210                 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
06211             } else {
06212                 totals[k] += *(const GLushort*)temp_index * x_percent;
06213             }
06214             }
06215 #else
06216             (*extractPackedPixel)(isSwap,temp,extractTotals);
06217             for (k = 0; k < components; k++) {
06218                totals[k]+= extractTotals[k] * x_percent;
06219             }
06220 #endif
06221         }
06222         percent = x_percent * highy_float;
06223         temp += rowSizeInBytes;
06224 #if 0
06225         for (k = 0, temp_index = temp; k < components;
06226              k++, temp_index += element_size) {
06227             if (myswap_bytes) {
06228             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06229             } else {
06230             totals[k] += *(const GLushort*)temp_index * percent;
06231             }
06232         }
06233 #else
06234         (*extractPackedPixel)(isSwap,temp,extractTotals);
06235         for (k = 0; k < components; k++) {
06236            totals[k]+= extractTotals[k] * percent;
06237         }
06238 #endif
06239         } else if (highx_int > lowx_int) {
06240         y_percent = highy_float - lowy_float;
06241         percent = (1-lowx_float)*y_percent;
06242         temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
06243 #if 0
06244         for (k = 0, temp_index = temp; k < components;
06245              k++, temp_index += element_size) {
06246             if (myswap_bytes) {
06247             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06248             } else {
06249             totals[k] += *(const GLushort*)temp_index * percent;
06250             }
06251         }
06252 #else
06253         (*extractPackedPixel)(isSwap,temp,extractTotals);
06254         for (k = 0; k < components; k++) {
06255            totals[k]+= extractTotals[k] * percent;
06256         }
06257 #endif
06258         for (l = lowx_int+1; l < highx_int; l++) {
06259             temp += pixelSizeInBytes;
06260 #if 0
06261             for (k = 0, temp_index = temp; k < components;
06262              k++, temp_index += element_size) {
06263             if (myswap_bytes) {
06264                 totals[k] +=
06265                 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
06266             } else {
06267                 totals[k] += *(const GLushort*)temp_index * y_percent;
06268             }
06269             }
06270 #else
06271         (*extractPackedPixel)(isSwap,temp,extractTotals);
06272         for (k = 0; k < components; k++) {
06273            totals[k]+= extractTotals[k] * y_percent;
06274         }
06275 #endif
06276         }
06277         temp += pixelSizeInBytes;
06278         percent = y_percent * highx_float;
06279 #if 0
06280         for (k = 0, temp_index = temp; k < components;
06281              k++, temp_index += element_size) {
06282             if (myswap_bytes) {
06283             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06284             } else {
06285             totals[k] += *(const GLushort*)temp_index * percent;
06286             }
06287         }
06288 #else
06289         (*extractPackedPixel)(isSwap,temp,extractTotals);
06290         for (k = 0; k < components; k++) {
06291            totals[k]+= extractTotals[k] * percent;
06292         }
06293 #endif
06294         } else {
06295         percent = (highy_float-lowy_float)*(highx_float-lowx_float);
06296         temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
06297 #if 0
06298         for (k = 0, temp_index = temp; k < components;
06299              k++, temp_index += element_size) {
06300             if (myswap_bytes) {
06301             totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
06302             } else {
06303             totals[k] += *(const GLushort*)temp_index * percent;
06304             }
06305         }
06306 #else
06307         (*extractPackedPixel)(isSwap,temp,extractTotals);
06308         for (k = 0; k < components; k++) {
06309            totals[k]+= extractTotals[k] * percent;
06310         }
06311 #endif
06312         }
06313 
06314         /* this is for the pixels in the body */
06315         temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
06316         for (m = lowy_int+1; m < highy_int; m++) {
06317         temp = temp0;
06318         for(l = lowx_int+1; l < highx_int; l++) {
06319 #if 0
06320             for (k = 0, temp_index = temp; k < components;
06321              k++, temp_index += element_size) {
06322             if (myswap_bytes) {
06323                 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
06324             } else {
06325                 totals[k] += *(const GLushort*)temp_index;
06326             }
06327             }
06328 #else
06329             (*extractPackedPixel)(isSwap,temp,extractTotals);
06330             for (k = 0; k < components; k++) {
06331                totals[k]+= extractTotals[k];
06332             }
06333 #endif
06334             temp += pixelSizeInBytes;
06335         }
06336         temp0 += rowSizeInBytes;
06337         }
06338 
06339         outindex = (j + (i * widthOut)); /* * (components == 1) */
06340 #if 0
06341         for (k = 0; k < components; k++) {
06342         dataout[outindex + k] = totals[k]/area;
06343         /*printf("totals[%d] = %f\n", k, totals[k]);*/
06344         }
06345 #else
06346         for (k = 0; k < components; k++) {
06347         shoveTotals[k]= totals[k]/area;
06348         }
06349         (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
06350 #endif
06351         lowx_int = highx_int;
06352         lowx_float = highx_float;
06353         highx_int += convx_int;
06354         highx_float += convx_float;
06355         if(highx_float > 1) {
06356         highx_float -= 1.0;
06357         highx_int++;
06358         }
06359     }
06360     lowy_int = highy_int;
06361     lowy_float = highy_float;
06362     highy_int += convy_int;
06363     highy_float += convy_float;
06364     if(highy_float > 1) {
06365         highy_float -= 1.0;
06366         highy_int++;
06367     }
06368     }
06369 
06370     assert(outindex == (widthOut*heightOut - 1));
06371 } /* scaleInternalPackedPixel() */
06372 
06373 /* rowSizeInBytes is at least the width (in bytes) due to padding on
06374  *  inputs; not always equal. Output NEVER has row padding.
06375  */
06376 static void halveImagePackedPixel(int components,
06377                   void (*extractPackedPixel)
06378                   (int, const void *,GLfloat []),
06379                   void (*shovePackedPixel)
06380                   (const GLfloat [],int, void *),
06381                   GLint width, GLint height,
06382                   const void *dataIn, void *dataOut,
06383                   GLint pixelSizeInBytes,
06384                   GLint rowSizeInBytes, GLint isSwap)
06385 {
06386    /* handle case where there is only 1 column/row */
06387    if (width == 1 || height == 1) {
06388       assert(!(width == 1 && height == 1)); /* can't be 1x1 */
06389       halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
06390                   width,height,dataIn,dataOut,pixelSizeInBytes,
06391                   rowSizeInBytes,isSwap);
06392       return;
06393    }
06394 
06395    {
06396       int ii, jj;
06397 
06398       int halfWidth= width / 2;
06399       int halfHeight= height / 2;
06400       const char *src= (const char *) dataIn;
06401       int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
06402       int outIndex= 0;
06403 
06404       for (ii= 0; ii< halfHeight; ii++) {
06405      for (jj= 0; jj< halfWidth; jj++) {
06406 #define BOX4 4
06407         float totals[4];    /* 4 is maximum components */
06408         float extractTotals[BOX4][4]; /* 4 is maximum components */
06409         int cc;
06410 
06411         (*extractPackedPixel)(isSwap,src,
06412                   &extractTotals[0][0]);
06413         (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
06414                   &extractTotals[1][0]);
06415         (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
06416                   &extractTotals[2][0]);
06417         (*extractPackedPixel)(isSwap,
06418                   (src+rowSizeInBytes+pixelSizeInBytes),
06419                   &extractTotals[3][0]);
06420         for (cc = 0; cc < components; cc++) {
06421            int kk;
06422 
06423            /* grab 4 pixels to average */
06424            totals[cc]= 0.0;
06425            /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
06426         *          extractTotals[2][RED]+extractTotals[3][RED];
06427         * totals[RED]/= 4.0;
06428         */
06429            for (kk = 0; kk < BOX4; kk++) {
06430           totals[cc]+= extractTotals[kk][cc];
06431            }
06432            totals[cc]/= (float)BOX4;
06433         }
06434         (*shovePackedPixel)(totals,outIndex,dataOut);
06435 
06436         outIndex++;
06437         /* skip over to next square of 4 */
06438         src+= pixelSizeInBytes + pixelSizeInBytes;
06439      }
06440      /* skip past pad bytes, if any, to get to next row */
06441      src+= padBytes;
06442 
06443      /* src is at beginning of a row here, but it's the second row of
06444       * the square block of 4 pixels that we just worked on so we
06445       * need to go one more row.
06446       * i.e.,
06447       *           OO...
06448       *       here -->OO...
06449       *   but want -->OO...
06450       *           OO...
06451       *           ...
06452       */
06453      src+= rowSizeInBytes;
06454       }
06455 
06456       /* both pointers must reach one byte after the end */
06457       assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
06458       assert(outIndex == halfWidth * halfHeight);
06459    }
06460 } /* halveImagePackedPixel() */
06461 
06462 static void halve1DimagePackedPixel(int components,
06463                     void (*extractPackedPixel)
06464                     (int, const void *,GLfloat []),
06465                     void (*shovePackedPixel)
06466                     (const GLfloat [],int, void *),
06467                     GLint width, GLint height,
06468                     const void *dataIn, void *dataOut,
06469                     GLint pixelSizeInBytes,
06470                     GLint rowSizeInBytes, GLint isSwap)
06471 {
06472    int halfWidth= width / 2;
06473    int halfHeight= height / 2;
06474    const char *src= (const char *) dataIn;
06475    int jj;
06476 
06477    assert(width == 1 || height == 1); /* must be 1D */
06478    assert(width != height); /* can't be square */
06479 
06480    if (height == 1) {   /* 1 row */
06481       int outIndex= 0;
06482 
06483       assert(width != 1);   /* widthxheight can't be 1x1 */
06484       halfHeight= 1;
06485 
06486       /* one horizontal row with possible pad bytes */
06487 
06488       for (jj= 0; jj< halfWidth; jj++) {
06489 #define BOX2 2
06490      float totals[4];   /* 4 is maximum components */
06491      float extractTotals[BOX2][4]; /* 4 is maximum components */
06492      int cc;
06493 
06494      /* average two at a time, instead of four */
06495      (*extractPackedPixel)(isSwap,src,
06496                    &extractTotals[0][0]);
06497      (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
06498                    &extractTotals[1][0]);
06499      for (cc = 0; cc < components; cc++) {
06500         int kk;
06501 
06502         /* grab 2 pixels to average */
06503         totals[cc]= 0.0;
06504         /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
06505          * totals[RED]/= 2.0;
06506          */
06507         for (kk = 0; kk < BOX2; kk++) {
06508            totals[cc]+= extractTotals[kk][cc];
06509         }
06510         totals[cc]/= (float)BOX2;
06511      }
06512      (*shovePackedPixel)(totals,outIndex,dataOut);
06513 
06514      outIndex++;
06515      /* skip over to next group of 2 */
06516      src+= pixelSizeInBytes + pixelSizeInBytes;
06517       }
06518 
06519       {
06520      int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
06521      src+= padBytes;    /* for assertion only */
06522       }
06523       assert(src == &((const char *)dataIn)[rowSizeInBytes]);
06524       assert(outIndex == halfWidth * halfHeight);
06525    }
06526    else if (width == 1) { /* 1 column */
06527       int outIndex= 0;
06528 
06529       assert(height != 1);  /* widthxheight can't be 1x1 */
06530       halfWidth= 1;
06531       /* one vertical column with possible pad bytes per row */
06532       /* average two at a time */
06533 
06534       for (jj= 0; jj< halfHeight; jj++) {
06535 #define BOX2 2
06536      float totals[4];   /* 4 is maximum components */
06537      float extractTotals[BOX2][4]; /* 4 is maximum components */
06538      int cc;
06539 
06540      /* average two at a time, instead of four */
06541      (*extractPackedPixel)(isSwap,src,
06542                    &extractTotals[0][0]);
06543      (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
06544                    &extractTotals[1][0]);
06545      for (cc = 0; cc < components; cc++) {
06546         int kk;
06547 
06548         /* grab 2 pixels to average */
06549         totals[cc]= 0.0;
06550         /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
06551          * totals[RED]/= 2.0;
06552          */
06553         for (kk = 0; kk < BOX2; kk++) {
06554            totals[cc]+= extractTotals[kk][cc];
06555         }
06556         totals[cc]/= (float)BOX2;
06557      }
06558      (*shovePackedPixel)(totals,outIndex,dataOut);
06559 
06560      outIndex++;
06561      src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
06562       }
06563 
06564       assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
06565       assert(outIndex == halfWidth * halfHeight);
06566    }
06567 } /* halve1DimagePackedPixel() */
06568 
06569 /*===========================================================================*/
06570 
06571 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
06572 /*
06573  * This section ensures that GLU 1.3 will load and run on
06574  * a GL 1.1 implementation. It dynamically resolves the
06575  * call to glTexImage3D() which might not be available.
06576  * Or is it might be supported as an extension.
06577  * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
06578  */
06579 
06580 typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
06581                           GLenum internalFormat,
06582                           GLsizei width, GLsizei height,
06583                           GLsizei depth, GLint border,
06584                           GLenum format, GLenum type,
06585                           const GLvoid *pixels );
06586 
06587 static TexImage3Dproc pTexImage3D;
06588 
06589 #ifndef WIN32
06590 #  include <dlfcn.h>
06591 #  include <sys/types.h>
06592 #else
06593 #  include <windows.h>
06594 PROC WINAPI wglGetProcAddress(LPCSTR);
06595 #endif
06596 
06597 static void gluTexImage3D( GLenum target, GLint level,
06598                GLenum internalFormat,
06599                GLsizei width, GLsizei height,
06600                GLsizei depth, GLint border,
06601                GLenum format, GLenum type,
06602                const GLvoid *pixels )
06603 {
06604    if (!pTexImage3D) {
06605 #ifdef WIN32
06606       pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
06607       if (!pTexImage3D)
06608      pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
06609 #else
06610       void *libHandle = dlopen("libgl.so", RTLD_LAZY);
06611       pTexImage3D = (TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
06612       if (!pTexImage3D)
06613      pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
06614       dlclose(libHandle);
06615 #endif
06616    }
06617 
06618    /* Now call glTexImage3D */
06619    if (pTexImage3D)
06620       pTexImage3D(target, level, internalFormat, width, height,
06621           depth, border, format, type, pixels);
06622 }
06623 
06624 #else
06625 
06626 /* Only bind to a GL 1.2 implementation: */
06627 #define gluTexImage3D glTexImage3D
06628 
06629 #endif
06630 
06631 static GLint imageSize3D(GLint width, GLint height, GLint depth,
06632              GLenum format, GLenum type)
06633 {
06634     int components= elements_per_group(format,type);
06635     int bytes_per_row=  bytes_per_element(type) * width;
06636 
06637 assert(width > 0 && height > 0 && depth > 0);
06638 assert(type != GL_BITMAP);
06639 
06640     return bytes_per_row * height * depth * components;
06641 } /* imageSize3D() */
06642 
06643 static void fillImage3D(const PixelStorageModes *psm,
06644             GLint width, GLint height, GLint depth, GLenum format,
06645             GLenum type, GLboolean indexFormat,
06646             const void *userImage, GLushort *newImage)
06647 {
06648    int myswapBytes;
06649    int components;
06650    int groupsPerLine;
06651    int elementSize;
06652    int groupSize;
06653    int rowSize;
06654    int padding;
06655    int elementsPerLine;
06656    int rowsPerImage;
06657    int imageSize;
06658    const GLubyte *start, *rowStart, *iter = NULL;
06659    GLushort *iter2;
06660    int ww, hh, dd, k;
06661 
06662    myswapBytes= psm->unpack_swap_bytes;
06663    components= elements_per_group(format,type);
06664    if (psm->unpack_row_length > 0) {
06665       groupsPerLine= psm->unpack_row_length;
06666    }
06667    else {
06668       groupsPerLine= width;
06669    }
06670    elementSize= bytes_per_element(type);
06671    groupSize= elementSize * components;
06672    if (elementSize == 1) myswapBytes= 0;
06673 
06674    /* 3dstuff begin */
06675    if (psm->unpack_image_height > 0) {
06676       rowsPerImage= psm->unpack_image_height;
06677    }
06678    else {
06679       rowsPerImage= height;
06680    }
06681    /* 3dstuff end */
06682 
06683    rowSize= groupsPerLine * groupSize;
06684    padding= rowSize % psm->unpack_alignment;
06685    if (padding) {
06686       rowSize+= psm->unpack_alignment - padding;
06687    }
06688 
06689    imageSize= rowsPerImage * rowSize; /* 3dstuff */
06690 
06691    start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
06692                  psm->unpack_skip_pixels * groupSize +
06693                  /*3dstuff*/
06694                  psm->unpack_skip_images * imageSize;
06695    elementsPerLine = width * components;
06696 
06697    iter2= newImage;
06698    for (dd= 0; dd < depth; dd++) {
06699       rowStart= start;
06700 
06701       for (hh= 0; hh < height; hh++) {
06702      iter= rowStart;
06703 
06704      for (ww= 0; ww < elementsPerLine; ww++) {
06705         Type_Widget widget;
06706         float extractComponents[4];
06707 
06708         switch(type) {
06709         case GL_UNSIGNED_BYTE:
06710           if (indexFormat) {
06711           *iter2++ = *iter;
06712           } else {
06713           *iter2++ = (*iter) * 257;
06714           }
06715           break;
06716         case GL_BYTE:
06717           if (indexFormat) {
06718           *iter2++ = *((const GLbyte *) iter);
06719           } else {
06720           /* rough approx */
06721           *iter2++ = (*((const GLbyte *) iter)) * 516;
06722           }
06723           break;
06724         case GL_UNSIGNED_BYTE_3_3_2:
06725           extract332(0,iter,extractComponents);
06726           for (k = 0; k < 3; k++) {
06727         *iter2++ = (GLushort)(extractComponents[k]*65535);
06728           }
06729           break;
06730         case GL_UNSIGNED_BYTE_2_3_3_REV:
06731           extract233rev(0,iter,extractComponents);
06732           for (k = 0; k < 3; k++) {
06733         *iter2++ = (GLushort)(extractComponents[k]*65535);
06734           }
06735           break;
06736         case GL_UNSIGNED_SHORT_5_6_5:
06737           extract565(myswapBytes,iter,extractComponents);
06738           for (k = 0; k < 3; k++) {
06739         *iter2++ = (GLushort)(extractComponents[k]*65535);
06740           }
06741           break;
06742         case GL_UNSIGNED_SHORT_5_6_5_REV:
06743           extract565rev(myswapBytes,iter,extractComponents);
06744           for (k = 0; k < 3; k++) {
06745         *iter2++ = (GLushort)(extractComponents[k]*65535);
06746           }
06747           break;
06748         case GL_UNSIGNED_SHORT_4_4_4_4:
06749           extract4444(myswapBytes,iter,extractComponents);
06750           for (k = 0; k < 4; k++) {
06751         *iter2++ = (GLushort)(extractComponents[k]*65535);
06752           }
06753           break;
06754         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
06755           extract4444rev(myswapBytes,iter,extractComponents);
06756           for (k = 0; k < 4; k++) {
06757         *iter2++ = (GLushort)(extractComponents[k]*65535);
06758           }
06759           break;
06760         case GL_UNSIGNED_SHORT_5_5_5_1:
06761           extract5551(myswapBytes,iter,extractComponents);
06762           for (k = 0; k < 4; k++) {
06763         *iter2++ = (GLushort)(extractComponents[k]*65535);
06764           }
06765           break;
06766         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
06767           extract1555rev(myswapBytes,iter,extractComponents);
06768           for (k = 0; k < 4; k++) {
06769         *iter2++ = (GLushort)(extractComponents[k]*65535);
06770           }
06771           break;
06772         case GL_UNSIGNED_SHORT:
06773         case GL_SHORT:
06774           if (myswapBytes) {
06775           widget.ub[0] = iter[1];
06776           widget.ub[1] = iter[0];
06777           } else {
06778           widget.ub[0] = iter[0];
06779           widget.ub[1] = iter[1];
06780           }
06781           if (type == GL_SHORT) {
06782           if (indexFormat) {
06783               *iter2++ = widget.s[0];
06784           } else {
06785               /* rough approx */
06786               *iter2++ = widget.s[0]*2;
06787           }
06788           } else {
06789           *iter2++ = widget.us[0];
06790           }
06791           break;
06792         case GL_UNSIGNED_INT_8_8_8_8:
06793           extract8888(myswapBytes,iter,extractComponents);
06794           for (k = 0; k < 4; k++) {
06795         *iter2++ = (GLushort)(extractComponents[k]*65535);
06796           }
06797           break;
06798         case GL_UNSIGNED_INT_8_8_8_8_REV:
06799           extract8888rev(myswapBytes,iter,extractComponents);
06800           for (k = 0; k < 4; k++) {
06801         *iter2++ = (GLushort)(extractComponents[k]*65535);
06802           }
06803           break;
06804         case GL_UNSIGNED_INT_10_10_10_2:
06805           extract1010102(myswapBytes,iter,extractComponents);
06806           for (k = 0; k < 4; k++) {
06807         *iter2++ = (GLushort)(extractComponents[k]*65535);
06808           }
06809           break;
06810         case GL_UNSIGNED_INT_2_10_10_10_REV:
06811           extract2101010rev(myswapBytes,iter,extractComponents);
06812           for (k = 0; k < 4; k++) {
06813         *iter2++ = (GLushort)(extractComponents[k]*65535);
06814           }
06815           break;
06816         case GL_INT:
06817         case GL_UNSIGNED_INT:
06818         case GL_FLOAT:
06819           if (myswapBytes) {
06820           widget.ub[0] = iter[3];
06821           widget.ub[1] = iter[2];
06822           widget.ub[2] = iter[1];
06823           widget.ub[3] = iter[0];
06824           } else {
06825           widget.ub[0] = iter[0];
06826           widget.ub[1] = iter[1];
06827           widget.ub[2] = iter[2];
06828           widget.ub[3] = iter[3];
06829           }
06830           if (type == GL_FLOAT) {
06831           if (indexFormat) {
06832               *iter2++ = widget.f;
06833           } else {
06834               *iter2++ = 65535 * widget.f;
06835           }
06836           } else if (type == GL_UNSIGNED_INT) {
06837           if (indexFormat) {
06838               *iter2++ = widget.ui;
06839           } else {
06840               *iter2++ = widget.ui >> 16;
06841           }
06842           } else {
06843           if (indexFormat) {
06844               *iter2++ = widget.i;
06845           } else {
06846               *iter2++ = widget.i >> 15;
06847           }
06848           }
06849           break;
06850         default:
06851           assert(0);
06852         }
06853 
06854         iter+= elementSize;
06855      } /* for ww */
06856      rowStart+= rowSize;
06857 
06858      iter= rowStart;    /* for assertion purposes */
06859       } /* for hh */
06860 
06861       start+= imageSize;
06862    } /* for dd */
06863 
06864    /* iterators should be one byte past end */
06865    if (!isTypePackedPixel(type)) {
06866       assert(iter2 == &newImage[width*height*depth*components]);
06867    }
06868    else {
06869       assert(iter2 == &newImage[width*height*depth*
06870                 elements_per_group(format,0)]);
06871    }
06872    assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
06873                     psm->unpack_skip_rows * rowSize +
06874                     psm->unpack_skip_pixels * groupSize +
06875                     /*3dstuff*/
06876                     psm->unpack_skip_images * imageSize] );
06877 } /* fillImage3D () */
06878 
06879 static void scaleInternal3D(GLint components,
06880                 GLint widthIn, GLint heightIn, GLint depthIn,
06881                 const GLushort *dataIn,
06882                 GLint widthOut, GLint heightOut, GLint depthOut,
06883                 GLushort *dataOut)
06884 {
06885     float x, lowx, highx, convx, halfconvx;
06886     float y, lowy, highy, convy, halfconvy;
06887     float z, lowz, highz, convz, halfconvz;
06888     float xpercent,ypercent,zpercent;
06889     float percent;
06890     /* Max components in a format is 4, so... */
06891     float totals[4];
06892     float volume;
06893     int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
06894     int temp;
06895 
06896     convz = (float) depthIn/depthOut;
06897     convy = (float) heightIn/heightOut;
06898     convx = (float) widthIn/widthOut;
06899     halfconvx = convx/2;
06900     halfconvy = convy/2;
06901     halfconvz = convz/2;
06902     for (d = 0; d < depthOut; d++) {
06903        z = convz * (d+0.5);
06904        if (depthIn > depthOut) {
06905        highz = z + halfconvz;
06906        lowz = z - halfconvz;
06907        } else {
06908        highz = z + 0.5;
06909        lowz = z - 0.5;
06910        }
06911        for (i = 0; i < heightOut; i++) {
06912        y = convy * (i+0.5);
06913        if (heightIn > heightOut) {
06914            highy = y + halfconvy;
06915            lowy = y - halfconvy;
06916        } else {
06917            highy = y + 0.5;
06918            lowy = y - 0.5;
06919        }
06920        for (j = 0; j < widthOut; j++) {
06921            x = convx * (j+0.5);
06922            if (widthIn > widthOut) {
06923            highx = x + halfconvx;
06924            lowx = x - halfconvx;
06925            } else {
06926            highx = x + 0.5;
06927            lowx = x - 0.5;
06928            }
06929 
06930            /*
06931            ** Ok, now apply box filter to box that goes from (lowx, lowy,
06932            ** lowz) to (highx, highy, highz) on input data into this pixel
06933            ** on output data.
06934            */
06935            totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
06936            volume = 0.0;
06937 
06938            z = lowz;
06939            zint = floor(z);
06940            while (z < highz) {
06941           zindex = (zint + depthIn) % depthIn;
06942           if (highz < zint+1) {
06943               zpercent = highz - z;
06944           } else {
06945               zpercent = zint+1 - z;
06946           }
06947 
06948           y = lowy;
06949           yint = floor(y);
06950           while (y < highy) {
06951               yindex = (yint + heightIn) % heightIn;
06952               if (highy < yint+1) {
06953               ypercent = highy - y;
06954               } else {
06955               ypercent = yint+1 - y;
06956               }
06957 
06958               x = lowx;
06959               xint = floor(x);
06960 
06961               while (x < highx) {
06962               xindex = (xint + widthIn) % widthIn;
06963               if (highx < xint+1) {
06964                   xpercent = highx - x;
06965               } else {
06966                   xpercent = xint+1 - x;
06967               }
06968 
06969               percent = xpercent * ypercent * zpercent;
06970               volume += percent;
06971 
06972               temp = (xindex + (yindex*widthIn) +
06973                   (zindex*widthIn*heightIn)) * components;
06974               for (k = 0; k < components; k++) {
06975                   assert(0 <= (temp+k) &&
06976                      (temp+k) <
06977                      (widthIn*heightIn*depthIn*components));
06978                   totals[k] += dataIn[temp + k] * percent;
06979               }
06980 
06981               xint++;
06982               x = xint;
06983               } /* while x */
06984 
06985               yint++;
06986               y = yint;
06987           } /* while y */
06988 
06989           zint++;
06990           z = zint;
06991            } /* while z */
06992 
06993            temp = (j + (i * widthOut) +
06994                (d*widthOut*heightOut)) * components;
06995            for (k = 0; k < components; k++) {
06996            /* totals[] should be rounded in the case of enlarging an
06997             * RGB ramp when the type is 332 or 4444
06998             */
06999            assert(0 <= (temp+k) &&
07000               (temp+k) < (widthOut*heightOut*depthOut*components));
07001            dataOut[temp + k] = (totals[k]+0.5)/volume;
07002            }
07003        } /* for j */
07004        } /* for i */
07005     } /* for d */
07006 } /* scaleInternal3D() */
07007 
07008 static void emptyImage3D(const PixelStorageModes *psm,
07009              GLint width, GLint height, GLint depth,
07010              GLenum format, GLenum type, GLboolean indexFormat,
07011              const GLushort *oldImage, void *userImage)
07012 {
07013    int myswapBytes;
07014    int components;
07015    int groupsPerLine;
07016    int elementSize;
07017    int groupSize;
07018    int rowSize;
07019    int padding;
07020    GLubyte *start, *rowStart, *iter=NULL;
07021    int elementsPerLine;
07022    const GLushort *iter2;
07023    int ii, jj, dd, k;
07024    int rowsPerImage;
07025    int imageSize;
07026 
07027    myswapBytes= psm->pack_swap_bytes;
07028    components = elements_per_group(format,type);
07029    if (psm->pack_row_length > 0) {
07030       groupsPerLine = psm->pack_row_length;
07031    }
07032    else {
07033       groupsPerLine = width;
07034    }
07035 
07036    elementSize= bytes_per_element(type);
07037    groupSize= elementSize * components;
07038    if (elementSize == 1) myswapBytes= 0;
07039 
07040    /* 3dstuff begin */
07041    if (psm->pack_image_height > 0) {
07042       rowsPerImage= psm->pack_image_height;
07043    }
07044    else {
07045       rowsPerImage= height;
07046    }
07047 
07048    /* 3dstuff end */
07049 
07050    rowSize = groupsPerLine * groupSize;
07051    padding = rowSize % psm->pack_alignment;
07052    if (padding) {
07053       rowSize+= psm->pack_alignment - padding;
07054    }
07055 
07056    imageSize= rowsPerImage * rowSize; /* 3dstuff */
07057 
07058    start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
07059                   psm->pack_skip_pixels * groupSize +
07060                   /*3dstuff*/
07061                   psm->pack_skip_images * imageSize;
07062    elementsPerLine= width * components;
07063 
07064    iter2 = oldImage;
07065    for (dd= 0; dd < depth; dd++) {
07066       rowStart= start;
07067 
07068       for (ii= 0; ii< height; ii++) {
07069      iter = rowStart;
07070 
07071      for (jj = 0; jj < elementsPerLine; jj++) {
07072         Type_Widget widget;
07073         float shoveComponents[4];
07074 
07075         switch(type){
07076         case GL_UNSIGNED_BYTE:
07077           if (indexFormat) {
07078           *iter = *iter2++;
07079           } else {
07080           *iter = *iter2++ >> 8;
07081           }
07082           break;
07083         case GL_BYTE:
07084           if (indexFormat) {
07085           *((GLbyte *) iter) = *iter2++;
07086           } else {
07087           *((GLbyte *) iter) = *iter2++ >> 9;
07088           }
07089           break;
07090         case GL_UNSIGNED_BYTE_3_3_2:
07091           for (k = 0; k < 3; k++) {
07092          shoveComponents[k]= *iter2++ / 65535.0;
07093           }
07094           shove332(shoveComponents,0,(void *)iter);
07095           break;
07096         case GL_UNSIGNED_BYTE_2_3_3_REV:
07097           for (k = 0; k < 3; k++) {
07098          shoveComponents[k]= *iter2++ / 65535.0;
07099           }
07100           shove233rev(shoveComponents,0,(void *)iter);
07101           break;
07102         case GL_UNSIGNED_SHORT_5_6_5:
07103           for (k = 0; k < 3; k++) {
07104          shoveComponents[k]= *iter2++ / 65535.0;
07105           }
07106           shove565(shoveComponents,0,(void *)&widget.us[0]);
07107           if (myswapBytes) {
07108          iter[0] = widget.ub[1];
07109          iter[1] = widget.ub[0];
07110           }
07111           else {
07112          *(GLushort *)iter = widget.us[0];
07113           }
07114           break;
07115         case GL_UNSIGNED_SHORT_5_6_5_REV:
07116           for (k = 0; k < 3; k++) {
07117          shoveComponents[k]= *iter2++ / 65535.0;
07118           }
07119           shove565rev(shoveComponents,0,(void *)&widget.us[0]);
07120           if (myswapBytes) {
07121          iter[0] = widget.ub[1];
07122          iter[1] = widget.ub[0];
07123           }
07124           else {
07125          *(GLushort *)iter = widget.us[0];
07126           }
07127           break;
07128         case GL_UNSIGNED_SHORT_4_4_4_4:
07129           for (k = 0; k < 4; k++) {
07130          shoveComponents[k]= *iter2++ / 65535.0;
07131           }
07132           shove4444(shoveComponents,0,(void *)&widget.us[0]);
07133           if (myswapBytes) {
07134          iter[0] = widget.ub[1];
07135          iter[1] = widget.ub[0];
07136           } else {
07137          *(GLushort *)iter = widget.us[0];
07138           }
07139           break;
07140         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
07141           for (k = 0; k < 4; k++) {
07142          shoveComponents[k]= *iter2++ / 65535.0;
07143           }
07144           shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
07145           if (myswapBytes) {
07146          iter[0] = widget.ub[1];
07147          iter[1] = widget.ub[0];
07148           } else {
07149          *(GLushort *)iter = widget.us[0];
07150           }
07151           break;
07152         case GL_UNSIGNED_SHORT_5_5_5_1:
07153           for (k = 0; k < 4; k++) {
07154          shoveComponents[k]= *iter2++ / 65535.0;
07155           }
07156           shove5551(shoveComponents,0,(void *)&widget.us[0]);
07157           if (myswapBytes) {
07158          iter[0] = widget.ub[1];
07159          iter[1] = widget.ub[0];
07160           } else {
07161          *(GLushort *)iter = widget.us[0];
07162           }
07163           break;
07164         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
07165           for (k = 0; k < 4; k++) {
07166          shoveComponents[k]= *iter2++ / 65535.0;
07167           }
07168           shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
07169           if (myswapBytes) {
07170          iter[0] = widget.ub[1];
07171          iter[1] = widget.ub[0];
07172           } else {
07173          *(GLushort *)iter = widget.us[0];
07174           }
07175           break;
07176         case GL_UNSIGNED_SHORT:
07177         case GL_SHORT:
07178           if (type == GL_SHORT) {
07179           if (indexFormat) {
07180               widget.s[0] = *iter2++;
07181           } else {
07182               widget.s[0] = *iter2++ >> 1;
07183           }
07184           } else {
07185           widget.us[0] = *iter2++;
07186           }
07187           if (myswapBytes) {
07188           iter[0] = widget.ub[1];
07189           iter[1] = widget.ub[0];
07190           } else {
07191           iter[0] = widget.ub[0];
07192           iter[1] = widget.ub[1];
07193           }
07194           break;
07195         case GL_UNSIGNED_INT_8_8_8_8:
07196            for (k = 0; k < 4; k++) {
07197           shoveComponents[k]= *iter2++ / 65535.0;
07198            }
07199            shove8888(shoveComponents,0,(void *)&widget.ui);
07200            if (myswapBytes) {
07201            iter[3] = widget.ub[0];
07202            iter[2] = widget.ub[1];
07203            iter[1] = widget.ub[2];
07204            iter[0] = widget.ub[3];
07205            } else {
07206            *(GLuint *)iter= widget.ui;
07207            }
07208            break;
07209         case GL_UNSIGNED_INT_8_8_8_8_REV:
07210            for (k = 0; k < 4; k++) {
07211           shoveComponents[k]= *iter2++ / 65535.0;
07212            }
07213            shove8888rev(shoveComponents,0,(void *)&widget.ui);
07214            if (myswapBytes) {
07215            iter[3] = widget.ub[0];
07216            iter[2] = widget.ub[1];
07217            iter[1] = widget.ub[2];
07218            iter[0] = widget.ub[3];
07219            } else {
07220            *(GLuint *)iter= widget.ui;
07221            }
07222            break;
07223         case GL_UNSIGNED_INT_10_10_10_2:
07224            for (k = 0; k < 4; k++) {
07225           shoveComponents[k]= *iter2++ / 65535.0;
07226            }
07227            shove1010102(shoveComponents,0,(void *)&widget.ui);
07228            if (myswapBytes) {
07229            iter[3] = widget.ub[0];
07230            iter[2] = widget.ub[1];
07231            iter[1] = widget.ub[2];
07232            iter[0] = widget.ub[3];
07233            } else {
07234            *(GLuint *)iter= widget.ui;
07235            }
07236            break;
07237         case GL_UNSIGNED_INT_2_10_10_10_REV:
07238            for (k = 0; k < 4; k++) {
07239           shoveComponents[k]= *iter2++ / 65535.0;
07240            }
07241            shove2101010rev(shoveComponents,0,(void *)&widget.ui);
07242            if (myswapBytes) {
07243            iter[3] = widget.ub[0];
07244            iter[2] = widget.ub[1];
07245            iter[1] = widget.ub[2];
07246            iter[0] = widget.ub[3];
07247            } else {
07248            *(GLuint *)iter= widget.ui;
07249            }
07250            break;
07251         case GL_INT:
07252         case GL_UNSIGNED_INT:
07253         case GL_FLOAT:
07254           if (type == GL_FLOAT) {
07255           if (indexFormat) {
07256               widget.f = *iter2++;
07257           } else {
07258               widget.f = *iter2++ / (float) 65535.0;
07259           }
07260           } else if (type == GL_UNSIGNED_INT) {
07261           if (indexFormat) {
07262               widget.ui = *iter2++;
07263           } else {
07264               widget.ui = (unsigned int) *iter2++ * 65537;
07265           }
07266           } else {
07267           if (indexFormat) {
07268               widget.i = *iter2++;
07269           } else {
07270               widget.i = ((unsigned int) *iter2++ * 65537)/2;
07271           }
07272           }
07273           if (myswapBytes) {
07274           iter[3] = widget.ub[0];
07275           iter[2] = widget.ub[1];
07276           iter[1] = widget.ub[2];
07277           iter[0] = widget.ub[3];
07278           } else {
07279           iter[0] = widget.ub[0];
07280           iter[1] = widget.ub[1];
07281           iter[2] = widget.ub[2];
07282           iter[3] = widget.ub[3];
07283           }
07284           break;
07285         default:
07286            assert(0);
07287         }
07288 
07289         iter+= elementSize;
07290      }  /* for jj */
07291 
07292      rowStart+= rowSize;
07293       } /* for ii */
07294 
07295       start+= imageSize;
07296    } /* for dd */
07297 
07298    /* iterators should be one byte past end */
07299    if (!isTypePackedPixel(type)) {
07300       assert(iter2 == &oldImage[width*height*depth*components]);
07301    }
07302    else {
07303       assert(iter2 == &oldImage[width*height*depth*
07304                 elements_per_group(format,0)]);
07305    }
07306    assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
07307                     psm->unpack_skip_rows * rowSize +
07308                     psm->unpack_skip_pixels * groupSize +
07309                     /*3dstuff*/
07310                     psm->unpack_skip_images * imageSize] );
07311 } /* emptyImage3D() */
07312 
07313 static
07314 int gluScaleImage3D(GLenum format,
07315             GLint widthIn, GLint heightIn, GLint depthIn,
07316             GLenum typeIn, const void *dataIn,
07317             GLint widthOut, GLint heightOut, GLint depthOut,
07318             GLenum typeOut, void *dataOut)
07319 {
07320    int components;
07321    GLushort *beforeImage, *afterImage;
07322    PixelStorageModes psm;
07323 
07324    if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
07325        widthOut == 0 || heightOut == 0 || depthOut == 0) {
07326       return 0;
07327    }
07328 
07329    if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
07330        widthOut < 0 || heightOut < 0 || depthOut < 0) {
07331       return GLU_INVALID_VALUE;
07332    }
07333 
07334    if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
07335        typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
07336       return GLU_INVALID_ENUM;
07337    }
07338    if (!isLegalFormatForPackedPixelType(format, typeIn)) {
07339       return GLU_INVALID_OPERATION;
07340    }
07341    if (!isLegalFormatForPackedPixelType(format, typeOut)) {
07342       return GLU_INVALID_OPERATION;
07343    }
07344 
07345    beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
07346                     GL_UNSIGNED_SHORT));
07347    if (beforeImage == NULL) {
07348        return GLU_OUT_OF_MEMORY;
07349    }
07350 
07351    afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
07352                    GL_UNSIGNED_SHORT));
07353    if (afterImage == NULL) {
07354        free(beforeImage);
07355        return GLU_OUT_OF_MEMORY;
07356    }
07357    retrieveStoreModes3D(&psm);
07358 
07359    fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
07360            dataIn, beforeImage);
07361    components = elements_per_group(format,0);
07362    scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
07363            widthOut,heightOut,depthOut,afterImage);
07364    emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
07365         is_index(format),afterImage, dataOut);
07366    free((void *) beforeImage);
07367    free((void *) afterImage);
07368 
07369    return 0;
07370 } /* gluScaleImage3D() */
07371 
07372 
07373 static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
07374              GLint internalFormat, GLenum format, GLenum type,
07375              GLint *newWidth, GLint *newHeight, GLint *newDepth)
07376 {
07377    GLint widthPowerOf2= nearestPower(width);
07378    GLint heightPowerOf2= nearestPower(height);
07379    GLint depthPowerOf2= nearestPower(depth);
07380    GLint proxyWidth ;
07381 
07382    do {
07383       /* compute level 1 width & height & depth, clamping each at 1 */
07384       GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
07385                   widthPowerOf2 >> 1 :
07386                   widthPowerOf2;
07387       GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
07388                    heightPowerOf2 >> 1 :
07389                    heightPowerOf2;
07390       GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
07391                   depthPowerOf2 >> 1 :
07392                   depthPowerOf2;
07393       GLenum proxyTarget = 0;
07394       assert(widthAtLevelOne > 0);
07395       assert(heightAtLevelOne > 0);
07396       assert(depthAtLevelOne > 0);
07397 
07398       /* does width x height x depth at level 1 & all their mipmaps fit? */
07399       if (target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D) {
07400      proxyTarget = GL_PROXY_TEXTURE_3D;
07401      gluTexImage3D(proxyTarget, 1, /* must be non-zero */
07402               internalFormat,
07403               widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
07404               0,format,type,NULL);
07405       }
07406       glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
07407       /* does it fit??? */
07408       if (proxyWidth == 0) { /* nope, so try again with these sizes */
07409      if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
07410          depthPowerOf2 == 1) {
07411         *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
07412         return;
07413      }
07414      widthPowerOf2= widthAtLevelOne;
07415      heightPowerOf2= heightAtLevelOne;
07416      depthPowerOf2= depthAtLevelOne;
07417       }
07418       /* else it does fit */
07419    } while (proxyWidth == 0);
07420    /* loop must terminate! */
07421 
07422    /* return the width & height at level 0 that fits */
07423    *newWidth= widthPowerOf2;
07424    *newHeight= heightPowerOf2;
07425    *newDepth= depthPowerOf2;
07426 /*printf("Proxy Textures\n");*/
07427 } /* closestFit3D() */
07428 
07429 static void halveImagePackedPixelSlice(int components,
07430                        void (*extractPackedPixel)
07431                        (int, const void *,GLfloat []),
07432                        void (*shovePackedPixel)
07433                        (const GLfloat [],int, void *),
07434                        GLint width, GLint height, GLint depth,
07435                        const void *dataIn, void *dataOut,
07436                        GLint pixelSizeInBytes,
07437                        GLint rowSizeInBytes,
07438                        GLint imageSizeInBytes,
07439                        GLint isSwap)
07440 {
07441    int ii, jj;
07442    int halfWidth= width / 2;
07443    int halfHeight= height / 2;
07444    int halfDepth= depth / 2;
07445    const char *src= (const char *)dataIn;
07446    int outIndex= 0;
07447 
07448    assert((width == 1 || height == 1) && depth >= 2);
07449 
07450    if (width == height) {   /* a 1-pixel column viewed from top */
07451       assert(width == 1 && height == 1);
07452       assert(depth >= 2);
07453 
07454       for (ii= 0; ii< halfDepth; ii++) {
07455      float totals[4];
07456      float extractTotals[BOX2][4];
07457      int cc;
07458 
07459      (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
07460      (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
07461                    &extractTotals[1][0]);
07462      for (cc = 0; cc < components; cc++) {
07463         int kk;
07464 
07465         /* average 2 pixels since only a column */
07466         totals[cc]= 0.0;
07467         /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
07468          * totals[RED]/= 2.0;
07469          */
07470         for (kk = 0; kk < BOX2; kk++) {
07471           totals[cc]+= extractTotals[kk][cc];
07472         }
07473         totals[cc]/= (float)BOX2;
07474      } /* for cc */
07475 
07476      (*shovePackedPixel)(totals,outIndex,dataOut);
07477      outIndex++;
07478      /* skip over to next group of 2 */
07479      src+= imageSizeInBytes + imageSizeInBytes;
07480       } /* for ii */
07481    }
07482    else if (height == 1) {  /* horizontal slice viewed from top */
07483       assert(width != 1);
07484 
07485       for (ii= 0; ii< halfDepth; ii++) {
07486      for (jj= 0; jj< halfWidth; jj++) {
07487          float totals[4];
07488          float extractTotals[BOX4][4];
07489          int cc;
07490 
07491          (*extractPackedPixel)(isSwap,src,
07492                    &extractTotals[0][0]);
07493          (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
07494                    &extractTotals[1][0]);
07495          (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
07496                    &extractTotals[2][0]);
07497          (*extractPackedPixel)(isSwap,
07498                    (src+imageSizeInBytes+pixelSizeInBytes),
07499                    &extractTotals[3][0]);
07500          for (cc = 0; cc < components; cc++) {
07501         int kk;
07502 
07503         /* grab 4 pixels to average */
07504         totals[cc]= 0.0;
07505         /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
07506          *      extractTotals[2][RED]+extractTotals[3][RED];
07507          * totals[RED]/= 4.0;
07508          */
07509         for (kk = 0; kk < BOX4; kk++) {
07510            totals[cc]+= extractTotals[kk][cc];
07511         }
07512         totals[cc]/= (float)BOX4;
07513          }
07514          (*shovePackedPixel)(totals,outIndex,dataOut);
07515 
07516          outIndex++;
07517          /* skip over to next horizontal square of 4 */
07518          src+= imageSizeInBytes + imageSizeInBytes;
07519      }
07520       }
07521 
07522       /* assert() */
07523    }
07524    else if (width == 1) {   /* vertical slice viewed from top */
07525       assert(height != 1);
07526 
07527       for (ii= 0; ii< halfDepth; ii++) {
07528      for (jj= 0; jj< halfHeight; jj++) {
07529         float totals[4];
07530         float extractTotals[BOX4][4];
07531         int cc;
07532 
07533         (*extractPackedPixel)(isSwap,src,
07534                   &extractTotals[0][0]);
07535         (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
07536                   &extractTotals[1][0]);
07537         (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
07538                   &extractTotals[2][0]);
07539         (*extractPackedPixel)(isSwap,
07540                   (src+imageSizeInBytes+rowSizeInBytes),
07541                   &extractTotals[3][0]);
07542         for (cc = 0; cc < components; cc++) {
07543            int kk;
07544 
07545            /* grab 4 pixels to average */
07546            totals[cc]= 0.0;
07547            /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
07548         *          extractTotals[2][RED]+extractTotals[3][RED];
07549         * totals[RED]/= 4.0;
07550         */
07551            for (kk = 0; kk < BOX4; kk++) {
07552           totals[cc]+= extractTotals[kk][cc];
07553            }
07554            totals[cc]/= (float)BOX4;
07555         }
07556         (*shovePackedPixel)(totals,outIndex,dataOut);
07557 
07558         outIndex++;
07559 
07560         /* skip over to next vertical square of 4 */
07561         src+= imageSizeInBytes + imageSizeInBytes;
07562      }
07563       }
07564       /* assert() */
07565    }
07566 
07567 } /* halveImagePackedPixelSlice() */
07568 
07569 static void halveImagePackedPixel3D(int components,
07570                     void (*extractPackedPixel)
07571                     (int, const void *,GLfloat []),
07572                     void (*shovePackedPixel)
07573                     (const GLfloat [],int, void *),
07574                     GLint width, GLint height, GLint depth,
07575                     const void *dataIn, void *dataOut,
07576                     GLint pixelSizeInBytes,
07577                     GLint rowSizeInBytes,
07578                     GLint imageSizeInBytes,
07579                     GLint isSwap)
07580 {
07581    if (depth == 1) {
07582       assert(1 <= width && 1 <= height);
07583 
07584       halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
07585                 width,height,dataIn,dataOut,pixelSizeInBytes,
07586                 rowSizeInBytes,isSwap);
07587       return;
07588    }
07589    /* a horizontal or vertical slice viewed from top */
07590    else if (width == 1 || height == 1) {
07591       assert(1 <= depth);
07592 
07593       halveImagePackedPixelSlice(components,
07594                  extractPackedPixel,shovePackedPixel,
07595                  width, height, depth, dataIn, dataOut,
07596                  pixelSizeInBytes, rowSizeInBytes,
07597                  imageSizeInBytes, isSwap);
07598       return;
07599    }
07600    {
07601       int ii, jj, dd;
07602 
07603       int halfWidth= width / 2;
07604       int halfHeight= height / 2;
07605       int halfDepth= depth / 2;
07606       const char *src= (const char *) dataIn;
07607       int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
07608       int outIndex= 0;
07609 
07610       for (dd= 0; dd < halfDepth; dd++) {
07611      for (ii= 0; ii< halfHeight; ii++) {
07612         for (jj= 0; jj< halfWidth; jj++) {
07613 #define BOX8 8
07614            float totals[4]; /* 4 is maximum components */
07615            float extractTotals[BOX8][4]; /* 4 is maximum components */
07616            int cc;
07617 
07618            (*extractPackedPixel)(isSwap,src,
07619                      &extractTotals[0][0]);
07620            (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
07621                      &extractTotals[1][0]);
07622            (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
07623                      &extractTotals[2][0]);
07624            (*extractPackedPixel)(isSwap,
07625                      (src+rowSizeInBytes+pixelSizeInBytes),
07626                      &extractTotals[3][0]);
07627 
07628            (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
07629                      &extractTotals[4][0]);
07630            (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
07631                      &extractTotals[5][0]);
07632            (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
07633                      &extractTotals[6][0]);
07634            (*extractPackedPixel)(isSwap,
07635                      (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
07636                      &extractTotals[7][0]);
07637            for (cc = 0; cc < components; cc++) {
07638           int kk;
07639 
07640           /* grab 8 pixels to average */
07641           totals[cc]= 0.0;
07642           /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
07643            *          extractTotals[2][RED]+extractTotals[3][RED]+
07644            *          extractTotals[4][RED]+extractTotals[5][RED]+
07645            *          extractTotals[6][RED]+extractTotals[7][RED];
07646            * totals[RED]/= 8.0;
07647            */
07648           for (kk = 0; kk < BOX8; kk++) {
07649              totals[cc]+= extractTotals[kk][cc];
07650           }
07651           totals[cc]/= (float)BOX8;
07652            }
07653            (*shovePackedPixel)(totals,outIndex,dataOut);
07654 
07655            outIndex++;
07656            /* skip over to next square of 4 */
07657            src+= pixelSizeInBytes + pixelSizeInBytes;
07658         }
07659         /* skip past pad bytes, if any, to get to next row */
07660         src+= padBytes;
07661 
07662         /* src is at beginning of a row here, but it's the second row of
07663          * the square block of 4 pixels that we just worked on so we
07664          * need to go one more row.
07665          * i.e.,
07666          *           OO...
07667          *       here -->OO...
07668          *       but want -->OO...
07669          *           OO...
07670          *           ...
07671          */
07672         src+= rowSizeInBytes;
07673      }
07674 
07675      src+= imageSizeInBytes;
07676       } /* for dd */
07677 
07678       /* both pointers must reach one byte after the end */
07679       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
07680       assert(outIndex == halfWidth * halfHeight * halfDepth);
07681    } /* for dd */
07682 
07683 } /* halveImagePackedPixel3D() */
07684 
07685 static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
07686                       GLsizei width,
07687                       GLsizei height,
07688                       GLsizei depth,
07689                       GLsizei widthPowerOf2,
07690                       GLsizei heightPowerOf2,
07691                       GLsizei depthPowerOf2,
07692                       GLenum format, GLenum type,
07693                       GLint userLevel,
07694                       GLint baseLevel,GLint maxLevel,
07695                       const void *data)
07696 {
07697    GLint newWidth, newHeight, newDepth;
07698    GLint level, levels;
07699    const void *usersImage;
07700    void *srcImage, *dstImage;
07701    __GLU_INIT_SWAP_IMAGE;
07702    GLint memReq;
07703    GLint cmpts;
07704 
07705    GLint myswapBytes, groupsPerLine, elementSize, groupSize;
07706    GLint rowsPerImage, imageSize;
07707    GLint rowSize, padding;
07708    PixelStorageModes psm;
07709 
07710    assert(checkMipmapArgs(internalFormat,format,type) == 0);
07711    assert(width >= 1 && height >= 1 && depth >= 1);
07712    assert(type != GL_BITMAP);
07713 
07714    srcImage = dstImage = NULL;
07715 
07716    newWidth= widthPowerOf2;
07717    newHeight= heightPowerOf2;
07718    newDepth= depthPowerOf2;
07719    levels = computeLog(newWidth);
07720    level = computeLog(newHeight);
07721    if (level > levels) levels=level;
07722    level = computeLog(newDepth);
07723    if (level > levels) levels=level;
07724 
07725    levels+= userLevel;
07726 
07727    retrieveStoreModes3D(&psm);
07728    myswapBytes = psm.unpack_swap_bytes;
07729    cmpts = elements_per_group(format,type);
07730    if (psm.unpack_row_length > 0) {
07731        groupsPerLine = psm.unpack_row_length;
07732    } else {
07733        groupsPerLine = width;
07734    }
07735 
07736    elementSize = bytes_per_element(type);
07737    groupSize = elementSize * cmpts;
07738    if (elementSize == 1) myswapBytes = 0;
07739 
07740    /* 3dstuff begin */
07741    if (psm.unpack_image_height > 0) {
07742       rowsPerImage= psm.unpack_image_height;
07743    }
07744    else {
07745       rowsPerImage= height;
07746    }
07747 
07748    /* 3dstuff end */
07749    rowSize = groupsPerLine * groupSize;
07750    padding = (rowSize % psm.unpack_alignment);
07751    if (padding) {
07752        rowSize += psm.unpack_alignment - padding;
07753    }
07754 
07755    imageSize= rowsPerImage * rowSize; /* 3dstuff */
07756 
07757    usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
07758                   psm.unpack_skip_pixels * groupSize +
07759                   /* 3dstuff */
07760                   psm.unpack_skip_images * imageSize;
07761 
07762    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
07763    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
07764    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
07765    glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
07766    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
07767 
07768    level = userLevel;
07769 
07770    if (width == newWidth && height == newHeight && depth == newDepth) {
07771        /* Use usersImage for level userLevel */
07772        if (baseLevel <= level && level <= maxLevel) {
07773       gluTexImage3D(target, level, internalFormat, width,
07774                height, depth, 0, format, type,
07775                usersImage);
07776        }
07777        if(levels == 0) { /* we're done. clean up and return */
07778      glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
07779      glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
07780      glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
07781      glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
07782      glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
07783      glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
07784      glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
07785      return 0;
07786        }
07787        {
07788       int nextWidth= newWidth/2;
07789       int nextHeight= newHeight/2;
07790       int nextDepth= newDepth/2;
07791 
07792       /* clamp to 1 */
07793       if (nextWidth < 1) nextWidth= 1;
07794       if (nextHeight < 1) nextHeight= 1;
07795       if (nextDepth < 1) nextDepth= 1;
07796        memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
07797        }
07798        switch(type) {
07799        case GL_UNSIGNED_BYTE:
07800      dstImage = (GLubyte *)malloc(memReq);
07801      break;
07802        case GL_BYTE:
07803      dstImage = (GLbyte *)malloc(memReq);
07804      break;
07805        case GL_UNSIGNED_SHORT:
07806      dstImage = (GLushort *)malloc(memReq);
07807      break;
07808        case GL_SHORT:
07809      dstImage = (GLshort *)malloc(memReq);
07810      break;
07811        case GL_UNSIGNED_INT:
07812      dstImage = (GLuint *)malloc(memReq);
07813      break;
07814        case GL_INT:
07815      dstImage = (GLint *)malloc(memReq);
07816      break;
07817        case GL_FLOAT:
07818      dstImage = (GLfloat *)malloc(memReq);
07819      break;
07820        case GL_UNSIGNED_BYTE_3_3_2:
07821        case GL_UNSIGNED_BYTE_2_3_3_REV:
07822      dstImage = (GLubyte *)malloc(memReq);
07823      break;
07824        case GL_UNSIGNED_SHORT_5_6_5:
07825        case GL_UNSIGNED_SHORT_5_6_5_REV:
07826        case GL_UNSIGNED_SHORT_4_4_4_4:
07827        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
07828        case GL_UNSIGNED_SHORT_5_5_5_1:
07829        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
07830      dstImage = (GLushort *)malloc(memReq);
07831      break;
07832        case GL_UNSIGNED_INT_8_8_8_8:
07833        case GL_UNSIGNED_INT_8_8_8_8_REV:
07834        case GL_UNSIGNED_INT_10_10_10_2:
07835        case GL_UNSIGNED_INT_2_10_10_10_REV:
07836      dstImage = (GLuint *)malloc(memReq);
07837      break;
07838        default:
07839      return GLU_INVALID_ENUM; /* assertion */
07840        }
07841        if (dstImage == NULL) {
07842      glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
07843      glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
07844      glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
07845      glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
07846      glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
07847      glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
07848      glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
07849      return GLU_OUT_OF_MEMORY;
07850        }
07851        else
07852      switch(type) {
07853      case GL_UNSIGNED_BYTE:
07854        if (depth > 1) {
07855          halveImage3D(cmpts,extractUbyte,shoveUbyte,
07856               width,height,depth,
07857               usersImage,dstImage,elementSize,groupSize,rowSize,
07858               imageSize,myswapBytes);
07859        }
07860        else {
07861          halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
07862                   elementSize,rowSize,groupSize);
07863        }
07864        break;
07865      case GL_BYTE:
07866        if (depth > 1) {
07867        halveImage3D(cmpts,extractSbyte,shoveSbyte,
07868             width,height,depth,
07869             usersImage,dstImage,elementSize,groupSize,rowSize,
07870             imageSize,myswapBytes);
07871        }
07872        else {
07873          halveImage_byte(cmpts,width,height,usersImage,dstImage,
07874                  elementSize,rowSize,groupSize);
07875        }
07876        break;
07877      case GL_UNSIGNED_SHORT:
07878        if (depth > 1) {
07879        halveImage3D(cmpts,extractUshort,shoveUshort,
07880             width,height,depth,
07881             usersImage,dstImage,elementSize,groupSize,rowSize,
07882             imageSize,myswapBytes);
07883        }
07884        else {
07885          halveImage_ushort(cmpts,width,height,usersImage,dstImage,
07886                    elementSize,rowSize,groupSize,myswapBytes);
07887        }
07888        break;
07889      case GL_SHORT:
07890        if (depth > 1) {
07891        halveImage3D(cmpts,extractSshort,shoveSshort,
07892             width,height,depth,
07893             usersImage,dstImage,elementSize,groupSize,rowSize,
07894             imageSize,myswapBytes);
07895        }
07896        else {
07897          halveImage_short(cmpts,width,height,usersImage,dstImage,
07898                   elementSize,rowSize,groupSize,myswapBytes);
07899        }
07900        break;
07901      case GL_UNSIGNED_INT:
07902        if (depth > 1) {
07903        halveImage3D(cmpts,extractUint,shoveUint,
07904             width,height,depth,
07905             usersImage,dstImage,elementSize,groupSize,rowSize,
07906             imageSize,myswapBytes);
07907        }
07908        else {
07909          halveImage_uint(cmpts,width,height,usersImage,dstImage,
07910                  elementSize,rowSize,groupSize,myswapBytes);
07911        }
07912        break;
07913      case GL_INT:
07914        if (depth > 1) {
07915        halveImage3D(cmpts,extractSint,shoveSint,
07916             width,height,depth,
07917             usersImage,dstImage,elementSize,groupSize,rowSize,
07918             imageSize,myswapBytes);
07919        }
07920        else {
07921          halveImage_int(cmpts,width,height,usersImage,dstImage,
07922                 elementSize,rowSize,groupSize,myswapBytes);
07923        }
07924        break;
07925      case GL_FLOAT:
07926        if (depth > 1 ) {
07927        halveImage3D(cmpts,extractFloat,shoveFloat,
07928             width,height,depth,
07929             usersImage,dstImage,elementSize,groupSize,rowSize,
07930             imageSize,myswapBytes);
07931        }
07932        else {
07933          halveImage_float(cmpts,width,height,usersImage,dstImage,
07934                   elementSize,rowSize,groupSize,myswapBytes);
07935        }
07936        break;
07937      case GL_UNSIGNED_BYTE_3_3_2:
07938        assert(format == GL_RGB);
07939        halveImagePackedPixel3D(3,extract332,shove332,
07940                    width,height,depth,usersImage,dstImage,
07941                    elementSize,rowSize,imageSize,myswapBytes);
07942        break;
07943      case GL_UNSIGNED_BYTE_2_3_3_REV:
07944        assert(format == GL_RGB);
07945        halveImagePackedPixel3D(3,extract233rev,shove233rev,
07946                    width,height,depth,usersImage,dstImage,
07947                    elementSize,rowSize,imageSize,myswapBytes);
07948        break;
07949      case GL_UNSIGNED_SHORT_5_6_5:
07950        halveImagePackedPixel3D(3,extract565,shove565,
07951                    width,height,depth,usersImage,dstImage,
07952                    elementSize,rowSize,imageSize,myswapBytes);
07953        break;
07954      case GL_UNSIGNED_SHORT_5_6_5_REV:
07955        halveImagePackedPixel3D(3,extract565rev,shove565rev,
07956                    width,height,depth,usersImage,dstImage,
07957                    elementSize,rowSize,imageSize,myswapBytes);
07958        break;
07959      case GL_UNSIGNED_SHORT_4_4_4_4:
07960        halveImagePackedPixel3D(4,extract4444,shove4444,
07961                    width,height,depth,usersImage,dstImage,
07962                    elementSize,rowSize,imageSize,myswapBytes);
07963        break;
07964      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
07965        halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
07966                    width,height,depth,usersImage,dstImage,
07967                    elementSize,rowSize,imageSize,myswapBytes);
07968        break;
07969      case GL_UNSIGNED_SHORT_5_5_5_1:
07970        halveImagePackedPixel3D(4,extract5551,shove5551,
07971                    width,height,depth,usersImage,dstImage,
07972                    elementSize,rowSize,imageSize,myswapBytes);
07973        break;
07974      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
07975        halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
07976                    width,height,depth,usersImage,dstImage,
07977                    elementSize,rowSize,imageSize,myswapBytes);
07978        break;
07979      case GL_UNSIGNED_INT_8_8_8_8:
07980        halveImagePackedPixel3D(4,extract8888,shove8888,
07981                    width,height,depth,usersImage,dstImage,
07982                    elementSize,rowSize,imageSize,myswapBytes);
07983        break;
07984      case GL_UNSIGNED_INT_8_8_8_8_REV:
07985        halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
07986                    width,height,depth,usersImage,dstImage,
07987                    elementSize,rowSize,imageSize,myswapBytes);
07988        break;
07989      case GL_UNSIGNED_INT_10_10_10_2:
07990        halveImagePackedPixel3D(4,extract1010102,shove1010102,
07991                    width,height,depth,usersImage,dstImage,
07992                    elementSize,rowSize,imageSize,myswapBytes);
07993        break;
07994      case GL_UNSIGNED_INT_2_10_10_10_REV:
07995        halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
07996                    width,height,depth,usersImage,dstImage,
07997                    elementSize,rowSize,imageSize,myswapBytes);
07998        break;
07999      default:
08000        assert(0);
08001        break;
08002      }
08003        newWidth = width/2;
08004        newHeight = height/2;
08005        newDepth = depth/2;
08006        /* clamp to 1 */
08007        if (newWidth < 1) newWidth= 1;
08008        if (newHeight < 1) newHeight= 1;
08009        if (newDepth < 1) newDepth= 1;
08010 
08011        myswapBytes = 0;
08012        rowSize = newWidth * groupSize;
08013        imageSize= rowSize * newHeight; /* 3dstuff */
08014        memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
08015        /* Swap srcImage and dstImage */
08016        __GLU_SWAP_IMAGE(srcImage,dstImage);
08017        switch(type) {
08018        case GL_UNSIGNED_BYTE:
08019      dstImage = (GLubyte *)malloc(memReq);
08020      break;
08021        case GL_BYTE:
08022      dstImage = (GLbyte *)malloc(memReq);
08023      break;
08024        case GL_UNSIGNED_SHORT:
08025      dstImage = (GLushort *)malloc(memReq);
08026      break;
08027        case GL_SHORT:
08028      dstImage = (GLshort *)malloc(memReq);
08029      break;
08030        case GL_UNSIGNED_INT:
08031      dstImage = (GLuint *)malloc(memReq);
08032      break;
08033        case GL_INT:
08034      dstImage = (GLint *)malloc(memReq);
08035      break;
08036        case GL_FLOAT:
08037      dstImage = (GLfloat *)malloc(memReq);
08038      break;
08039        case GL_UNSIGNED_BYTE_3_3_2:
08040        case GL_UNSIGNED_BYTE_2_3_3_REV:
08041      dstImage = (GLubyte *)malloc(memReq);
08042      break;
08043        case GL_UNSIGNED_SHORT_5_6_5:
08044        case GL_UNSIGNED_SHORT_5_6_5_REV:
08045        case GL_UNSIGNED_SHORT_4_4_4_4:
08046        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
08047        case GL_UNSIGNED_SHORT_5_5_5_1:
08048        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
08049      dstImage = (GLushort *)malloc(memReq);
08050      break;
08051        case GL_UNSIGNED_INT_8_8_8_8:
08052        case GL_UNSIGNED_INT_8_8_8_8_REV:
08053        case GL_UNSIGNED_INT_10_10_10_2:
08054        case GL_UNSIGNED_INT_2_10_10_10_REV:
08055      dstImage = (GLuint *)malloc(memReq);
08056      break;
08057        default:
08058      return GLU_INVALID_ENUM; /* assertion */
08059        }
08060        if (dstImage == NULL) {
08061      glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
08062      glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
08063      glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
08064      glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
08065      glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
08066      glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
08067      glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
08068      return GLU_OUT_OF_MEMORY;
08069        }
08070        /* level userLevel+1 is in srcImage; level userLevel already saved */
08071        level = userLevel+1;
08072    } else {/* user's image is *not* nice power-of-2 sized square */
08073        memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
08074        switch(type) {
08075        case GL_UNSIGNED_BYTE:
08076            dstImage = (GLubyte *)malloc(memReq);
08077            break;
08078        case GL_BYTE:
08079            dstImage = (GLbyte *)malloc(memReq);
08080            break;
08081        case GL_UNSIGNED_SHORT:
08082            dstImage = (GLushort *)malloc(memReq);
08083            break;
08084        case GL_SHORT:
08085            dstImage = (GLshort *)malloc(memReq);
08086            break;
08087        case GL_UNSIGNED_INT:
08088            dstImage = (GLuint *)malloc(memReq);
08089            break;
08090        case GL_INT:
08091            dstImage = (GLint *)malloc(memReq);
08092            break;
08093        case GL_FLOAT:
08094            dstImage = (GLfloat *)malloc(memReq);
08095            break;
08096        case GL_UNSIGNED_BYTE_3_3_2:
08097        case GL_UNSIGNED_BYTE_2_3_3_REV:
08098            dstImage = (GLubyte *)malloc(memReq);
08099            break;
08100        case GL_UNSIGNED_SHORT_5_6_5:
08101        case GL_UNSIGNED_SHORT_5_6_5_REV:
08102        case GL_UNSIGNED_SHORT_4_4_4_4:
08103        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
08104        case GL_UNSIGNED_SHORT_5_5_5_1:
08105        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
08106            dstImage = (GLushort *)malloc(memReq);
08107            break;
08108        case GL_UNSIGNED_INT_8_8_8_8:
08109        case GL_UNSIGNED_INT_8_8_8_8_REV:
08110        case GL_UNSIGNED_INT_10_10_10_2:
08111        case GL_UNSIGNED_INT_2_10_10_10_REV:
08112            dstImage = (GLuint *)malloc(memReq);
08113            break;
08114        default:
08115            return GLU_INVALID_ENUM; /* assertion */
08116        }
08117 
08118        if (dstImage == NULL) {
08119        glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
08120        glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
08121        glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
08122        glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
08123        glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
08124        glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
08125        glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
08126        return GLU_OUT_OF_MEMORY;
08127        }
08128        /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
08129        width,height,depth,newWidth,newHeight,newDepth);*/
08130 
08131        gluScaleImage3D(format, width, height, depth, type, usersImage,
08132                newWidth, newHeight, newDepth, type, dstImage);
08133 
08134        myswapBytes = 0;
08135        rowSize = newWidth * groupSize;
08136        imageSize = rowSize * newHeight; /* 3dstuff */
08137        /* Swap dstImage and srcImage */
08138        __GLU_SWAP_IMAGE(srcImage,dstImage);
08139 
08140        if(levels != 0) { /* use as little memory as possible */
08141      {
08142         int nextWidth= newWidth/2;
08143         int nextHeight= newHeight/2;
08144         int nextDepth= newDepth/2;
08145         if (nextWidth < 1) nextWidth= 1;
08146         if (nextHeight < 1) nextHeight= 1;
08147         if (nextDepth < 1) nextDepth= 1;
08148 
08149      memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
08150      }
08151      switch(type) {
08152      case GL_UNSIGNED_BYTE:
08153        dstImage = (GLubyte *)malloc(memReq);
08154        break;
08155      case GL_BYTE:
08156        dstImage = (GLbyte *)malloc(memReq);
08157        break;
08158      case GL_UNSIGNED_SHORT:
08159        dstImage = (GLushort *)malloc(memReq);
08160        break;
08161      case GL_SHORT:
08162        dstImage = (GLshort *)malloc(memReq);
08163        break;
08164      case GL_UNSIGNED_INT:
08165        dstImage = (GLuint *)malloc(memReq);
08166        break;
08167      case GL_INT:
08168        dstImage = (GLint *)malloc(memReq);
08169        break;
08170      case GL_FLOAT:
08171        dstImage = (GLfloat *)malloc(memReq);
08172        break;
08173      case GL_UNSIGNED_BYTE_3_3_2:
08174      case GL_UNSIGNED_BYTE_2_3_3_REV:
08175        dstImage = (GLubyte *)malloc(memReq);
08176        break;
08177      case GL_UNSIGNED_SHORT_5_6_5:
08178      case GL_UNSIGNED_SHORT_5_6_5_REV:
08179      case GL_UNSIGNED_SHORT_4_4_4_4:
08180      case GL_UNSIGNED_SHORT_4_4_4_4_REV:
08181      case GL_UNSIGNED_SHORT_5_5_5_1:
08182      case GL_UNSIGNED_SHORT_1_5_5_5_REV:
08183        dstImage = (GLushort *)malloc(memReq);
08184        break;
08185      case GL_UNSIGNED_INT_8_8_8_8:
08186      case GL_UNSIGNED_INT_8_8_8_8_REV:
08187      case GL_UNSIGNED_INT_10_10_10_2:
08188      case GL_UNSIGNED_INT_2_10_10_10_REV:
08189        dstImage = (GLuint *)malloc(memReq);
08190        break;
08191      default:
08192        return GLU_INVALID_ENUM; /* assertion */
08193      }
08194      if (dstImage == NULL) {
08195        glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
08196        glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
08197        glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
08198        glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
08199        glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
08200        glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
08201        glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
08202        return GLU_OUT_OF_MEMORY;
08203      }
08204        }
08205        /* level userLevel is in srcImage; nothing saved yet */
08206        level = userLevel;
08207    }
08208 
08209    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
08210    if (baseLevel <= level && level <= maxLevel) {
08211      gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
08212           0,format, type, (void *)srcImage);
08213    }
08214    level++; /* update current level for the loop */
08215    for (; level <= levels; level++) {
08216        switch(type) {
08217        case GL_UNSIGNED_BYTE:
08218            if (newDepth > 1) {
08219            halveImage3D(cmpts,extractUbyte,shoveUbyte,
08220                 newWidth,newHeight,newDepth,
08221                 srcImage,dstImage,elementSize,groupSize,rowSize,
08222                 imageSize,myswapBytes);
08223            }
08224            else {
08225          halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
08226                   elementSize,rowSize,groupSize);
08227            }
08228            break;
08229        case GL_BYTE:
08230            if (newDepth > 1) {
08231            halveImage3D(cmpts,extractSbyte,shoveSbyte,
08232                 newWidth,newHeight,newDepth,
08233                 srcImage,dstImage,elementSize,groupSize,rowSize,
08234                 imageSize,myswapBytes);
08235            }
08236            else {
08237          halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
08238                   elementSize,rowSize,groupSize);
08239            }
08240            break;
08241        case GL_UNSIGNED_SHORT:
08242            if (newDepth > 1) {
08243            halveImage3D(cmpts,extractUshort,shoveUshort,
08244                 newWidth,newHeight,newDepth,
08245                 srcImage,dstImage,elementSize,groupSize,rowSize,
08246                 imageSize,myswapBytes);
08247            }
08248            else {
08249          halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
08250                    elementSize,rowSize,groupSize,myswapBytes);
08251            }
08252            break;
08253        case GL_SHORT:
08254            if (newDepth > 1) {
08255            halveImage3D(cmpts,extractSshort,shoveSshort,
08256                 newWidth,newHeight,newDepth,
08257                 srcImage,dstImage,elementSize,groupSize,rowSize,
08258                 imageSize,myswapBytes);
08259            }
08260            else {
08261          halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
08262                   elementSize,rowSize,groupSize,myswapBytes);
08263            }
08264            break;
08265        case GL_UNSIGNED_INT:
08266            if (newDepth > 1) {
08267            halveImage3D(cmpts,extractUint,shoveUint,
08268                 newWidth,newHeight,newDepth,
08269                 srcImage,dstImage,elementSize,groupSize,rowSize,
08270                 imageSize,myswapBytes);
08271            }
08272            else {
08273          halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
08274                  elementSize,rowSize,groupSize,myswapBytes);
08275            }
08276            break;
08277        case GL_INT:
08278            if (newDepth > 1) {
08279            halveImage3D(cmpts,extractSint,shoveSint,
08280                 newWidth,newHeight,newDepth,
08281                 srcImage,dstImage,elementSize,groupSize,rowSize,
08282                 imageSize,myswapBytes);
08283            }
08284            else {
08285          halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
08286                 elementSize,rowSize,groupSize,myswapBytes);
08287            }
08288            break;
08289        case GL_FLOAT:
08290            if (newDepth > 1) {
08291            halveImage3D(cmpts,extractFloat,shoveFloat,
08292                 newWidth,newHeight,newDepth,
08293                 srcImage,dstImage,elementSize,groupSize,rowSize,
08294                 imageSize,myswapBytes);
08295            }
08296            else {
08297          halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
08298                   elementSize,rowSize,groupSize,myswapBytes);
08299            }
08300            break;
08301        case GL_UNSIGNED_BYTE_3_3_2:
08302            halveImagePackedPixel3D(3,extract332,shove332,
08303                        newWidth,newHeight,newDepth,
08304                        srcImage,dstImage,elementSize,rowSize,
08305                        imageSize,myswapBytes);
08306            break;
08307        case GL_UNSIGNED_BYTE_2_3_3_REV:
08308            halveImagePackedPixel3D(3,extract233rev,shove233rev,
08309                        newWidth,newHeight,newDepth,
08310                        srcImage,dstImage,elementSize,rowSize,
08311                        imageSize,myswapBytes);
08312            break;
08313        case GL_UNSIGNED_SHORT_5_6_5:
08314            halveImagePackedPixel3D(3,extract565,shove565,
08315                        newWidth,newHeight,newDepth,
08316                        srcImage,dstImage,elementSize,rowSize,
08317                        imageSize,myswapBytes);
08318            break;
08319        case GL_UNSIGNED_SHORT_5_6_5_REV:
08320            halveImagePackedPixel3D(3,extract565rev,shove565rev,
08321                        newWidth,newHeight,newDepth,
08322                        srcImage,dstImage,elementSize,rowSize,
08323                        imageSize,myswapBytes);
08324            break;
08325        case GL_UNSIGNED_SHORT_4_4_4_4:
08326            halveImagePackedPixel3D(4,extract4444,shove4444,
08327                        newWidth,newHeight,newDepth,
08328                        srcImage,dstImage,elementSize,rowSize,
08329                        imageSize,myswapBytes);
08330            break;
08331        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
08332            halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
08333                        newWidth,newHeight,newDepth,
08334                        srcImage,dstImage,elementSize,rowSize,
08335                        imageSize,myswapBytes);
08336            break;
08337        case GL_UNSIGNED_SHORT_5_5_5_1:
08338            halveImagePackedPixel3D(4,extract5551,shove5551,
08339                        newWidth,newHeight,newDepth,
08340                        srcImage,dstImage,elementSize,rowSize,
08341                        imageSize,myswapBytes);
08342            break;
08343        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
08344            halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
08345                        newWidth,newHeight,newDepth,
08346                        srcImage,dstImage,elementSize,rowSize,
08347                        imageSize,myswapBytes);
08348            break;
08349        case GL_UNSIGNED_INT_8_8_8_8:
08350            halveImagePackedPixel3D(4,extract8888,shove8888,
08351                        newWidth,newHeight,newDepth,
08352                        srcImage,dstImage,elementSize,rowSize,
08353                        imageSize,myswapBytes);
08354            break;
08355        case GL_UNSIGNED_INT_8_8_8_8_REV:
08356            halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
08357                        newWidth,newHeight,newDepth,
08358                        srcImage,dstImage,elementSize,rowSize,
08359                        imageSize,myswapBytes);
08360            break;
08361        case GL_UNSIGNED_INT_10_10_10_2:
08362            halveImagePackedPixel3D(4,extract1010102,shove1010102,
08363                        newWidth,newHeight,newDepth,
08364                        srcImage,dstImage,elementSize,rowSize,
08365                        imageSize,myswapBytes);
08366            break;
08367        case GL_UNSIGNED_INT_2_10_10_10_REV:
08368            halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
08369                        newWidth,newHeight,newDepth,
08370                        srcImage,dstImage,elementSize,rowSize,
08371                        imageSize,myswapBytes);
08372            break;
08373        default:
08374            assert(0);
08375            break;
08376        }
08377 
08378        __GLU_SWAP_IMAGE(srcImage,dstImage);
08379 
08380        if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
08381        if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
08382        if (newDepth > 1) newDepth /= 2;
08383        {
08384       /* call tex image with srcImage untouched since it's not padded */
08385       if (baseLevel <= level && level <= maxLevel) {
08386         gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
08387              newDepth,0, format, type, (void *) srcImage);
08388       }
08389        }
08390    } /* for level */
08391    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
08392    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
08393    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
08394    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
08395    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
08396    glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
08397    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
08398 
08399    free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
08400    if (dstImage) { /* if it's non-rectangular and only 1 level */
08401      free(dstImage);
08402    }
08403    return 0;
08404 } /* gluBuild3DMipmapLevelsCore() */
08405 
08406 GLint GLAPIENTRY
08407 gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
08408                  GLsizei width, GLsizei height, GLsizei depth,
08409                  GLenum format, GLenum type,
08410                  GLint userLevel, GLint baseLevel, GLint maxLevel,
08411                  const void *data)
08412 {
08413    int level, levels;
08414 
08415    int rc= checkMipmapArgs(internalFormat,format,type);
08416    if (rc != 0) return rc;
08417 
08418    if (width < 1 || height < 1 || depth < 1) {
08419        return GLU_INVALID_VALUE;
08420    }
08421 
08422    if(type == GL_BITMAP) {
08423       return GLU_INVALID_ENUM;
08424    }
08425 
08426    levels = computeLog(width);
08427    level = computeLog(height);
08428    if (level > levels) levels=level;
08429    level = computeLog(depth);
08430    if (level > levels) levels=level;
08431 
08432    levels+= userLevel;
08433    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
08434       return GLU_INVALID_VALUE;
08435 
08436    return gluBuild3DMipmapLevelsCore(target, internalFormat,
08437                      width, height, depth,
08438                      width, height, depth,
08439                      format, type,
08440                      userLevel, baseLevel, maxLevel,
08441                      data);
08442 } /* gluBuild3DMipmapLevels() */
08443 
08444 GLint GLAPIENTRY
08445 gluBuild3DMipmaps(GLenum target, GLint internalFormat,
08446             GLsizei width, GLsizei height, GLsizei depth,
08447             GLenum format, GLenum type, const void *data)
08448 {
08449    GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
08450    int level, levels;
08451 
08452    int rc= checkMipmapArgs(internalFormat,format,type);
08453    if (rc != 0) return rc;
08454 
08455    if (width < 1 || height < 1 || depth < 1) {
08456        return GLU_INVALID_VALUE;
08457    }
08458 
08459    if(type == GL_BITMAP) {
08460       return GLU_INVALID_ENUM;
08461    }
08462 
08463    closestFit3D(target,width,height,depth,internalFormat,format,type,
08464         &widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
08465 
08466    levels = computeLog(widthPowerOf2);
08467    level = computeLog(heightPowerOf2);
08468    if (level > levels) levels=level;
08469    level = computeLog(depthPowerOf2);
08470    if (level > levels) levels=level;
08471 
08472    return gluBuild3DMipmapLevelsCore(target, internalFormat,
08473                      width, height, depth,
08474                      widthPowerOf2, heightPowerOf2,
08475                      depthPowerOf2,
08476                      format, type, 0, 0, levels,
08477                      data);
08478 } /* gluBuild3DMipmaps() */
08479 
08480 static GLdouble extractUbyte(int isSwap, const void *ubyte)
08481 {
08482    isSwap= isSwap;      /* turn off warnings */
08483 
08484    return (GLdouble)(*((const GLubyte *)ubyte));
08485 } /* extractUbyte() */
08486 
08487 static void shoveUbyte(GLdouble value, int index, void *data)
08488 {
08489    assert(0.0 <= value && value < 256.0);
08490 
08491    ((GLubyte *)data)[index]= (GLubyte)value;
08492 } /* shoveUbyte() */
08493 
08494 static GLdouble extractSbyte(int isSwap, const void *sbyte)
08495 {
08496    isSwap= isSwap;      /* turn off warnings */
08497 
08498    return (GLdouble)(*((const GLbyte *)sbyte));
08499 } /* extractSbyte() */
08500 
08501 static void shoveSbyte(GLdouble value, int index, void *data)
08502 {
08503    ((GLbyte *)data)[index]= (GLbyte)value;
08504 } /* shoveSbyte() */
08505 
08506 static GLdouble extractUshort(int isSwap, const void *uitem)
08507 {
08508    GLushort ushort;
08509 
08510    if (isSwap) {
08511      ushort= __GLU_SWAP_2_BYTES(uitem);
08512    }
08513    else {
08514      ushort= *(const GLushort *)uitem;
08515    }
08516 
08517    return (GLdouble)ushort;
08518 } /* extractUshort() */
08519 
08520 static void shoveUshort(GLdouble value, int index, void *data)
08521 {
08522    assert(0.0 <= value && value < 65536.0);
08523 
08524    ((GLushort *)data)[index]= (GLushort)value;
08525 } /* shoveUshort() */
08526 
08527 static GLdouble extractSshort(int isSwap, const void *sitem)
08528 {
08529    GLshort sshort;
08530 
08531    if (isSwap) {
08532      sshort= __GLU_SWAP_2_BYTES(sitem);
08533    }
08534    else {
08535      sshort= *(const GLshort *)sitem;
08536    }
08537 
08538    return (GLdouble)sshort;
08539 } /* extractSshort() */
08540 
08541 static void shoveSshort(GLdouble value, int index, void *data)
08542 {
08543    assert(0.0 <= value && value < 32768.0);
08544 
08545    ((GLshort *)data)[index]= (GLshort)value;
08546 } /* shoveSshort() */
08547 
08548 static GLdouble extractUint(int isSwap, const void *uitem)
08549 {
08550    GLuint uint;
08551 
08552    if (isSwap) {
08553      uint= __GLU_SWAP_4_BYTES(uitem);
08554    }
08555    else {
08556      uint= *(const GLuint *)uitem;
08557    }
08558 
08559    assert(uint <= 0xffffffff);
08560 
08561    return (GLdouble)uint;
08562 } /* extractUint() */
08563 
08564 static void shoveUint(GLdouble value, int index, void *data)
08565 {
08566    assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
08567 
08568    ((GLuint *)data)[index]= (GLuint)value;
08569 } /* shoveUint() */
08570 
08571 static GLdouble extractSint(int isSwap, const void *sitem)
08572 {
08573    GLint sint;
08574 
08575    if (isSwap) {
08576      sint= __GLU_SWAP_4_BYTES(sitem);
08577    }
08578    else {
08579      sint= *(const GLint *)sitem;
08580    }
08581 
08582    assert(sint <= 0x7fffffff);
08583 
08584    return (GLdouble)sint;
08585 } /* extractSint() */
08586 
08587 static void shoveSint(GLdouble value, int index, void *data)
08588 {
08589    assert(0.0 <= value && value <= (GLdouble) INT_MAX);
08590 
08591    ((GLint *)data)[index]= (GLint)value;
08592 } /* shoveSint() */
08593 
08594 static GLdouble extractFloat(int isSwap, const void *item)
08595 {
08596    GLfloat ffloat;
08597 
08598    if (isSwap) {
08599      ffloat= __GLU_SWAP_4_BYTES(item);
08600    }
08601    else {
08602      ffloat= *(const GLfloat *)item;
08603    }
08604 
08605    assert(ffloat <= 1.0);
08606 
08607    return (GLdouble)ffloat;
08608 } /* extractFloat() */
08609 
08610 static void shoveFloat(GLdouble value, int index, void *data)
08611 {
08612    assert(0.0 <= value && value <= 1.0);
08613 
08614    ((GLfloat *)data)[index]= value;
08615 } /* shoveFloat() */
08616 
08617 static void halveImageSlice(int components,
08618                 GLdouble (*extract)(int, const void *),
08619                 void (*shove)(GLdouble, int, void *),
08620                 GLint width, GLint height, GLint depth,
08621                 const void *dataIn, void *dataOut,
08622                 GLint elementSizeInBytes,
08623                 GLint groupSizeInBytes,
08624                 GLint rowSizeInBytes,
08625                 GLint imageSizeInBytes,
08626                 GLint isSwap)
08627 {
08628    int ii, jj;
08629    int halfWidth= width / 2;
08630    int halfHeight= height / 2;
08631    int halfDepth= depth / 2;
08632    const char *src= (const char *)dataIn;
08633    int padBytes= rowSizeInBytes - (width * groupSizeInBytes);
08634    int outIndex= 0;
08635 
08636    assert((width == 1 || height == 1) && depth >= 2);
08637 
08638    if (width == height) {   /* a 1-pixel column viewed from top */
08639       /* printf("1-column\n");*/
08640       assert(width == 1 && height == 1);
08641       assert(depth >= 2);
08642 
08643       for (ii= 0; ii< halfDepth; ii++) {
08644      int cc;
08645 
08646      for (cc = 0; cc < components; cc++) {
08647         double totals[4];
08648         double extractTotals[BOX2][4];
08649         int kk;
08650 
08651         extractTotals[0][cc]= (*extract)(isSwap,src);
08652         extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
08653 
08654         /* average 2 pixels since only a column */
08655         totals[cc]= 0.0;
08656         /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
08657          * totals[RED]/= 2.0;
08658          */
08659         for (kk = 0; kk < BOX2; kk++) {
08660           totals[cc]+= extractTotals[kk][cc];
08661         }
08662         totals[cc]/= (double)BOX2;
08663 
08664         (*shove)(totals[cc],outIndex,dataOut);
08665         outIndex++;
08666         src+= elementSizeInBytes;
08667      } /* for cc */
08668 
08669      /* skip over to next group of 2 */
08670      src+= rowSizeInBytes;
08671       } /* for ii */
08672 
08673       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
08674       assert(outIndex == halfDepth * components);
08675    }
08676    else if (height == 1) {  /* horizontal slice viewed from top */
08677       /* printf("horizontal slice\n"); */
08678       assert(width != 1);
08679 
08680       for (ii= 0; ii< halfDepth; ii++) {
08681      for (jj= 0; jj< halfWidth; jj++) {
08682         int cc;
08683 
08684         for (cc = 0; cc < components; cc++) {
08685            int kk;
08686            double totals[4];
08687            double extractTotals[BOX4][4];
08688 
08689            extractTotals[0][cc]=(*extract)(isSwap,src);
08690            extractTotals[1][cc]=(*extract)(isSwap,
08691                            (src+groupSizeInBytes));
08692            extractTotals[2][cc]=(*extract)(isSwap,
08693                            (src+imageSizeInBytes));
08694            extractTotals[3][cc]=(*extract)(isSwap,
08695                            (src+imageSizeInBytes+groupSizeInBytes));
08696 
08697            /* grab 4 pixels to average */
08698            totals[cc]= 0.0;
08699            /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
08700         *          extractTotals[2][RED]+extractTotals[3][RED];
08701         * totals[RED]/= 4.0;
08702         */
08703            for (kk = 0; kk < BOX4; kk++) {
08704           totals[cc]+= extractTotals[kk][cc];
08705            }
08706            totals[cc]/= (double)BOX4;
08707 
08708            (*shove)(totals[cc],outIndex,dataOut);
08709            outIndex++;
08710 
08711            src+= elementSizeInBytes;
08712         } /* for cc */
08713 
08714         /* skip over to next horizontal square of 4 */
08715         src+= groupSizeInBytes;
08716      } /* for jj */
08717      src+= padBytes;
08718 
08719      src+= rowSizeInBytes;
08720       } /* for ii */
08721 
08722       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
08723       assert(outIndex == halfWidth * halfDepth * components);
08724    }
08725    else if (width == 1) {   /* vertical slice viewed from top */
08726       /* printf("vertical slice\n"); */
08727       assert(height != 1);
08728 
08729       for (ii= 0; ii< halfDepth; ii++) {
08730      for (jj= 0; jj< halfHeight; jj++) {
08731         int cc;
08732 
08733         for (cc = 0; cc < components; cc++) {
08734            int kk;
08735            double totals[4];
08736            double extractTotals[BOX4][4];
08737 
08738            extractTotals[0][cc]=(*extract)(isSwap,src);
08739            extractTotals[1][cc]=(*extract)(isSwap,
08740                            (src+rowSizeInBytes));
08741            extractTotals[2][cc]=(*extract)(isSwap,
08742                            (src+imageSizeInBytes));
08743            extractTotals[3][cc]=(*extract)(isSwap,
08744                            (src+imageSizeInBytes+rowSizeInBytes));
08745 
08746            /* grab 4 pixels to average */
08747            totals[cc]= 0.0;
08748            /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
08749         *          extractTotals[2][RED]+extractTotals[3][RED];
08750         * totals[RED]/= 4.0;
08751         */
08752            for (kk = 0; kk < BOX4; kk++) {
08753           totals[cc]+= extractTotals[kk][cc];
08754            }
08755            totals[cc]/= (double)BOX4;
08756 
08757            (*shove)(totals[cc],outIndex,dataOut);
08758            outIndex++;
08759 
08760            src+= elementSizeInBytes;
08761         } /* for cc */
08762         src+= padBytes;
08763 
08764         /* skip over to next vertical square of 4 */
08765         src+= rowSizeInBytes;
08766      } /* for jj */
08767 
08768      src+= imageSizeInBytes;
08769       } /* for ii */
08770 
08771       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
08772       assert(outIndex == halfHeight * halfDepth * components);
08773    }
08774 
08775 } /* halveImageSlice() */
08776 
08777 static void halveImage3D(int components,
08778              GLdouble (*extract)(int, const void *),
08779              void (*shove)(GLdouble, int, void *),
08780              GLint width, GLint height, GLint depth,
08781              const void *dataIn, void *dataOut,
08782              GLint elementSizeInBytes,
08783              GLint groupSizeInBytes,
08784              GLint rowSizeInBytes,
08785              GLint imageSizeInBytes,
08786              GLint isSwap)
08787 {
08788    assert(depth > 1);
08789 
08790    /* a horizontal/vertical/one-column slice viewed from top */
08791    if (width == 1 || height == 1) {
08792       assert(1 <= depth);
08793 
08794       halveImageSlice(components,extract,shove, width, height, depth,
08795               dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
08796               rowSizeInBytes, imageSizeInBytes, isSwap);
08797       return;
08798    }
08799    {
08800       int ii, jj, dd;
08801 
08802       int halfWidth= width / 2;
08803       int halfHeight= height / 2;
08804       int halfDepth= depth / 2;
08805       const char *src= (const char *) dataIn;
08806       int padBytes= rowSizeInBytes - (width*groupSizeInBytes);
08807       int outIndex= 0;
08808 
08809       for (dd= 0; dd < halfDepth; dd++) {
08810      for (ii= 0; ii< halfHeight; ii++) {
08811         for (jj= 0; jj< halfWidth; jj++) {
08812            int cc;
08813 
08814            for (cc= 0; cc < components; cc++) {
08815           int kk;
08816 #define BOX8 8
08817           double totals[4]; /* 4 is maximum components */
08818           double extractTotals[BOX8][4]; /* 4 is maximum components */
08819 
08820           extractTotals[0][cc]= (*extract)(isSwap,src);
08821           extractTotals[1][cc]= (*extract)(isSwap,
08822                            (src+groupSizeInBytes));
08823           extractTotals[2][cc]= (*extract)(isSwap,
08824                            (src+rowSizeInBytes));
08825           extractTotals[3][cc]= (*extract)(isSwap,
08826                            (src+rowSizeInBytes+groupSizeInBytes));
08827 
08828           extractTotals[4][cc]= (*extract)(isSwap,
08829                            (src+imageSizeInBytes));
08830 
08831           extractTotals[5][cc]= (*extract)(isSwap,
08832                            (src+groupSizeInBytes+imageSizeInBytes));
08833           extractTotals[6][cc]= (*extract)(isSwap,
08834                            (src+rowSizeInBytes+imageSizeInBytes));
08835           extractTotals[7][cc]= (*extract)(isSwap,
08836                            (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
08837 
08838           totals[cc]= 0.0;
08839 
08840           /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
08841            *          extractTotals[2][RED]+extractTotals[3][RED]+
08842            *          extractTotals[4][RED]+extractTotals[5][RED]+
08843            *          extractTotals[6][RED]+extractTotals[7][RED];
08844            * totals[RED]/= 8.0;
08845            */
08846           for (kk = 0; kk < BOX8; kk++) {
08847              totals[cc]+= extractTotals[kk][cc];
08848           }
08849           totals[cc]/= (double)BOX8;
08850 
08851           (*shove)(totals[cc],outIndex,dataOut);
08852 
08853           outIndex++;
08854 
08855           src+= elementSizeInBytes; /* go to next component */
08856            } /* for cc */
08857 
08858            /* skip over to next square of 4 */
08859            src+= groupSizeInBytes;
08860         } /* for jj */
08861         /* skip past pad bytes, if any, to get to next row */
08862         src+= padBytes;
08863 
08864         /* src is at beginning of a row here, but it's the second row of
08865          * the square block of 4 pixels that we just worked on so we
08866          * need to go one more row.
08867          * i.e.,
08868          *           OO...
08869          *       here -->OO...
08870          *       but want -->OO...
08871          *           OO...
08872          *           ...
08873          */
08874         src+= rowSizeInBytes;
08875      } /* for ii */
08876 
08877      src+= imageSizeInBytes;
08878       } /* for dd */
08879 
08880       /* both pointers must reach one byte after the end */
08881       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
08882       assert(outIndex == halfWidth * halfHeight * halfDepth * components);
08883    }
08884 } /* halveImage3D() */
08885 
08886 
08887 
08888 /*** mipmap.c ***/
08889 

Generated on Wed May 23 2012 04:18:29 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.