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