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 
retrieveStoreModes(PixelStorageModes * psm)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 
retrieveStoreModes3D(PixelStorageModes * psm)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 
computeLog(GLuint value)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 */
nearestPower(GLuint value)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 
halveImage(GLint components,GLuint width,GLuint height,const GLushort * datain,GLushort * dataout)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 
halveImage_ubyte(GLint components,GLuint width,GLuint height,const GLubyte * datain,GLubyte * dataout,GLint element_size,GLint ysize,GLint group_size)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 /* */
halve1Dimage_ubyte(GLint components,GLuint width,GLuint height,const GLubyte * dataIn,GLubyte * dataOut,GLint element_size,GLint ysize,GLint group_size)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 
halveImage_byte(GLint components,GLuint width,GLuint height,const GLbyte * datain,GLbyte * dataout,GLint element_size,GLint ysize,GLint group_size)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 
halve1Dimage_byte(GLint components,GLuint width,GLuint height,const GLbyte * dataIn,GLbyte * dataOut,GLint element_size,GLint ysize,GLint group_size)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 
halveImage_ushort(GLint components,GLuint width,GLuint height,const GLushort * datain,GLushort * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
halve1Dimage_ushort(GLint components,GLuint width,GLuint height,const GLushort * dataIn,GLushort * dataOut,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
halveImage_short(GLint components,GLuint width,GLuint height,const GLshort * datain,GLshort * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
halve1Dimage_short(GLint components,GLuint width,GLuint height,const GLshort * dataIn,GLshort * dataOut,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
halveImage_uint(GLint components,GLuint width,GLuint height,const GLuint * datain,GLuint * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 /* */
halve1Dimage_uint(GLint components,GLuint width,GLuint height,const GLuint * dataIn,GLuint * dataOut,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
halveImage_int(GLint components,GLuint width,GLuint height,const GLint * datain,GLint * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 /* */
halve1Dimage_int(GLint components,GLuint width,GLuint height,const GLint * dataIn,GLint * dataOut,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
halveImage_float(GLint components,GLuint width,GLuint height,const GLfloat * datain,GLfloat * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 /* */
halve1Dimage_float(GLint components,GLuint width,GLuint height,const GLfloat * dataIn,GLfloat * dataOut,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
scale_internal(GLint components,GLint widthin,GLint heightin,const GLushort * datain,GLint widthout,GLint heightout,GLushort * dataout)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 
scale_internal_ubyte(GLint components,GLint widthin,GLint heightin,const GLubyte * datain,GLint widthout,GLint heightout,GLubyte * dataout,GLint element_size,GLint ysize,GLint group_size)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 
scale_internal_byte(GLint components,GLint widthin,GLint heightin,const GLbyte * datain,GLint widthout,GLint heightout,GLbyte * dataout,GLint element_size,GLint ysize,GLint group_size)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 
scale_internal_ushort(GLint components,GLint widthin,GLint heightin,const GLushort * datain,GLint widthout,GLint heightout,GLushort * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
scale_internal_short(GLint components,GLint widthin,GLint heightin,const GLshort * datain,GLint widthout,GLint heightout,GLshort * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
scale_internal_uint(GLint components,GLint widthin,GLint heightin,const GLuint * datain,GLint widthout,GLint heightout,GLuint * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
scale_internal_int(GLint components,GLint widthin,GLint heightin,const GLint * datain,GLint widthout,GLint heightout,GLint * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
scale_internal_float(GLint components,GLint widthin,GLint heightin,const GLfloat * datain,GLint widthout,GLint heightout,GLfloat * dataout,GLint element_size,GLint ysize,GLint group_size,GLint myswap_bytes)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 
checkMipmapArgs(GLenum internalFormat,GLenum format,GLenum type)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 
legalFormat(GLenum format)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 
legalType(GLenum type)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 /* */
isTypePackedPixel(GLenum type)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 */
isLegalFormatForPackedPixelType(GLenum format,GLenum type)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 
isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel,GLint totalLevels)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  */
closestFit(GLenum target,GLint width,GLint height,GLint internalFormat,GLenum format,GLenum type,GLint * newWidth,GLint * newHeight)3410 static void closestFit(GLenum target, GLint width, GLint height,
3411 		       GLint internalFormat, GLenum format, GLenum type,
3412 		       GLint *newWidth, GLint *newHeight)
3413 {
3414    /* Use proxy textures if OpenGL version is >= 1.1 */
3415    if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
3416 	) {
3417       GLint widthPowerOf2= nearestPower(width);
3418       GLint heightPowerOf2= nearestPower(height);
3419       GLint proxyWidth;
3420 
3421       do {
3422 	 /* compute level 1 width & height, clamping each at 1 */
3423 	 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
3424 				 widthPowerOf2 >> 1 :
3425 				 widthPowerOf2;
3426 	 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
3427 				  heightPowerOf2 >> 1 :
3428 				  heightPowerOf2;
3429 	 GLenum proxyTarget;
3430 	 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
3431 
3432 	 /* does width x height at level 1 & all their mipmaps fit? */
3433 	 if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
3434 	    proxyTarget = GL_PROXY_TEXTURE_2D;
3435 	    glTexImage2D(proxyTarget, 1, /* must be non-zero */
3436 			 internalFormat,
3437 			 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3438 	 } else
3439 #if defined(GL_ARB_texture_cube_map)
3440 	 if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
3441 	     (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
3442 	     (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
3443 	     (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
3444 	     (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
3445 	     (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
3446 	     proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3447 	     glTexImage2D(proxyTarget, 1, /* must be non-zero */
3448 			  internalFormat,
3449 			  widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3450 	 } else
3451 #endif /* GL_ARB_texture_cube_map */
3452 	 {
3453 	    assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
3454 	    proxyTarget = GL_PROXY_TEXTURE_1D;
3455 	    glTexImage1D(proxyTarget, 1, /* must be non-zero */
3456 			 internalFormat,widthAtLevelOne,0,format,type,NULL);
3457 	 }
3458 	 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
3459 	 /* does it fit??? */
3460 	 if (proxyWidth == 0) { /* nope, so try again with these sizes */
3461 	    if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
3462 	       /* An 1x1 texture couldn't fit for some reason, so
3463 		* break out.  This should never happen. But things
3464 		* happen.  The disadvantage with this if-statement is
3465 		* that we will never be aware of when this happens
3466 		* since it will silently branch out.
3467 		*/
3468 	       goto noProxyTextures;
3469 	    }
3470 	    widthPowerOf2= widthAtLevelOne;
3471 	    heightPowerOf2= heightAtLevelOne;
3472 	 }
3473 	 /* else it does fit */
3474       } while (proxyWidth == 0);
3475       /* loop must terminate! */
3476 
3477       /* return the width & height at level 0 that fits */
3478       *newWidth= widthPowerOf2;
3479       *newHeight= heightPowerOf2;
3480 /*printf("Proxy Textures\n");*/
3481    } /* if gluCheckExtension() */
3482    else {			/* no texture extension, so do this instead */
3483       GLint maxsize;
3484 
3485 noProxyTextures:
3486 
3487       glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3488       /* clamp user's texture sizes to maximum sizes, if necessary */
3489       *newWidth = nearestPower(width);
3490       if (*newWidth > maxsize) *newWidth = maxsize;
3491       *newHeight = nearestPower(height);
3492       if (*newHeight > maxsize) *newHeight = maxsize;
3493 /*printf("NO proxy textures\n");*/
3494    }
3495 } /* closestFit() */
3496 
3497 GLint GLAPIENTRY
gluScaleImage(GLenum format,GLsizei widthin,GLsizei heightin,GLenum typein,const void * datain,GLsizei widthout,GLsizei heightout,GLenum typeout,void * dataout)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 
gluBuild1DMipmapLevelsCore(GLenum target,GLint internalFormat,GLsizei width,GLsizei widthPowerOf2,GLenum format,GLenum type,GLint userLevel,GLint baseLevel,GLint maxLevel,const void * data)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
gluBuild1DMipmapLevels(GLenum target,GLint internalFormat,GLsizei width,GLenum format,GLenum type,GLint userLevel,GLint baseLevel,GLint maxLevel,const void * data)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
gluBuild1DMipmaps(GLenum target,GLint internalFormat,GLsizei width,GLenum format,GLenum type,const void * data)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 
bitmapBuild2DMipmaps(GLenum target,GLint internalFormat,GLint width,GLint height,GLenum format,GLenum type,const void * data)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 
gluBuild2DMipmapLevelsCore(GLenum target,GLint internalFormat,GLsizei width,GLsizei height,GLsizei widthPowerOf2,GLsizei heightPowerOf2,GLenum format,GLenum type,GLint userLevel,GLint baseLevel,GLint maxLevel,const void * data)3802 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3803 				      GLsizei width, GLsizei height,
3804 				      GLsizei widthPowerOf2,
3805 				      GLsizei heightPowerOf2,
3806 				      GLenum format, GLenum type,
3807 				      GLint userLevel,
3808 				      GLint baseLevel,GLint maxLevel,
3809 				      const void *data)
3810 {
3811     GLint newwidth, newheight;
3812     GLint level, levels;
3813     const void *usersImage; /* passed from user. Don't touch! */
3814     void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3815     __GLU_INIT_SWAP_IMAGE;
3816     GLint memreq;
3817     GLint cmpts;
3818 
3819     GLint myswap_bytes, groups_per_line, element_size, group_size;
3820     GLint rowsize, padding;
3821     PixelStorageModes psm;
3822 
3823     assert(checkMipmapArgs(internalFormat,format,type) == 0);
3824     assert(width >= 1 && height >= 1);
3825 
3826     if(type == GL_BITMAP) {
3827 	return bitmapBuild2DMipmaps(target, internalFormat, width, height,
3828 		format, type, data);
3829     }
3830 
3831     srcImage = dstImage = NULL;
3832 
3833     newwidth= widthPowerOf2;
3834     newheight= heightPowerOf2;
3835     levels = computeLog(newwidth);
3836     level = computeLog(newheight);
3837     if (level > levels) levels=level;
3838 
3839     levels+= userLevel;
3840 
3841     retrieveStoreModes(&psm);
3842     myswap_bytes = psm.unpack_swap_bytes;
3843     cmpts = elements_per_group(format,type);
3844     if (psm.unpack_row_length > 0) {
3845 	groups_per_line = psm.unpack_row_length;
3846     } else {
3847 	groups_per_line = width;
3848     }
3849 
3850     element_size = bytes_per_element(type);
3851     group_size = element_size * cmpts;
3852     if (element_size == 1) myswap_bytes = 0;
3853 
3854     rowsize = groups_per_line * group_size;
3855     padding = (rowsize % psm.unpack_alignment);
3856     if (padding) {
3857 	rowsize += psm.unpack_alignment - padding;
3858     }
3859     usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3860 	psm.unpack_skip_pixels * group_size;
3861 
3862     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3863     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3864     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3865 
3866     level = userLevel;
3867 
3868     /* already power-of-two square */
3869     if (width == newwidth && height == newheight) {
3870 	/* Use usersImage for level userLevel */
3871 	if (baseLevel <= level && level <= maxLevel) {
3872         glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3873 	glTexImage2D(target, level, internalFormat, width,
3874 		height, 0, format, type,
3875 		usersImage);
3876 	}
3877         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3878 	if(levels == 0) { /* we're done. clean up and return */
3879 	  glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3880 	  glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3881 	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3882 	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3883 	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3884 	  return 0;
3885 	}
3886 	{
3887 	   int nextWidth= newwidth/2;
3888 	   int nextHeight= newheight/2;
3889 
3890 	   /* clamp to 1 */
3891 	   if (nextWidth < 1) nextWidth= 1;
3892 	   if (nextHeight < 1) nextHeight= 1;
3893 	memreq = image_size(nextWidth, nextHeight, format, type);
3894 	}
3895 
3896 	switch(type) {
3897 	case GL_UNSIGNED_BYTE:
3898 	  dstImage = (GLubyte *)malloc(memreq);
3899 	  break;
3900 	case GL_BYTE:
3901 	  dstImage = (GLbyte *)malloc(memreq);
3902 	  break;
3903 	case GL_UNSIGNED_SHORT:
3904 	  dstImage = (GLushort *)malloc(memreq);
3905 	  break;
3906 	case GL_SHORT:
3907 	  dstImage = (GLshort *)malloc(memreq);
3908 	  break;
3909 	case GL_UNSIGNED_INT:
3910 	  dstImage = (GLuint *)malloc(memreq);
3911 	  break;
3912 	case GL_INT:
3913 	  dstImage = (GLint *)malloc(memreq);
3914 	  break;
3915 	case GL_FLOAT:
3916 	  dstImage = (GLfloat *)malloc(memreq);
3917 	  break;
3918 	case GL_UNSIGNED_BYTE_3_3_2:
3919 	case GL_UNSIGNED_BYTE_2_3_3_REV:
3920 	  dstImage = (GLubyte *)malloc(memreq);
3921 	  break;
3922 	case GL_UNSIGNED_SHORT_5_6_5:
3923 	case GL_UNSIGNED_SHORT_5_6_5_REV:
3924 	case GL_UNSIGNED_SHORT_4_4_4_4:
3925 	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3926 	case GL_UNSIGNED_SHORT_5_5_5_1:
3927 	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3928 	  dstImage = (GLushort *)malloc(memreq);
3929 	  break;
3930 	case GL_UNSIGNED_INT_8_8_8_8:
3931 	case GL_UNSIGNED_INT_8_8_8_8_REV:
3932 	case GL_UNSIGNED_INT_10_10_10_2:
3933 	case GL_UNSIGNED_INT_2_10_10_10_REV:
3934 	  dstImage = (GLuint *)malloc(memreq);
3935 	  break;
3936 	default:
3937 	  return GLU_INVALID_ENUM;
3938 	}
3939 	if (dstImage == NULL) {
3940 	  glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3941 	  glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3942 	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3943 	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3944 	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3945 	  return GLU_OUT_OF_MEMORY;
3946 	}
3947 	else
3948 	  switch(type) {
3949 	  case GL_UNSIGNED_BYTE:
3950 	    halveImage_ubyte(cmpts, width, height,
3951 			     (const GLubyte *)usersImage, (GLubyte *)dstImage,
3952 			     element_size, rowsize, group_size);
3953 	    break;
3954 	  case GL_BYTE:
3955 	    halveImage_byte(cmpts, width, height,
3956 			    (const GLbyte *)usersImage, (GLbyte *)dstImage,
3957 			    element_size, rowsize, group_size);
3958 	    break;
3959 	  case GL_UNSIGNED_SHORT:
3960 	    halveImage_ushort(cmpts, width, height,
3961 			      (const GLushort *)usersImage, (GLushort *)dstImage,
3962 			      element_size, rowsize, group_size, myswap_bytes);
3963 	    break;
3964 	  case GL_SHORT:
3965 	    halveImage_short(cmpts, width, height,
3966 			     (const GLshort *)usersImage, (GLshort *)dstImage,
3967 			     element_size, rowsize, group_size, myswap_bytes);
3968 	    break;
3969 	  case GL_UNSIGNED_INT:
3970 	    halveImage_uint(cmpts, width, height,
3971 			    (const GLuint *)usersImage, (GLuint *)dstImage,
3972 			    element_size, rowsize, group_size, myswap_bytes);
3973 	    break;
3974 	  case GL_INT:
3975 	    halveImage_int(cmpts, width, height,
3976 			   (const GLint *)usersImage, (GLint *)dstImage,
3977 			   element_size, rowsize, group_size, myswap_bytes);
3978 	    break;
3979 	  case GL_FLOAT:
3980 	    halveImage_float(cmpts, width, height,
3981 			     (const GLfloat *)usersImage, (GLfloat *)dstImage,
3982 			     element_size, rowsize, group_size, myswap_bytes);
3983 	    break;
3984 	  case GL_UNSIGNED_BYTE_3_3_2:
3985 	    assert(format == GL_RGB);
3986 	    halveImagePackedPixel(3,extract332,shove332,
3987 				  width,height,usersImage,dstImage,
3988 				  element_size,rowsize,myswap_bytes);
3989 	    break;
3990 	  case GL_UNSIGNED_BYTE_2_3_3_REV:
3991 	    assert(format == GL_RGB);
3992 	    halveImagePackedPixel(3,extract233rev,shove233rev,
3993 				  width,height,usersImage,dstImage,
3994 				  element_size,rowsize,myswap_bytes);
3995 	    break;
3996 	  case GL_UNSIGNED_SHORT_5_6_5:
3997 	    halveImagePackedPixel(3,extract565,shove565,
3998 				  width,height,usersImage,dstImage,
3999 				  element_size,rowsize,myswap_bytes);
4000 	    break;
4001 	  case GL_UNSIGNED_SHORT_5_6_5_REV:
4002 	    halveImagePackedPixel(3,extract565rev,shove565rev,
4003 				  width,height,usersImage,dstImage,
4004 				  element_size,rowsize,myswap_bytes);
4005 	    break;
4006 	  case GL_UNSIGNED_SHORT_4_4_4_4:
4007 	    halveImagePackedPixel(4,extract4444,shove4444,
4008 				  width,height,usersImage,dstImage,
4009 				  element_size,rowsize,myswap_bytes);
4010 	    break;
4011 	  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4012 	    halveImagePackedPixel(4,extract4444rev,shove4444rev,
4013 				  width,height,usersImage,dstImage,
4014 				  element_size,rowsize,myswap_bytes);
4015 	    break;
4016 	  case GL_UNSIGNED_SHORT_5_5_5_1:
4017 	    halveImagePackedPixel(4,extract5551,shove5551,
4018 				  width,height,usersImage,dstImage,
4019 				  element_size,rowsize,myswap_bytes);
4020 	    break;
4021 	  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4022 	    halveImagePackedPixel(4,extract1555rev,shove1555rev,
4023 				  width,height,usersImage,dstImage,
4024 				  element_size,rowsize,myswap_bytes);
4025 	    break;
4026 	  case GL_UNSIGNED_INT_8_8_8_8:
4027 	    halveImagePackedPixel(4,extract8888,shove8888,
4028 				  width,height,usersImage,dstImage,
4029 				  element_size,rowsize,myswap_bytes);
4030 	    break;
4031 	  case GL_UNSIGNED_INT_8_8_8_8_REV:
4032 	    halveImagePackedPixel(4,extract8888rev,shove8888rev,
4033 				  width,height,usersImage,dstImage,
4034 				  element_size,rowsize,myswap_bytes);
4035 	    break;
4036 	  case GL_UNSIGNED_INT_10_10_10_2:
4037 	    halveImagePackedPixel(4,extract1010102,shove1010102,
4038 				  width,height,usersImage,dstImage,
4039 				  element_size,rowsize,myswap_bytes);
4040 	    break;
4041 	  case GL_UNSIGNED_INT_2_10_10_10_REV:
4042 	    halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4043 				  width,height,usersImage,dstImage,
4044 				  element_size,rowsize,myswap_bytes);
4045 	    break;
4046 	  default:
4047 	    assert(0);
4048 	    break;
4049 	  }
4050 	newwidth = width/2;
4051 	newheight = height/2;
4052 	/* clamp to 1 */
4053 	if (newwidth < 1) newwidth= 1;
4054 	if (newheight < 1) newheight= 1;
4055 
4056 	myswap_bytes = 0;
4057 	rowsize = newwidth * group_size;
4058 	memreq = image_size(newwidth, newheight, format, type);
4059 	/* Swap srcImage and dstImage */
4060 	__GLU_SWAP_IMAGE(srcImage,dstImage);
4061 	switch(type) {
4062 	case GL_UNSIGNED_BYTE:
4063 	  dstImage = (GLubyte *)malloc(memreq);
4064 	  break;
4065 	case GL_BYTE:
4066 	  dstImage = (GLbyte *)malloc(memreq);
4067 	  break;
4068 	case GL_UNSIGNED_SHORT:
4069 	  dstImage = (GLushort *)malloc(memreq);
4070 	  break;
4071 	case GL_SHORT:
4072 	  dstImage = (GLshort *)malloc(memreq);
4073 	  break;
4074 	case GL_UNSIGNED_INT:
4075 	  dstImage = (GLuint *)malloc(memreq);
4076 	  break;
4077 	case GL_INT:
4078 	  dstImage = (GLint *)malloc(memreq);
4079 	  break;
4080 	case GL_FLOAT:
4081 	  dstImage = (GLfloat *)malloc(memreq);
4082 	  break;
4083 	case GL_UNSIGNED_BYTE_3_3_2:
4084 	case GL_UNSIGNED_BYTE_2_3_3_REV:
4085 	  dstImage = (GLubyte *)malloc(memreq);
4086 	  break;
4087 	case GL_UNSIGNED_SHORT_5_6_5:
4088 	case GL_UNSIGNED_SHORT_5_6_5_REV:
4089 	case GL_UNSIGNED_SHORT_4_4_4_4:
4090 	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4091 	case GL_UNSIGNED_SHORT_5_5_5_1:
4092 	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4093 	  dstImage = (GLushort *)malloc(memreq);
4094 	  break;
4095 	case GL_UNSIGNED_INT_8_8_8_8:
4096 	case GL_UNSIGNED_INT_8_8_8_8_REV:
4097 	case GL_UNSIGNED_INT_10_10_10_2:
4098 	case GL_UNSIGNED_INT_2_10_10_10_REV:
4099 	  dstImage = (GLuint *)malloc(memreq);
4100 	  break;
4101 	default:
4102 	  return GLU_INVALID_ENUM;
4103 	}
4104 	if (dstImage == NULL) {
4105 	  glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4106 	  glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4107 	  glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4108 	  glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4109 	  glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4110 	  free(srcImage);
4111 	  return GLU_OUT_OF_MEMORY;
4112 	}
4113 	/* level userLevel+1 is in srcImage; level userLevel already saved */
4114 	level = userLevel+1;
4115     } else { /* user's image is *not* nice power-of-2 sized square */
4116 	memreq = image_size(newwidth, newheight, format, type);
4117 	switch(type) {
4118 	    case GL_UNSIGNED_BYTE:
4119 		dstImage = (GLubyte *)malloc(memreq);
4120 		break;
4121 	    case GL_BYTE:
4122 		dstImage = (GLbyte *)malloc(memreq);
4123 		break;
4124 	    case GL_UNSIGNED_SHORT:
4125 		dstImage = (GLushort *)malloc(memreq);
4126 		break;
4127 	    case GL_SHORT:
4128 		dstImage = (GLshort *)malloc(memreq);
4129 		break;
4130 	    case GL_UNSIGNED_INT:
4131 		dstImage = (GLuint *)malloc(memreq);
4132 		break;
4133 	    case GL_INT:
4134 		dstImage = (GLint *)malloc(memreq);
4135 		break;
4136 	    case GL_FLOAT:
4137 		dstImage = (GLfloat *)malloc(memreq);
4138 		break;
4139 	    case GL_UNSIGNED_BYTE_3_3_2:
4140 	    case GL_UNSIGNED_BYTE_2_3_3_REV:
4141 		dstImage = (GLubyte *)malloc(memreq);
4142 		break;
4143 	    case GL_UNSIGNED_SHORT_5_6_5:
4144 	    case GL_UNSIGNED_SHORT_5_6_5_REV:
4145 	    case GL_UNSIGNED_SHORT_4_4_4_4:
4146 	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4147 	    case GL_UNSIGNED_SHORT_5_5_5_1:
4148 	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4149 		dstImage = (GLushort *)malloc(memreq);
4150 		break;
4151 	    case GL_UNSIGNED_INT_8_8_8_8:
4152 	    case GL_UNSIGNED_INT_8_8_8_8_REV:
4153 	    case GL_UNSIGNED_INT_10_10_10_2:
4154 	    case GL_UNSIGNED_INT_2_10_10_10_REV:
4155 		dstImage = (GLuint *)malloc(memreq);
4156 		break;
4157 	    default:
4158 		return GLU_INVALID_ENUM;
4159 	}
4160 
4161 	if (dstImage == NULL) {
4162 	    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4163 	    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4164 	    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4165 	    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4166 	    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4167 	    return GLU_OUT_OF_MEMORY;
4168 	}
4169 
4170 	switch(type) {
4171 	case GL_UNSIGNED_BYTE:
4172 	    scale_internal_ubyte(cmpts, width, height,
4173 				 (const GLubyte *)usersImage, newwidth, newheight,
4174 				 (GLubyte *)dstImage, element_size,
4175 				 rowsize, group_size);
4176 	    break;
4177 	case GL_BYTE:
4178 	    scale_internal_byte(cmpts, width, height,
4179 				(const GLbyte *)usersImage, newwidth, newheight,
4180 				(GLbyte *)dstImage, element_size,
4181 				rowsize, group_size);
4182 	    break;
4183 	case GL_UNSIGNED_SHORT:
4184 	    scale_internal_ushort(cmpts, width, height,
4185 				  (const GLushort *)usersImage, newwidth, newheight,
4186 				  (GLushort *)dstImage, element_size,
4187 				  rowsize, group_size, myswap_bytes);
4188 	    break;
4189 	case GL_SHORT:
4190 	    scale_internal_short(cmpts, width, height,
4191 				 (const GLshort *)usersImage, newwidth, newheight,
4192 				 (GLshort *)dstImage, element_size,
4193 				 rowsize, group_size, myswap_bytes);
4194 	    break;
4195 	case GL_UNSIGNED_INT:
4196 	    scale_internal_uint(cmpts, width, height,
4197 				(const GLuint *)usersImage, newwidth, newheight,
4198 				(GLuint *)dstImage, element_size,
4199 				rowsize, group_size, myswap_bytes);
4200 	    break;
4201 	case GL_INT:
4202 	    scale_internal_int(cmpts, width, height,
4203 			       (const GLint *)usersImage, newwidth, newheight,
4204 			       (GLint *)dstImage, element_size,
4205 			       rowsize, group_size, myswap_bytes);
4206 	    break;
4207 	case GL_FLOAT:
4208 	    scale_internal_float(cmpts, width, height,
4209 				 (const GLfloat *)usersImage, newwidth, newheight,
4210 				 (GLfloat *)dstImage, element_size,
4211 				 rowsize, group_size, myswap_bytes);
4212 	    break;
4213 	case GL_UNSIGNED_BYTE_3_3_2:
4214 	    scaleInternalPackedPixel(3,extract332,shove332,
4215 				     width, height,usersImage,
4216 				     newwidth,newheight,(void *)dstImage,
4217 				     element_size,rowsize,myswap_bytes);
4218 	    break;
4219 	case GL_UNSIGNED_BYTE_2_3_3_REV:
4220 	    scaleInternalPackedPixel(3,extract233rev,shove233rev,
4221 				     width, height,usersImage,
4222 				     newwidth,newheight,(void *)dstImage,
4223 				     element_size,rowsize,myswap_bytes);
4224 	    break;
4225 	case GL_UNSIGNED_SHORT_5_6_5:
4226 	    scaleInternalPackedPixel(3,extract565,shove565,
4227 				     width, height,usersImage,
4228 				     newwidth,newheight,(void *)dstImage,
4229 				     element_size,rowsize,myswap_bytes);
4230 	    break;
4231 	case GL_UNSIGNED_SHORT_5_6_5_REV:
4232 	    scaleInternalPackedPixel(3,extract565rev,shove565rev,
4233 				     width, height,usersImage,
4234 				     newwidth,newheight,(void *)dstImage,
4235 				     element_size,rowsize,myswap_bytes);
4236 	    break;
4237 	case GL_UNSIGNED_SHORT_4_4_4_4:
4238 	    scaleInternalPackedPixel(4,extract4444,shove4444,
4239 				     width, height,usersImage,
4240 				     newwidth,newheight,(void *)dstImage,
4241 				     element_size,rowsize,myswap_bytes);
4242 	    break;
4243 	case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4244 	    scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4245 				     width, height,usersImage,
4246 				     newwidth,newheight,(void *)dstImage,
4247 				     element_size,rowsize,myswap_bytes);
4248 	    break;
4249 	case GL_UNSIGNED_SHORT_5_5_5_1:
4250 	    scaleInternalPackedPixel(4,extract5551,shove5551,
4251 				     width, height,usersImage,
4252 				     newwidth,newheight,(void *)dstImage,
4253 				     element_size,rowsize,myswap_bytes);
4254 	    break;
4255 	case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4256 	    scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4257 				     width, height,usersImage,
4258 				     newwidth,newheight,(void *)dstImage,
4259 				     element_size,rowsize,myswap_bytes);
4260 	    break;
4261 	case GL_UNSIGNED_INT_8_8_8_8:
4262 	    scaleInternalPackedPixel(4,extract8888,shove8888,
4263 				     width, height,usersImage,
4264 				     newwidth,newheight,(void *)dstImage,
4265 				     element_size,rowsize,myswap_bytes);
4266 	    break;
4267 	case GL_UNSIGNED_INT_8_8_8_8_REV:
4268 	    scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4269 				     width, height,usersImage,
4270 				     newwidth,newheight,(void *)dstImage,
4271 				     element_size,rowsize,myswap_bytes);
4272 	    break;
4273 	case GL_UNSIGNED_INT_10_10_10_2:
4274 	    scaleInternalPackedPixel(4,extract1010102,shove1010102,
4275 				     width, height,usersImage,
4276 				     newwidth,newheight,(void *)dstImage,
4277 				     element_size,rowsize,myswap_bytes);
4278 	    break;
4279 	case GL_UNSIGNED_INT_2_10_10_10_REV:
4280 	    scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
4281 				     width, height,usersImage,
4282 				     newwidth,newheight,(void *)dstImage,
4283 				     element_size,rowsize,myswap_bytes);
4284 	    break;
4285 	default:
4286 	    assert(0);
4287 	    break;
4288 	}
4289 	myswap_bytes = 0;
4290 	rowsize = newwidth * group_size;
4291 	/* Swap dstImage and srcImage */
4292 	__GLU_SWAP_IMAGE(srcImage,dstImage);
4293 
4294 	if(levels != 0) { /* use as little memory as possible */
4295 	  {
4296 	     int nextWidth= newwidth/2;
4297 	     int nextHeight= newheight/2;
4298 	     if (nextWidth < 1) nextWidth= 1;
4299 	     if (nextHeight < 1) nextHeight= 1;
4300 
4301 	  memreq = image_size(nextWidth, nextHeight, format, type);
4302 	  }
4303 
4304 	  switch(type) {
4305 	  case GL_UNSIGNED_BYTE:
4306 	    dstImage = (GLubyte *)malloc(memreq);
4307 	    break;
4308 	  case GL_BYTE:
4309 	    dstImage = (GLbyte *)malloc(memreq);
4310 	    break;
4311 	  case GL_UNSIGNED_SHORT:
4312 	    dstImage = (GLushort *)malloc(memreq);
4313 	    break;
4314 	  case GL_SHORT:
4315 	    dstImage = (GLshort *)malloc(memreq);
4316 	    break;
4317 	  case GL_UNSIGNED_INT:
4318 	    dstImage = (GLuint *)malloc(memreq);
4319 	    break;
4320 	  case GL_INT:
4321 	    dstImage = (GLint *)malloc(memreq);
4322 	    break;
4323 	  case GL_FLOAT:
4324 	    dstImage = (GLfloat *)malloc(memreq);
4325 	    break;
4326 	  case GL_UNSIGNED_BYTE_3_3_2:
4327 	  case GL_UNSIGNED_BYTE_2_3_3_REV:
4328 	    dstImage = (GLubyte *)malloc(memreq);
4329 	    break;
4330 	  case GL_UNSIGNED_SHORT_5_6_5:
4331 	  case GL_UNSIGNED_SHORT_5_6_5_REV:
4332 	  case GL_UNSIGNED_SHORT_4_4_4_4:
4333 	  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4334 	  case GL_UNSIGNED_SHORT_5_5_5_1:
4335 	  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4336 	    dstImage = (GLushort *)malloc(memreq);
4337 	    break;
4338 	  case GL_UNSIGNED_INT_8_8_8_8:
4339 	  case GL_UNSIGNED_INT_8_8_8_8_REV:
4340 	  case GL_UNSIGNED_INT_10_10_10_2:
4341 	  case GL_UNSIGNED_INT_2_10_10_10_REV:
4342 	    dstImage = (GLuint *)malloc(memreq);
4343 	    break;
4344 	  default:
4345 	    return GLU_INVALID_ENUM;
4346 	  }
4347 	  if (dstImage == NULL) {
4348 	    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4349 	    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4350 	    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4351 	    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4352 	    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4353 	    free(srcImage);
4354 	    return GLU_OUT_OF_MEMORY;
4355 	  }
4356 	}
4357 	/* level userLevel is in srcImage; nothing saved yet */
4358 	level = userLevel;
4359     }
4360 
4361     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4362     if (baseLevel <= level && level <= maxLevel) {
4363     glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4364 		 format, type, (void *)srcImage);
4365     }
4366 
4367     level++; /* update current level for the loop */
4368     for (; level <= levels; level++) {
4369 	switch(type) {
4370 	    case GL_UNSIGNED_BYTE:
4371 		halveImage_ubyte(cmpts, newwidth, newheight,
4372 		(GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4373 		rowsize, group_size);
4374 		break;
4375 	    case GL_BYTE:
4376 		halveImage_byte(cmpts, newwidth, newheight,
4377 		(GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4378 		rowsize, group_size);
4379 		break;
4380 	    case GL_UNSIGNED_SHORT:
4381 		halveImage_ushort(cmpts, newwidth, newheight,
4382 		(GLushort *)srcImage, (GLushort *)dstImage, element_size,
4383 		rowsize, group_size, myswap_bytes);
4384 		break;
4385 	    case GL_SHORT:
4386 		halveImage_short(cmpts, newwidth, newheight,
4387 		(GLshort *)srcImage, (GLshort *)dstImage, element_size,
4388 		rowsize, group_size, myswap_bytes);
4389 		break;
4390 	    case GL_UNSIGNED_INT:
4391 		halveImage_uint(cmpts, newwidth, newheight,
4392 		(GLuint *)srcImage, (GLuint *)dstImage, element_size,
4393 		rowsize, group_size, myswap_bytes);
4394 		break;
4395 	    case GL_INT:
4396 		halveImage_int(cmpts, newwidth, newheight,
4397 		(GLint *)srcImage, (GLint *)dstImage, element_size,
4398 		rowsize, group_size, myswap_bytes);
4399 		break;
4400 	    case GL_FLOAT:
4401 		halveImage_float(cmpts, newwidth, newheight,
4402 		(GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4403 		rowsize, group_size, myswap_bytes);
4404 		break;
4405 	    case GL_UNSIGNED_BYTE_3_3_2:
4406 		halveImagePackedPixel(3,extract332,shove332,
4407 				      newwidth,newheight,
4408 				      srcImage,dstImage,element_size,rowsize,
4409 				      myswap_bytes);
4410 		break;
4411 	    case GL_UNSIGNED_BYTE_2_3_3_REV:
4412 		halveImagePackedPixel(3,extract233rev,shove233rev,
4413 				      newwidth,newheight,
4414 				      srcImage,dstImage,element_size,rowsize,
4415 				      myswap_bytes);
4416 		break;
4417 	    case GL_UNSIGNED_SHORT_5_6_5:
4418 		halveImagePackedPixel(3,extract565,shove565,
4419 				      newwidth,newheight,
4420 				      srcImage,dstImage,element_size,rowsize,
4421 				      myswap_bytes);
4422 		break;
4423 	    case GL_UNSIGNED_SHORT_5_6_5_REV:
4424 		halveImagePackedPixel(3,extract565rev,shove565rev,
4425 				      newwidth,newheight,
4426 				      srcImage,dstImage,element_size,rowsize,
4427 				      myswap_bytes);
4428 		break;
4429 	    case GL_UNSIGNED_SHORT_4_4_4_4:
4430 		halveImagePackedPixel(4,extract4444,shove4444,
4431 				      newwidth,newheight,
4432 				      srcImage,dstImage,element_size,rowsize,
4433 				      myswap_bytes);
4434 		break;
4435 	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4436 		halveImagePackedPixel(4,extract4444rev,shove4444rev,
4437 				      newwidth,newheight,
4438 				      srcImage,dstImage,element_size,rowsize,
4439 				      myswap_bytes);
4440 		break;
4441 	    case GL_UNSIGNED_SHORT_5_5_5_1:
4442 		halveImagePackedPixel(4,extract5551,shove5551,
4443 				      newwidth,newheight,
4444 				      srcImage,dstImage,element_size,rowsize,
4445 				      myswap_bytes);
4446 		break;
4447 	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4448 		halveImagePackedPixel(4,extract1555rev,shove1555rev,
4449 				      newwidth,newheight,
4450 				      srcImage,dstImage,element_size,rowsize,
4451 				      myswap_bytes);
4452 		break;
4453 	    case GL_UNSIGNED_INT_8_8_8_8:
4454 		halveImagePackedPixel(4,extract8888,shove8888,
4455 				      newwidth,newheight,
4456 				      srcImage,dstImage,element_size,rowsize,
4457 				      myswap_bytes);
4458 		break;
4459 	    case GL_UNSIGNED_INT_8_8_8_8_REV:
4460 		halveImagePackedPixel(4,extract8888rev,shove8888rev,
4461 				      newwidth,newheight,
4462 				      srcImage,dstImage,element_size,rowsize,
4463 				      myswap_bytes);
4464 		break;
4465 	    case GL_UNSIGNED_INT_10_10_10_2:
4466 		halveImagePackedPixel(4,extract1010102,shove1010102,
4467 				      newwidth,newheight,
4468 				      srcImage,dstImage,element_size,rowsize,
4469 				      myswap_bytes);
4470 		break;
4471 	    case GL_UNSIGNED_INT_2_10_10_10_REV:
4472 		halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4473 				      newwidth,newheight,
4474 				      srcImage,dstImage,element_size,rowsize,
4475 				      myswap_bytes);
4476 		break;
4477 	    default:
4478 		assert(0);
4479 		break;
4480 	}
4481 
4482 	__GLU_SWAP_IMAGE(srcImage,dstImage);
4483 
4484 	if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4485 	if (newheight > 1) newheight /= 2;
4486       {
4487        /* compute amount to pad per row, if any */
4488        int rowPad= rowsize % psm.unpack_alignment;
4489 
4490        /* should row be padded? */
4491        if (rowPad == 0) {	/* nope, row should not be padded */
4492 	   /* call tex image with srcImage untouched since it's not padded */
4493 	   if (baseLevel <= level && level <= maxLevel) {
4494 	   glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4495 	   format, type, (void *) srcImage);
4496 	   }
4497        }
4498        else {			/* yes, row should be padded */
4499 	  /* compute length of new row in bytes, including padding */
4500 	  int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4501 	  int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4502 
4503 	  /* allocate new image for mipmap of size newRowLength x newheight */
4504 	  void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
4505 	  if (newMipmapImage == NULL) {
4506 	     /* out of memory so return */
4507 	     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4508 	     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4509 	     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4510 	     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4511 	     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4512 	     return GLU_OUT_OF_MEMORY;
4513 	  }
4514 
4515 	  /* copy image from srcImage into newMipmapImage by rows */
4516 	  for (ii= 0,
4517 	       dstTrav= (unsigned char *) newMipmapImage,
4518 	       srcTrav= (unsigned char *) srcImage;
4519 	       ii< newheight;
4520 	       ii++,
4521 	       dstTrav+= newRowLength, /* make sure the correct distance... */
4522 	       srcTrav+= rowsize) {    /* ...is skipped */
4523 	     memcpy(dstTrav,srcTrav,rowsize);
4524 	     /* note that the pad bytes are not visited and will contain
4525 	      * garbage, which is ok.
4526 	      */
4527 	  }
4528 
4529 	  /* ...and use this new image for mipmapping instead */
4530 	  if (baseLevel <= level && level <= maxLevel) {
4531 	  glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4532 		       format, type, newMipmapImage);
4533 	  }
4534 	  free(newMipmapImage); /* don't forget to free it! */
4535        } /* else */
4536       }
4537     } /* for level */
4538     glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4539     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4540     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4541     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4542     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4543 
4544     free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4545     if (dstImage) { /* if it's non-rectangular and only 1 level */
4546       free(dstImage);
4547     }
4548     return 0;
4549 } /* gluBuild2DMipmapLevelsCore() */
4550 
4551 GLint GLAPIENTRY
gluBuild2DMipmapLevels(GLenum target,GLint internalFormat,GLsizei width,GLsizei height,GLenum format,GLenum type,GLint userLevel,GLint baseLevel,GLint maxLevel,const void * data)4552 gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
4553 			     GLsizei width, GLsizei height,
4554 			     GLenum format, GLenum type,
4555 			     GLint userLevel, GLint baseLevel, GLint maxLevel,
4556 			     const void *data)
4557 {
4558    int level, levels;
4559 
4560    int rc= checkMipmapArgs(internalFormat,format,type);
4561    if (rc != 0) return rc;
4562 
4563    if (width < 1 || height < 1) {
4564        return GLU_INVALID_VALUE;
4565    }
4566 
4567    levels = computeLog(width);
4568    level = computeLog(height);
4569    if (level > levels) levels=level;
4570 
4571    levels+= userLevel;
4572    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
4573       return GLU_INVALID_VALUE;
4574 
4575    return gluBuild2DMipmapLevelsCore(target, internalFormat,
4576 				     width, height,
4577 				     width, height,
4578 				     format, type,
4579 				     userLevel, baseLevel, maxLevel,
4580 				     data);
4581 } /* gluBuild2DMipmapLevels() */
4582 
4583 GLint GLAPIENTRY
gluBuild2DMipmaps(GLenum target,GLint internalFormat,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * data)4584 gluBuild2DMipmaps(GLenum target, GLint internalFormat,
4585 			GLsizei width, GLsizei height,
4586 			GLenum format, GLenum type,
4587 			const void *data)
4588 {
4589    GLint widthPowerOf2, heightPowerOf2;
4590    int level, levels;
4591 
4592    int rc= checkMipmapArgs(internalFormat,format,type);
4593    if (rc != 0) return rc;
4594 
4595    if (width < 1 || height < 1) {
4596        return GLU_INVALID_VALUE;
4597    }
4598 
4599    closestFit(target,width,height,internalFormat,format,type,
4600 	      &widthPowerOf2,&heightPowerOf2);
4601 
4602    levels = computeLog(widthPowerOf2);
4603    level = computeLog(heightPowerOf2);
4604    if (level > levels) levels=level;
4605 
4606    return gluBuild2DMipmapLevelsCore(target,internalFormat,
4607 				     width, height,
4608 				     widthPowerOf2,heightPowerOf2,
4609 				     format,type,
4610 				     0,0,levels,data);
4611 }  /* gluBuild2DMipmaps() */
4612 
4613 #if 0
4614 /*
4615 ** This routine is for the limited case in which
4616 **	type == GL_UNSIGNED_BYTE && format != index  &&
4617 **	unpack_alignment = 1 && unpack_swap_bytes == false
4618 **
4619 ** so all of the work data can be kept as ubytes instead of shorts.
4620 */
4621 static int fastBuild2DMipmaps(const PixelStorageModes *psm,
4622 		       GLenum target, GLint components, GLint width,
4623 		     GLint height, GLenum format,
4624 		     GLenum type, void *data)
4625 {
4626     GLint newwidth, newheight;
4627     GLint level, levels;
4628     GLubyte *newImage;
4629     GLint newImage_width;
4630     GLint newImage_height;
4631     GLubyte *otherImage;
4632     GLubyte *imageTemp;
4633     GLint memreq;
4634     GLint cmpts;
4635 
4636 
4637 #if 0
4638     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
4639     newwidth = nearestPower(width);
4640     if (newwidth > maxsize) newwidth = maxsize;
4641     newheight = nearestPower(height);
4642     if (newheight > maxsize) newheight = maxsize;
4643 #else
4644     closestFit(target,width,height,components,format,type,
4645 	       &newwidth,&newheight);
4646 #endif
4647     levels = computeLog(newwidth);
4648     level = computeLog(newheight);
4649     if (level > levels) levels=level;
4650 
4651     cmpts = elements_per_group(format,type);
4652 
4653     otherImage = NULL;
4654     /**
4655     ** No need to copy the user data if its in the packed correctly.
4656     ** Make sure that later routines don't change that data.
4657     */
4658     if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
4659 	newImage = (GLubyte *)data;
4660 	newImage_width = width;
4661 	newImage_height = height;
4662     } else {
4663 	GLint rowsize;
4664 	GLint groups_per_line;
4665 	GLint elements_per_line;
4666 	const GLubyte *start;
4667 	const GLubyte *iter;
4668 	GLubyte *iter2;
4669 	GLint i, j;
4670 
4671 	newImage = (GLubyte *)
4672 	    malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
4673 	newImage_width = width;
4674 	newImage_height = height;
4675 	if (newImage == NULL) {
4676 	    return GLU_OUT_OF_MEMORY;
4677 	}
4678 
4679 	/*
4680 	** Abbreviated version of fill_image for this restricted case.
4681 	*/
4682 	if (psm->unpack_row_length > 0) {
4683 	    groups_per_line = psm->unpack_row_length;
4684 	} else {
4685 	    groups_per_line = width;
4686 	}
4687 	rowsize = groups_per_line * cmpts;
4688 	elements_per_line = width * cmpts;
4689 	start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
4690 		psm->unpack_skip_pixels * cmpts;
4691 	iter2 = newImage;
4692 
4693 	for (i = 0; i < height; i++) {
4694 	    iter = start;
4695 	    for (j = 0; j < elements_per_line; j++) {
4696 		*iter2 = *iter;
4697 		iter++;
4698 		iter2++;
4699 	    }
4700 	    start += rowsize;
4701 	}
4702     }
4703 
4704 
4705     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4706     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
4707     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
4708     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
4709     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4710 
4711     for (level = 0; level <= levels; level++) {
4712 	if (newImage_width == newwidth && newImage_height == newheight) {
4713 	    /* Use newImage for this level */
4714 	    glTexImage2D(target, level, components, newImage_width,
4715 		    newImage_height, 0, format, GL_UNSIGNED_BYTE,
4716 		    (void *) newImage);
4717 	} else {
4718 	    if (otherImage == NULL) {
4719 		memreq =
4720 		    image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
4721 		otherImage = (GLubyte *) malloc(memreq);
4722 		if (otherImage == NULL) {
4723 		    glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4724 		    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4725 		    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4726 		    glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
4727 		    glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
4728 		    return GLU_OUT_OF_MEMORY;
4729 		}
4730 	    }
4731 /*
4732 	    scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4733 		    newImage, newwidth, newheight, otherImage);
4734 */
4735 	    /* Swap newImage and otherImage */
4736 	    imageTemp = otherImage;
4737 	    otherImage = newImage;
4738 	    newImage = imageTemp;
4739 
4740 	    newImage_width = newwidth;
4741 	    newImage_height = newheight;
4742 	    glTexImage2D(target, level, components, newImage_width,
4743 		    newImage_height, 0, format, GL_UNSIGNED_BYTE,
4744 		    (void *) newImage);
4745 	}
4746 	if (newwidth > 1) newwidth /= 2;
4747 	if (newheight > 1) newheight /= 2;
4748     }
4749     glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4750     glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4751     glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4752     glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
4753     glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
4754 
4755     if (newImage != (const GLubyte *)data) {
4756 	free((GLbyte *) newImage);
4757     }
4758     if (otherImage && otherImage != (const GLubyte *)data) {
4759 	free((GLbyte *) otherImage);
4760     }
4761     return 0;
4762 }
4763 #endif
4764 
4765 /*
4766  * Utility Routines
4767  */
elements_per_group(GLenum format,GLenum type)4768 static GLint elements_per_group(GLenum format, GLenum type)
4769 {
4770     /*
4771      * Return the number of elements per group of a specified format
4772      */
4773 
4774     /* If the type is packedpixels then answer is 1 (ignore format) */
4775     if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4776 	type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4777 	type == GL_UNSIGNED_SHORT_5_6_5 ||
4778 	type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4779 	type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4780 	type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4781 	type == GL_UNSIGNED_SHORT_5_5_5_1  ||
4782 	type == GL_UNSIGNED_SHORT_1_5_5_5_REV  ||
4783 	type == GL_UNSIGNED_INT_8_8_8_8 ||
4784 	type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4785 	type == GL_UNSIGNED_INT_10_10_10_2 ||
4786 	type == GL_UNSIGNED_INT_2_10_10_10_REV) {
4787 	return 1;
4788     }
4789 
4790     /* Types are not packed pixels, so get elements per group */
4791     switch(format) {
4792       case GL_RGB:
4793       case GL_BGR:
4794 	return 3;
4795       case GL_LUMINANCE_ALPHA:
4796 	return 2;
4797       case GL_RGBA:
4798       case GL_BGRA:
4799 	return 4;
4800       default:
4801 	return 1;
4802     }
4803 }
4804 
bytes_per_element(GLenum type)4805 static GLfloat bytes_per_element(GLenum type)
4806 {
4807     /*
4808      * Return the number of bytes per element, based on the element type
4809      */
4810     switch(type) {
4811       case GL_BITMAP:
4812 	return 1.0 / 8.0;
4813       case GL_UNSIGNED_SHORT:
4814 	return(sizeof(GLushort));
4815       case GL_SHORT:
4816 	return(sizeof(GLshort));
4817       case GL_UNSIGNED_BYTE:
4818 	return(sizeof(GLubyte));
4819       case GL_BYTE:
4820 	return(sizeof(GLbyte));
4821       case GL_INT:
4822 	return(sizeof(GLint));
4823       case GL_UNSIGNED_INT:
4824 	return(sizeof(GLuint));
4825       case GL_FLOAT:
4826 	return(sizeof(GLfloat));
4827       case GL_UNSIGNED_BYTE_3_3_2:
4828       case GL_UNSIGNED_BYTE_2_3_3_REV:
4829 	return(sizeof(GLubyte));
4830       case GL_UNSIGNED_SHORT_5_6_5:
4831       case GL_UNSIGNED_SHORT_5_6_5_REV:
4832       case GL_UNSIGNED_SHORT_4_4_4_4:
4833       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4834       case GL_UNSIGNED_SHORT_5_5_5_1:
4835       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4836 	return(sizeof(GLushort));
4837       case GL_UNSIGNED_INT_8_8_8_8:
4838       case GL_UNSIGNED_INT_8_8_8_8_REV:
4839       case GL_UNSIGNED_INT_10_10_10_2:
4840       case GL_UNSIGNED_INT_2_10_10_10_REV:
4841 	return(sizeof(GLuint));
4842       default:
4843 	return 4;
4844     }
4845 }
4846 
is_index(GLenum format)4847 static GLint is_index(GLenum format)
4848 {
4849     return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4850 }
4851 
4852 /*
4853 ** Compute memory required for internal packed array of data of given type
4854 ** and format.
4855 */
image_size(GLint width,GLint height,GLenum format,GLenum type)4856 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4857 {
4858     int bytes_per_row;
4859     int components;
4860 
4861 assert(width > 0);
4862 assert(height > 0);
4863     components = elements_per_group(format,type);
4864     if (type == GL_BITMAP) {
4865 	bytes_per_row = (width + 7) / 8;
4866     } else {
4867 	bytes_per_row = bytes_per_element(type) * width;
4868     }
4869     return bytes_per_row * height * components;
4870 }
4871 
4872 /*
4873 ** Extract array from user's data applying all pixel store modes.
4874 ** The internal format used is an array of unsigned shorts.
4875 */
fill_image(const PixelStorageModes * psm,GLint width,GLint height,GLenum format,GLenum type,GLboolean index_format,const void * userdata,GLushort * newimage)4876 static void fill_image(const PixelStorageModes *psm,
4877 		       GLint width, GLint height, GLenum format,
4878 		       GLenum type, GLboolean index_format,
4879 		       const void *userdata, GLushort *newimage)
4880 {
4881     GLint components;
4882     GLint element_size;
4883     GLint rowsize;
4884     GLint padding;
4885     GLint groups_per_line;
4886     GLint group_size;
4887     GLint elements_per_line;
4888     const GLubyte *start;
4889     const GLubyte *iter;
4890     GLushort *iter2;
4891     GLint i, j, k;
4892     GLint myswap_bytes;
4893 
4894     myswap_bytes = psm->unpack_swap_bytes;
4895     components = elements_per_group(format,type);
4896     if (psm->unpack_row_length > 0) {
4897 	groups_per_line = psm->unpack_row_length;
4898     } else {
4899 	groups_per_line = width;
4900     }
4901 
4902     /* All formats except GL_BITMAP fall out trivially */
4903     if (type == GL_BITMAP) {
4904 	GLint bit_offset;
4905 	GLint current_bit;
4906 
4907 	rowsize = (groups_per_line * components + 7) / 8;
4908 	padding = (rowsize % psm->unpack_alignment);
4909 	if (padding) {
4910 	    rowsize += psm->unpack_alignment - padding;
4911 	}
4912 	start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4913 		(psm->unpack_skip_pixels * components / 8);
4914 	elements_per_line = width * components;
4915 	iter2 = newimage;
4916 	for (i = 0; i < height; i++) {
4917 	    iter = start;
4918 	    bit_offset = (psm->unpack_skip_pixels * components) % 8;
4919 	    for (j = 0; j < elements_per_line; j++) {
4920 		/* Retrieve bit */
4921 		if (psm->unpack_lsb_first) {
4922 		    current_bit = iter[0] & (1 << bit_offset);
4923 		} else {
4924 		    current_bit = iter[0] & (1 << (7 - bit_offset));
4925 		}
4926 		if (current_bit) {
4927 		    if (index_format) {
4928 			*iter2 = 1;
4929 		    } else {
4930 			*iter2 = 65535;
4931 		    }
4932 		} else {
4933 		    *iter2 = 0;
4934 		}
4935 		bit_offset++;
4936 		if (bit_offset == 8) {
4937 		    bit_offset = 0;
4938 		    iter++;
4939 		}
4940 		iter2++;
4941 	    }
4942 	    start += rowsize;
4943 	}
4944     } else {
4945 	element_size = bytes_per_element(type);
4946 	group_size = element_size * components;
4947 	if (element_size == 1) myswap_bytes = 0;
4948 
4949 	rowsize = groups_per_line * group_size;
4950 	padding = (rowsize % psm->unpack_alignment);
4951 	if (padding) {
4952 	    rowsize += psm->unpack_alignment - padding;
4953 	}
4954 	start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4955 		psm->unpack_skip_pixels * group_size;
4956 	elements_per_line = width * components;
4957 
4958 	iter2 = newimage;
4959 	for (i = 0; i < height; i++) {
4960 	    iter = start;
4961 	    for (j = 0; j < elements_per_line; j++) {
4962 		Type_Widget widget;
4963 		float extractComponents[4];
4964 
4965 		switch(type) {
4966 		  case GL_UNSIGNED_BYTE_3_3_2:
4967 		    extract332(0,iter,extractComponents);
4968 		    for (k = 0; k < 3; k++) {
4969 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
4970 		    }
4971 		    break;
4972 		  case GL_UNSIGNED_BYTE_2_3_3_REV:
4973 		    extract233rev(0,iter,extractComponents);
4974 		    for (k = 0; k < 3; k++) {
4975 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
4976 		    }
4977 		    break;
4978 		  case GL_UNSIGNED_BYTE:
4979 		    if (index_format) {
4980 			*iter2++ = *iter;
4981 		    } else {
4982 			*iter2++ = (*iter) * 257;
4983 		    }
4984 		    break;
4985 		  case GL_BYTE:
4986 		    if (index_format) {
4987 			*iter2++ = *((const GLbyte *) iter);
4988 		    } else {
4989 			/* rough approx */
4990 			*iter2++ = (*((const GLbyte *) iter)) * 516;
4991 		    }
4992 		    break;
4993 		  case GL_UNSIGNED_SHORT_5_6_5:
4994 		    extract565(myswap_bytes,iter,extractComponents);
4995 		    for (k = 0; k < 3; k++) {
4996 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
4997 		    }
4998 		    break;
4999 		  case GL_UNSIGNED_SHORT_5_6_5_REV:
5000 		    extract565rev(myswap_bytes,iter,extractComponents);
5001 		    for (k = 0; k < 3; k++) {
5002 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5003 		    }
5004 		    break;
5005 		  case GL_UNSIGNED_SHORT_4_4_4_4:
5006 		    extract4444(myswap_bytes,iter,extractComponents);
5007 		    for (k = 0; k < 4; k++) {
5008 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5009 		    }
5010 		    break;
5011 		  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5012 		    extract4444rev(myswap_bytes,iter,extractComponents);
5013 		    for (k = 0; k < 4; k++) {
5014 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5015 		    }
5016 		    break;
5017 		  case GL_UNSIGNED_SHORT_5_5_5_1:
5018 		    extract5551(myswap_bytes,iter,extractComponents);
5019 		    for (k = 0; k < 4; k++) {
5020 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5021 		    }
5022 		    break;
5023 		  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5024 		    extract1555rev(myswap_bytes,iter,extractComponents);
5025 		    for (k = 0; k < 4; k++) {
5026 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5027 		    }
5028 		    break;
5029 		  case GL_UNSIGNED_SHORT:
5030 		  case GL_SHORT:
5031 		    if (myswap_bytes) {
5032 			widget.ub[0] = iter[1];
5033 			widget.ub[1] = iter[0];
5034 		    } else {
5035 			widget.ub[0] = iter[0];
5036 			widget.ub[1] = iter[1];
5037 		    }
5038 		    if (type == GL_SHORT) {
5039 			if (index_format) {
5040 			    *iter2++ = widget.s[0];
5041 			} else {
5042 			    /* rough approx */
5043 			    *iter2++ = widget.s[0]*2;
5044 			}
5045 		    } else {
5046 			*iter2++ = widget.us[0];
5047 		    }
5048 		    break;
5049 		  case GL_UNSIGNED_INT_8_8_8_8:
5050 		    extract8888(myswap_bytes,iter,extractComponents);
5051 		    for (k = 0; k < 4; k++) {
5052 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5053 		    }
5054 		    break;
5055 		  case GL_UNSIGNED_INT_8_8_8_8_REV:
5056 		    extract8888rev(myswap_bytes,iter,extractComponents);
5057 		    for (k = 0; k < 4; k++) {
5058 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5059 		    }
5060 		    break;
5061 		  case GL_UNSIGNED_INT_10_10_10_2:
5062 		    extract1010102(myswap_bytes,iter,extractComponents);
5063 		    for (k = 0; k < 4; k++) {
5064 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5065 		    }
5066 		    break;
5067 		  case GL_UNSIGNED_INT_2_10_10_10_REV:
5068 		    extract2101010rev(myswap_bytes,iter,extractComponents);
5069 		    for (k = 0; k < 4; k++) {
5070 		      *iter2++ = (GLushort)(extractComponents[k]*65535);
5071 		    }
5072 		    break;
5073 		  case GL_INT:
5074 		  case GL_UNSIGNED_INT:
5075 		  case GL_FLOAT:
5076 		    if (myswap_bytes) {
5077 			widget.ub[0] = iter[3];
5078 			widget.ub[1] = iter[2];
5079 			widget.ub[2] = iter[1];
5080 			widget.ub[3] = iter[0];
5081 		    } else {
5082 			widget.ub[0] = iter[0];
5083 			widget.ub[1] = iter[1];
5084 			widget.ub[2] = iter[2];
5085 			widget.ub[3] = iter[3];
5086 		    }
5087 		    if (type == GL_FLOAT) {
5088 			if (index_format) {
5089 			    *iter2++ = widget.f;
5090 			} else {
5091 			    *iter2++ = 65535 * widget.f;
5092 			}
5093 		    } else if (type == GL_UNSIGNED_INT) {
5094 			if (index_format) {
5095 			    *iter2++ = widget.ui;
5096 			} else {
5097 			    *iter2++ = widget.ui >> 16;
5098 			}
5099 		    } else {
5100 			if (index_format) {
5101 			    *iter2++ = widget.i;
5102 			} else {
5103 			    *iter2++ = widget.i >> 15;
5104 			}
5105 		    }
5106 		    break;
5107 		}
5108 		iter += element_size;
5109 	    } /* for j */
5110 	    start += rowsize;
5111 #if 1
5112 	    /* want 'iter' pointing at start, not within, row for assertion
5113 	     * purposes
5114 	     */
5115 	    iter= start;
5116 #endif
5117 	} /* for i */
5118 
5119        /* iterators should be one byte past end */
5120        if (!isTypePackedPixel(type)) {
5121 	  assert(iter2 == &newimage[width*height*components]);
5122        }
5123        else {
5124 	  assert(iter2 == &newimage[width*height*
5125 				    elements_per_group(format,0)]);
5126        }
5127        assert( iter == &((const GLubyte *)userdata)[rowsize*height +
5128 					psm->unpack_skip_rows * rowsize +
5129 					psm->unpack_skip_pixels * group_size] );
5130 
5131     } /* else */
5132 } /* fill_image() */
5133 
5134 /*
5135 ** Insert array into user's data applying all pixel store modes.
5136 ** The internal format is an array of unsigned shorts.
5137 ** empty_image() because it is the opposite of fill_image().
5138 */
empty_image(const PixelStorageModes * psm,GLint width,GLint height,GLenum format,GLenum type,GLboolean index_format,const GLushort * oldimage,void * userdata)5139 static void empty_image(const PixelStorageModes *psm,
5140 			GLint width, GLint height, GLenum format,
5141 			GLenum type, GLboolean index_format,
5142 			const GLushort *oldimage, void *userdata)
5143 {
5144     GLint components;
5145     GLint element_size;
5146     GLint rowsize;
5147     GLint padding;
5148     GLint groups_per_line;
5149     GLint group_size;
5150     GLint elements_per_line;
5151     GLubyte *start;
5152     GLubyte *iter;
5153     const GLushort *iter2;
5154     GLint i, j, k;
5155     GLint myswap_bytes;
5156 
5157     myswap_bytes = psm->pack_swap_bytes;
5158     components = elements_per_group(format,type);
5159     if (psm->pack_row_length > 0) {
5160 	groups_per_line = psm->pack_row_length;
5161     } else {
5162 	groups_per_line = width;
5163     }
5164 
5165     /* All formats except GL_BITMAP fall out trivially */
5166     if (type == GL_BITMAP) {
5167 	GLint bit_offset;
5168 	GLint current_bit;
5169 
5170 	rowsize = (groups_per_line * components + 7) / 8;
5171 	padding = (rowsize % psm->pack_alignment);
5172 	if (padding) {
5173 	    rowsize += psm->pack_alignment - padding;
5174 	}
5175 	start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5176 		(psm->pack_skip_pixels * components / 8);
5177 	elements_per_line = width * components;
5178 	iter2 = oldimage;
5179 	for (i = 0; i < height; i++) {
5180 	    iter = start;
5181 	    bit_offset = (psm->pack_skip_pixels * components) % 8;
5182 	    for (j = 0; j < elements_per_line; j++) {
5183 		if (index_format) {
5184 		    current_bit = iter2[0] & 1;
5185 		} else {
5186 		    if (iter2[0] > 32767) {
5187 			current_bit = 1;
5188 		    } else {
5189 			current_bit = 0;
5190 		    }
5191 		}
5192 
5193 		if (current_bit) {
5194 		    if (psm->pack_lsb_first) {
5195 			*iter |= (1 << bit_offset);
5196 		    } else {
5197 			*iter |= (1 << (7 - bit_offset));
5198 		    }
5199 		} else {
5200 		    if (psm->pack_lsb_first) {
5201 			*iter &= ~(1 << bit_offset);
5202 		    } else {
5203 			*iter &= ~(1 << (7 - bit_offset));
5204 		    }
5205 		}
5206 
5207 		bit_offset++;
5208 		if (bit_offset == 8) {
5209 		    bit_offset = 0;
5210 		    iter++;
5211 		}
5212 		iter2++;
5213 	    }
5214 	    start += rowsize;
5215 	}
5216     } else {
5217 	float shoveComponents[4];
5218 
5219 	element_size = bytes_per_element(type);
5220 	group_size = element_size * components;
5221 	if (element_size == 1) myswap_bytes = 0;
5222 
5223 	rowsize = groups_per_line * group_size;
5224 	padding = (rowsize % psm->pack_alignment);
5225 	if (padding) {
5226 	    rowsize += psm->pack_alignment - padding;
5227 	}
5228 	start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5229 		psm->pack_skip_pixels * group_size;
5230 	elements_per_line = width * components;
5231 
5232 	iter2 = oldimage;
5233 	for (i = 0; i < height; i++) {
5234 	    iter = start;
5235 	    for (j = 0; j < elements_per_line; j++) {
5236 		Type_Widget widget;
5237 
5238 		switch(type) {
5239 		  case GL_UNSIGNED_BYTE_3_3_2:
5240 		    for (k = 0; k < 3; k++) {
5241 		       shoveComponents[k]= *iter2++ / 65535.0;
5242 		    }
5243 		    shove332(shoveComponents,0,(void *)iter);
5244 		    break;
5245 		  case GL_UNSIGNED_BYTE_2_3_3_REV:
5246 		    for (k = 0; k < 3; k++) {
5247 		       shoveComponents[k]= *iter2++ / 65535.0;
5248 		    }
5249 		    shove233rev(shoveComponents,0,(void *)iter);
5250 		    break;
5251 		  case GL_UNSIGNED_BYTE:
5252 		    if (index_format) {
5253 			*iter = *iter2++;
5254 		    } else {
5255 			*iter = *iter2++ >> 8;
5256 		    }
5257 		    break;
5258 		  case GL_BYTE:
5259 		    if (index_format) {
5260 			*((GLbyte *) iter) = *iter2++;
5261 		    } else {
5262 			*((GLbyte *) iter) = *iter2++ >> 9;
5263 		    }
5264 		    break;
5265 		  case GL_UNSIGNED_SHORT_5_6_5:
5266 		    for (k = 0; k < 3; k++) {
5267 		       shoveComponents[k]= *iter2++ / 65535.0;
5268 		    }
5269 		    shove565(shoveComponents,0,(void *)&widget.us[0]);
5270 		    if (myswap_bytes) {
5271 		       iter[0] = widget.ub[1];
5272 		       iter[1] = widget.ub[0];
5273 		    }
5274 		    else {
5275 		       *(GLushort *)iter = widget.us[0];
5276 		    }
5277 		    break;
5278 		  case GL_UNSIGNED_SHORT_5_6_5_REV:
5279 		    for (k = 0; k < 3; k++) {
5280 		       shoveComponents[k]= *iter2++ / 65535.0;
5281 		    }
5282 		    shove565rev(shoveComponents,0,(void *)&widget.us[0]);
5283 		    if (myswap_bytes) {
5284 		       iter[0] = widget.ub[1];
5285 		       iter[1] = widget.ub[0];
5286 		    }
5287 		    else {
5288 		       *(GLushort *)iter = widget.us[0];
5289 		    }
5290 		    break;
5291 		  case GL_UNSIGNED_SHORT_4_4_4_4:
5292 		    for (k = 0; k < 4; k++) {
5293 		       shoveComponents[k]= *iter2++ / 65535.0;
5294 		    }
5295 		    shove4444(shoveComponents,0,(void *)&widget.us[0]);
5296 		    if (myswap_bytes) {
5297 		       iter[0] = widget.ub[1];
5298 		       iter[1] = widget.ub[0];
5299 		    } else {
5300 		       *(GLushort *)iter = widget.us[0];
5301 		    }
5302 		    break;
5303 		  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5304 		    for (k = 0; k < 4; k++) {
5305 		       shoveComponents[k]= *iter2++ / 65535.0;
5306 		    }
5307 		    shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
5308 		    if (myswap_bytes) {
5309 		       iter[0] = widget.ub[1];
5310 		       iter[1] = widget.ub[0];
5311 		    } else {
5312 		       *(GLushort *)iter = widget.us[0];
5313 		    }
5314 		    break;
5315 		  case GL_UNSIGNED_SHORT_5_5_5_1:
5316 		    for (k = 0; k < 4; k++) {
5317 		       shoveComponents[k]= *iter2++ / 65535.0;
5318 		    }
5319 		    shove5551(shoveComponents,0,(void *)&widget.us[0]);
5320 		    if (myswap_bytes) {
5321 		       iter[0] = widget.ub[1];
5322 		       iter[1] = widget.ub[0];
5323 		    } else {
5324 		       *(GLushort *)iter = widget.us[0];
5325 		    }
5326 		    break;
5327 		  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5328 		    for (k = 0; k < 4; k++) {
5329 		       shoveComponents[k]= *iter2++ / 65535.0;
5330 		    }
5331 		    shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
5332 		    if (myswap_bytes) {
5333 		       iter[0] = widget.ub[1];
5334 		       iter[1] = widget.ub[0];
5335 		    } else {
5336 		       *(GLushort *)iter = widget.us[0];
5337 		    }
5338 		    break;
5339 		  case GL_UNSIGNED_SHORT:
5340 		  case GL_SHORT:
5341 		    if (type == GL_SHORT) {
5342 			if (index_format) {
5343 			    widget.s[0] = *iter2++;
5344 			} else {
5345 			    widget.s[0] = *iter2++ >> 1;
5346 			}
5347 		    } else {
5348 			widget.us[0] = *iter2++;
5349 		    }
5350 		    if (myswap_bytes) {
5351 			iter[0] = widget.ub[1];
5352 			iter[1] = widget.ub[0];
5353 		    } else {
5354 			iter[0] = widget.ub[0];
5355 			iter[1] = widget.ub[1];
5356 		    }
5357 		    break;
5358 		  case GL_UNSIGNED_INT_8_8_8_8:
5359 		    for (k = 0; k < 4; k++) {
5360 		       shoveComponents[k]= *iter2++ / 65535.0;
5361 		    }
5362 		    shove8888(shoveComponents,0,(void *)&widget.ui);
5363 		    if (myswap_bytes) {
5364 			iter[3] = widget.ub[0];
5365 			iter[2] = widget.ub[1];
5366 			iter[1] = widget.ub[2];
5367 			iter[0] = widget.ub[3];
5368 		    } else {
5369 			*(GLuint *)iter= widget.ui;
5370 		    }
5371 
5372 		    break;
5373 		  case GL_UNSIGNED_INT_8_8_8_8_REV:
5374 		    for (k = 0; k < 4; k++) {
5375 		       shoveComponents[k]= *iter2++ / 65535.0;
5376 		    }
5377 		    shove8888rev(shoveComponents,0,(void *)&widget.ui);
5378 		    if (myswap_bytes) {
5379 			iter[3] = widget.ub[0];
5380 			iter[2] = widget.ub[1];
5381 			iter[1] = widget.ub[2];
5382 			iter[0] = widget.ub[3];
5383 		    } else {
5384 			*(GLuint *)iter= widget.ui;
5385 		    }
5386 		    break;
5387 		  case GL_UNSIGNED_INT_10_10_10_2:
5388 		    for (k = 0; k < 4; k++) {
5389 		       shoveComponents[k]= *iter2++ / 65535.0;
5390 		    }
5391 		    shove1010102(shoveComponents,0,(void *)&widget.ui);
5392 		    if (myswap_bytes) {
5393 			iter[3] = widget.ub[0];
5394 			iter[2] = widget.ub[1];
5395 			iter[1] = widget.ub[2];
5396 			iter[0] = widget.ub[3];
5397 		    } else {
5398 			*(GLuint *)iter= widget.ui;
5399 		    }
5400 		    break;
5401 		  case GL_UNSIGNED_INT_2_10_10_10_REV:
5402 		    for (k = 0; k < 4; k++) {
5403 		       shoveComponents[k]= *iter2++ / 65535.0;
5404 		    }
5405 		    shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5406 		    if (myswap_bytes) {
5407 			iter[3] = widget.ub[0];
5408 			iter[2] = widget.ub[1];
5409 			iter[1] = widget.ub[2];
5410 			iter[0] = widget.ub[3];
5411 		    } else {
5412 			*(GLuint *)iter= widget.ui;
5413 		    }
5414 		    break;
5415 		  case GL_INT:
5416 		  case GL_UNSIGNED_INT:
5417 		  case GL_FLOAT:
5418 		    if (type == GL_FLOAT) {
5419 			if (index_format) {
5420 			    widget.f = *iter2++;
5421 			} else {
5422 			    widget.f = *iter2++ / (float) 65535.0;
5423 			}
5424 		    } else if (type == GL_UNSIGNED_INT) {
5425 			if (index_format) {
5426 			    widget.ui = *iter2++;
5427 			} else {
5428 			    widget.ui = (unsigned int) *iter2++ * 65537;
5429 			}
5430 		    } else {
5431 			if (index_format) {
5432 			    widget.i = *iter2++;
5433 			} else {
5434 			    widget.i = ((unsigned int) *iter2++ * 65537)/2;
5435 			}
5436 		    }
5437 		    if (myswap_bytes) {
5438 			iter[3] = widget.ub[0];
5439 			iter[2] = widget.ub[1];
5440 			iter[1] = widget.ub[2];
5441 			iter[0] = widget.ub[3];
5442 		    } else {
5443 			iter[0] = widget.ub[0];
5444 			iter[1] = widget.ub[1];
5445 			iter[2] = widget.ub[2];
5446 			iter[3] = widget.ub[3];
5447 		    }
5448 		    break;
5449 		}
5450 		iter += element_size;
5451 	    } /* for j */
5452 	    start += rowsize;
5453 #if 1
5454 	    /* want 'iter' pointing at start, not within, row for assertion
5455 	     * purposes
5456 	     */
5457 	    iter= start;
5458 #endif
5459 	} /* for i */
5460 
5461 	/* iterators should be one byte past end */
5462 	if (!isTypePackedPixel(type)) {
5463 	   assert(iter2 == &oldimage[width*height*components]);
5464 	}
5465 	else {
5466 	   assert(iter2 == &oldimage[width*height*
5467 				     elements_per_group(format,0)]);
5468 	}
5469 	assert( iter == &((GLubyte *)userdata)[rowsize*height +
5470 					psm->pack_skip_rows * rowsize +
5471 					psm->pack_skip_pixels * group_size] );
5472 
5473     } /* else */
5474 } /* empty_image() */
5475 
5476 /*--------------------------------------------------------------------------
5477  * Decimation of packed pixel types
5478  *--------------------------------------------------------------------------
5479  */
extract332(int isSwap,const void * packedPixel,GLfloat extractComponents[])5480 static void extract332(int isSwap,
5481 		       const void *packedPixel, GLfloat extractComponents[])
5482 {
5483    GLubyte ubyte= *(const GLubyte *)packedPixel;
5484 
5485    isSwap= isSwap;		/* turn off warnings */
5486 
5487    /* 11100000 == 0xe0 */
5488    /* 00011100 == 0x1c */
5489    /* 00000011 == 0x03 */
5490 
5491    extractComponents[0]=   (float)((ubyte & 0xe0)  >> 5) / 7.0;
5492    extractComponents[1]=   (float)((ubyte & 0x1c)  >> 2) / 7.0; /* 7 = 2^3-1 */
5493    extractComponents[2]=   (float)((ubyte & 0x03)      ) / 3.0; /* 3 = 2^2-1 */
5494 } /* extract332() */
5495 
shove332(const GLfloat shoveComponents[],int index,void * packedPixel)5496 static void shove332(const GLfloat shoveComponents[],
5497 		     int index, void *packedPixel)
5498 {
5499    /* 11100000 == 0xe0 */
5500    /* 00011100 == 0x1c */
5501    /* 00000011 == 0x03 */
5502 
5503    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5504    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5505    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5506 
5507    /* due to limited precision, need to round before shoving */
5508    ((GLubyte *)packedPixel)[index]  =
5509      ((GLubyte)((shoveComponents[0] * 7)+0.5)  << 5) & 0xe0;
5510    ((GLubyte *)packedPixel)[index] |=
5511      ((GLubyte)((shoveComponents[1] * 7)+0.5)  << 2) & 0x1c;
5512    ((GLubyte *)packedPixel)[index]  |=
5513      ((GLubyte)((shoveComponents[2] * 3)+0.5)	   ) & 0x03;
5514 } /* shove332() */
5515 
extract233rev(int isSwap,const void * packedPixel,GLfloat extractComponents[])5516 static void extract233rev(int isSwap,
5517 			  const void *packedPixel, GLfloat extractComponents[])
5518 {
5519    GLubyte ubyte= *(const GLubyte *)packedPixel;
5520 
5521    isSwap= isSwap;		/* turn off warnings */
5522 
5523    /* 0000,0111 == 0x07 */
5524    /* 0011,1000 == 0x38 */
5525    /* 1100,0000 == 0xC0 */
5526 
5527    extractComponents[0]= (float)((ubyte & 0x07)     ) / 7.0;
5528    extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5529    extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5530 } /* extract233rev() */
5531 
shove233rev(const GLfloat shoveComponents[],int index,void * packedPixel)5532 static void shove233rev(const GLfloat shoveComponents[],
5533 			int index, void *packedPixel)
5534 {
5535    /* 0000,0111 == 0x07 */
5536    /* 0011,1000 == 0x38 */
5537    /* 1100,0000 == 0xC0 */
5538 
5539    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5540    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5541    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5542 
5543    /* due to limited precision, need to round before shoving */
5544    ((GLubyte *)packedPixel)[index] =
5545      ((GLubyte)((shoveComponents[0] * 7.0)+0.5)     ) & 0x07;
5546    ((GLubyte *)packedPixel)[index]|=
5547      ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5548    ((GLubyte *)packedPixel)[index]|=
5549      ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5550 } /* shove233rev() */
5551 
extract565(int isSwap,const void * packedPixel,GLfloat extractComponents[])5552 static void extract565(int isSwap,
5553 		       const void *packedPixel, GLfloat extractComponents[])
5554 {
5555    GLushort ushort;
5556 
5557    if (isSwap) {
5558      ushort= __GLU_SWAP_2_BYTES(packedPixel);
5559    }
5560    else {
5561      ushort= *(const GLushort *)packedPixel;
5562    }
5563 
5564    /* 11111000,00000000 == 0xf800 */
5565    /* 00000111,11100000 == 0x07e0 */
5566    /* 00000000,00011111 == 0x001f */
5567 
5568    extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5569    extractComponents[1]=(float)((ushort & 0x07e0) >>  5) / 63.0;/* 63 = 2^6-1*/
5570    extractComponents[2]=(float)((ushort & 0x001f)      ) / 31.0;
5571 } /* extract565() */
5572 
shove565(const GLfloat shoveComponents[],int index,void * packedPixel)5573 static void shove565(const GLfloat shoveComponents[],
5574 		     int index,void *packedPixel)
5575 {
5576    /* 11111000,00000000 == 0xf800 */
5577    /* 00000111,11100000 == 0x07e0 */
5578    /* 00000000,00011111 == 0x001f */
5579 
5580    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5581    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5582    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5583 
5584    /* due to limited precision, need to round before shoving */
5585    ((GLushort *)packedPixel)[index] =
5586      ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5587    ((GLushort *)packedPixel)[index]|=
5588      ((GLushort)((shoveComponents[1] * 63)+0.5) <<  5) & 0x07e0;
5589    ((GLushort *)packedPixel)[index]|=
5590      ((GLushort)((shoveComponents[2] * 31)+0.5)      ) & 0x001f;
5591 } /* shove565() */
5592 
extract565rev(int isSwap,const void * packedPixel,GLfloat extractComponents[])5593 static void extract565rev(int isSwap,
5594 			  const void *packedPixel, GLfloat extractComponents[])
5595 {
5596    GLushort ushort;
5597 
5598    if (isSwap) {
5599      ushort= __GLU_SWAP_2_BYTES(packedPixel);
5600    }
5601    else {
5602      ushort= *(const GLushort *)packedPixel;
5603    }
5604 
5605    /* 00000000,00011111 == 0x001f */
5606    /* 00000111,11100000 == 0x07e0 */
5607    /* 11111000,00000000 == 0xf800 */
5608 
5609    extractComponents[0]= (float)((ushort & 0x001F)	) / 31.0;
5610    extractComponents[1]= (float)((ushort & 0x07E0) >>  5) / 63.0;
5611    extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5612 } /* extract565rev() */
5613 
shove565rev(const GLfloat shoveComponents[],int index,void * packedPixel)5614 static void shove565rev(const GLfloat shoveComponents[],
5615 			int index,void *packedPixel)
5616 {
5617    /* 00000000,00011111 == 0x001f */
5618    /* 00000111,11100000 == 0x07e0 */
5619    /* 11111000,00000000 == 0xf800 */
5620 
5621    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5622    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5623    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5624 
5625    /* due to limited precision, need to round before shoving */
5626    ((GLushort *)packedPixel)[index] =
5627      ((GLushort)((shoveComponents[0] * 31.0)+0.5)      ) & 0x001F;
5628    ((GLushort *)packedPixel)[index]|=
5629      ((GLushort)((shoveComponents[1] * 63.0)+0.5) <<  5) & 0x07E0;
5630    ((GLushort *)packedPixel)[index]|=
5631      ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5632 } /* shove565rev() */
5633 
extract4444(int isSwap,const void * packedPixel,GLfloat extractComponents[])5634 static void extract4444(int isSwap,const void *packedPixel,
5635 			GLfloat extractComponents[])
5636 {
5637    GLushort ushort;
5638 
5639    if (isSwap) {
5640      ushort= __GLU_SWAP_2_BYTES(packedPixel);
5641    }
5642    else {
5643      ushort= *(const GLushort *)packedPixel;
5644    }
5645 
5646    /* 11110000,00000000 == 0xf000 */
5647    /* 00001111,00000000 == 0x0f00 */
5648    /* 00000000,11110000 == 0x00f0 */
5649    /* 00000000,00001111 == 0x000f */
5650 
5651    extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5652    extractComponents[1]= (float)((ushort & 0x0f00) >>  8) / 15.0;
5653    extractComponents[2]= (float)((ushort & 0x00f0) >>  4) / 15.0;
5654    extractComponents[3]= (float)((ushort & 0x000f)	) / 15.0;
5655 } /* extract4444() */
5656 
shove4444(const GLfloat shoveComponents[],int index,void * packedPixel)5657 static void shove4444(const GLfloat shoveComponents[],
5658 		      int index,void *packedPixel)
5659 {
5660    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5661    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5662    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5663    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5664 
5665    /* due to limited precision, need to round before shoving */
5666    ((GLushort *)packedPixel)[index] =
5667      ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5668    ((GLushort *)packedPixel)[index]|=
5669      ((GLushort)((shoveComponents[1] * 15)+0.5) <<  8) & 0x0f00;
5670    ((GLushort *)packedPixel)[index]|=
5671      ((GLushort)((shoveComponents[2] * 15)+0.5) <<  4) & 0x00f0;
5672    ((GLushort *)packedPixel)[index]|=
5673      ((GLushort)((shoveComponents[3] * 15)+0.5)      ) & 0x000f;
5674 } /* shove4444() */
5675 
extract4444rev(int isSwap,const void * packedPixel,GLfloat extractComponents[])5676 static void extract4444rev(int isSwap,const void *packedPixel,
5677 			   GLfloat extractComponents[])
5678 {
5679    GLushort ushort;
5680 
5681    if (isSwap) {
5682      ushort= __GLU_SWAP_2_BYTES(packedPixel);
5683    }
5684    else {
5685      ushort= *(const GLushort *)packedPixel;
5686    }
5687 
5688    /* 00000000,00001111 == 0x000f */
5689    /* 00000000,11110000 == 0x00f0 */
5690    /* 00001111,00000000 == 0x0f00 */
5691    /* 11110000,00000000 == 0xf000 */
5692 
5693    /* 15 = 2^4-1 */
5694    extractComponents[0]= (float)((ushort & 0x000F)	) / 15.0;
5695    extractComponents[1]= (float)((ushort & 0x00F0) >>  4) / 15.0;
5696    extractComponents[2]= (float)((ushort & 0x0F00) >>  8) / 15.0;
5697    extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5698 } /* extract4444rev() */
5699 
shove4444rev(const GLfloat shoveComponents[],int index,void * packedPixel)5700 static void shove4444rev(const GLfloat shoveComponents[],
5701 			 int index,void *packedPixel)
5702 {
5703    /* 00000000,00001111 == 0x000f */
5704    /* 00000000,11110000 == 0x00f0 */
5705    /* 00001111,00000000 == 0x0f00 */
5706    /* 11110000,00000000 == 0xf000 */
5707 
5708    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5709    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5710    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5711    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5712 
5713    /* due to limited precision, need to round before shoving */
5714    ((GLushort *)packedPixel)[index] =
5715      ((GLushort)((shoveComponents[0] * 15)+0.5)      ) & 0x000F;
5716    ((GLushort *)packedPixel)[index]|=
5717      ((GLushort)((shoveComponents[1] * 15)+0.5) <<  4) & 0x00F0;
5718    ((GLushort *)packedPixel)[index]|=
5719      ((GLushort)((shoveComponents[2] * 15)+0.5) <<  8) & 0x0F00;
5720    ((GLushort *)packedPixel)[index]|=
5721      ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5722 } /* shove4444rev() */
5723 
extract5551(int isSwap,const void * packedPixel,GLfloat extractComponents[])5724 static void extract5551(int isSwap,const void *packedPixel,
5725 			GLfloat extractComponents[])
5726 {
5727    GLushort ushort;
5728 
5729    if (isSwap) {
5730      ushort= __GLU_SWAP_2_BYTES(packedPixel);
5731    }
5732    else {
5733      ushort= *(const GLushort *)packedPixel;
5734    }
5735 
5736    /* 11111000,00000000 == 0xf800 */
5737    /* 00000111,11000000 == 0x07c0 */
5738    /* 00000000,00111110 == 0x003e */
5739    /* 00000000,00000001 == 0x0001 */
5740 
5741    extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5742    extractComponents[1]=(float)((ushort & 0x07c0) >>  6) / 31.0;
5743    extractComponents[2]=(float)((ushort & 0x003e) >>  1) / 31.0;
5744    extractComponents[3]=(float)((ushort & 0x0001)      );
5745 } /* extract5551() */
5746 
shove5551(const GLfloat shoveComponents[],int index,void * packedPixel)5747 static void shove5551(const GLfloat shoveComponents[],
5748 		      int index,void *packedPixel)
5749 {
5750    /* 11111000,00000000 == 0xf800 */
5751    /* 00000111,11000000 == 0x07c0 */
5752    /* 00000000,00111110 == 0x003e */
5753    /* 00000000,00000001 == 0x0001 */
5754 
5755    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5756    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5757    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5758    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5759 
5760    /* due to limited precision, need to round before shoving */
5761    ((GLushort *)packedPixel)[index]  =
5762      ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5763    ((GLushort *)packedPixel)[index]|=
5764      ((GLushort)((shoveComponents[1] * 31)+0.5) <<  6) & 0x07c0;
5765    ((GLushort *)packedPixel)[index]|=
5766      ((GLushort)((shoveComponents[2] * 31)+0.5) <<  1) & 0x003e;
5767    ((GLushort *)packedPixel)[index]|=
5768      ((GLushort)((shoveComponents[3])+0.5)	     ) & 0x0001;
5769 } /* shove5551() */
5770 
extract1555rev(int isSwap,const void * packedPixel,GLfloat extractComponents[])5771 static void extract1555rev(int isSwap,const void *packedPixel,
5772 			   GLfloat extractComponents[])
5773 {
5774    GLushort ushort;
5775 
5776    if (isSwap) {
5777      ushort= __GLU_SWAP_2_BYTES(packedPixel);
5778    }
5779    else {
5780      ushort= *(const GLushort *)packedPixel;
5781    }
5782 
5783    /* 00000000,00011111 == 0x001F */
5784    /* 00000011,11100000 == 0x03E0 */
5785    /* 01111100,00000000 == 0x7C00 */
5786    /* 10000000,00000000 == 0x8000 */
5787 
5788    /* 31 = 2^5-1 */
5789    extractComponents[0]= (float)((ushort & 0x001F)	) / 31.0;
5790    extractComponents[1]= (float)((ushort & 0x03E0) >>  5) / 31.0;
5791    extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5792    extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5793 } /* extract1555rev() */
5794 
shove1555rev(const GLfloat shoveComponents[],int index,void * packedPixel)5795 static void shove1555rev(const GLfloat shoveComponents[],
5796 			 int index,void *packedPixel)
5797 {
5798    /* 00000000,00011111 == 0x001F */
5799    /* 00000011,11100000 == 0x03E0 */
5800    /* 01111100,00000000 == 0x7C00 */
5801    /* 10000000,00000000 == 0x8000 */
5802 
5803    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5804    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5805    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5806    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5807 
5808    /* due to limited precision, need to round before shoving */
5809    ((GLushort *)packedPixel)[index] =
5810      ((GLushort)((shoveComponents[0] * 31)+0.5)      ) & 0x001F;
5811    ((GLushort *)packedPixel)[index]|=
5812      ((GLushort)((shoveComponents[1] * 31)+0.5) <<  5) & 0x03E0;
5813    ((GLushort *)packedPixel)[index]|=
5814      ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5815    ((GLushort *)packedPixel)[index]|=
5816      ((GLushort)((shoveComponents[3])+0.5)	<< 15) & 0x8000;
5817 } /* shove1555rev() */
5818 
extract8888(int isSwap,const void * packedPixel,GLfloat extractComponents[])5819 static void extract8888(int isSwap,
5820 			const void *packedPixel, GLfloat extractComponents[])
5821 {
5822    GLuint uint;
5823 
5824    if (isSwap) {
5825      uint= __GLU_SWAP_4_BYTES(packedPixel);
5826    }
5827    else {
5828      uint= *(const GLuint *)packedPixel;
5829    }
5830 
5831    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5832    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5833    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5834    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5835 
5836    /* 255 = 2^8-1 */
5837    extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5838    extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5839    extractComponents[2]= (float)((uint & 0x0000ff00) >>  8) / 255.0;
5840    extractComponents[3]= (float)((uint & 0x000000ff)	  ) / 255.0;
5841 } /* extract8888() */
5842 
shove8888(const GLfloat shoveComponents[],int index,void * packedPixel)5843 static void shove8888(const GLfloat shoveComponents[],
5844 		      int index,void *packedPixel)
5845 {
5846    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5847    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5848    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5849    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5850 
5851    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5852    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5853    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5854    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5855 
5856    /* due to limited precision, need to round before shoving */
5857    ((GLuint *)packedPixel)[index] =
5858      ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5859    ((GLuint *)packedPixel)[index]|=
5860      ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5861    ((GLuint *)packedPixel)[index]|=
5862      ((GLuint)((shoveComponents[2] * 255)+0.5) <<  8) & 0x0000ff00;
5863    ((GLuint *)packedPixel)[index]|=
5864      ((GLuint)((shoveComponents[3] * 255)+0.5)	    ) & 0x000000ff;
5865 } /* shove8888() */
5866 
extract8888rev(int isSwap,const void * packedPixel,GLfloat extractComponents[])5867 static void extract8888rev(int isSwap,
5868 			   const void *packedPixel,GLfloat extractComponents[])
5869 {
5870    GLuint uint;
5871 
5872    if (isSwap) {
5873      uint= __GLU_SWAP_4_BYTES(packedPixel);
5874    }
5875    else {
5876      uint= *(const GLuint *)packedPixel;
5877    }
5878 
5879    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5880    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5881    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5882    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5883 
5884    /* 255 = 2^8-1 */
5885    extractComponents[0]= (float)((uint & 0x000000FF)	  ) / 255.0;
5886    extractComponents[1]= (float)((uint & 0x0000FF00) >>  8) / 255.0;
5887    extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5888    extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5889 } /* extract8888rev() */
5890 
shove8888rev(const GLfloat shoveComponents[],int index,void * packedPixel)5891 static void shove8888rev(const GLfloat shoveComponents[],
5892 			 int index,void *packedPixel)
5893 {
5894    /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5895    /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5896    /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5897    /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5898 
5899    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5900    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5901    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5902    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5903 
5904    /* due to limited precision, need to round before shoving */
5905    ((GLuint *)packedPixel)[index] =
5906      ((GLuint)((shoveComponents[0] * 255)+0.5)	    ) & 0x000000FF;
5907    ((GLuint *)packedPixel)[index]|=
5908      ((GLuint)((shoveComponents[1] * 255)+0.5) <<  8) & 0x0000FF00;
5909    ((GLuint *)packedPixel)[index]|=
5910      ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5911    ((GLuint *)packedPixel)[index]|=
5912      ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5913 } /* shove8888rev() */
5914 
extract1010102(int isSwap,const void * packedPixel,GLfloat extractComponents[])5915 static void extract1010102(int isSwap,
5916 			   const void *packedPixel,GLfloat extractComponents[])
5917 {
5918    GLuint uint;
5919 
5920    if (isSwap) {
5921      uint= __GLU_SWAP_4_BYTES(packedPixel);
5922    }
5923    else {
5924      uint= *(const GLuint *)packedPixel;
5925    }
5926 
5927    /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5928    /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5929    /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5930    /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5931 
5932    /* 1023 = 2^10-1 */
5933    extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5934    extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5935    extractComponents[2]= (float)((uint & 0x00000ffc) >>  2) / 1023.0;
5936    extractComponents[3]= (float)((uint & 0x00000003)	  ) / 3.0;
5937 } /* extract1010102() */
5938 
shove1010102(const GLfloat shoveComponents[],int index,void * packedPixel)5939 static void shove1010102(const GLfloat shoveComponents[],
5940 			 int index,void *packedPixel)
5941 {
5942    /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5943    /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5944    /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5945    /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5946 
5947    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5948    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5949    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5950    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5951 
5952    /* due to limited precision, need to round before shoving */
5953    ((GLuint *)packedPixel)[index] =
5954      ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5955    ((GLuint *)packedPixel)[index]|=
5956      ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5957    ((GLuint *)packedPixel)[index]|=
5958      ((GLuint)((shoveComponents[2] * 1023)+0.5) <<  2) & 0x00000ffc;
5959    ((GLuint *)packedPixel)[index]|=
5960      ((GLuint)((shoveComponents[3] * 3)+0.5)	     ) & 0x00000003;
5961 } /* shove1010102() */
5962 
extract2101010rev(int isSwap,const void * packedPixel,GLfloat extractComponents[])5963 static void extract2101010rev(int isSwap,
5964 			      const void *packedPixel,
5965 			      GLfloat extractComponents[])
5966 {
5967    GLuint uint;
5968 
5969    if (isSwap) {
5970      uint= __GLU_SWAP_4_BYTES(packedPixel);
5971    }
5972    else {
5973      uint= *(const GLuint *)packedPixel;
5974    }
5975 
5976    /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5977    /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5978    /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5979    /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5980 
5981    /* 1023 = 2^10-1 */
5982    extractComponents[0]= (float)((uint & 0x000003FF)	  ) / 1023.0;
5983    extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5984    extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5985    extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5986    /* 3 = 2^2-1 */
5987 } /* extract2101010rev() */
5988 
shove2101010rev(const GLfloat shoveComponents[],int index,void * packedPixel)5989 static void shove2101010rev(const GLfloat shoveComponents[],
5990 			    int index,void *packedPixel)
5991 {
5992    /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5993    /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5994    /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5995    /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5996 
5997    assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5998    assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5999    assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
6000    assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
6001 
6002    /* due to limited precision, need to round before shoving */
6003    ((GLuint *)packedPixel)[index] =
6004      ((GLuint)((shoveComponents[0] * 1023)+0.5)      ) & 0x000003FF;
6005    ((GLuint *)packedPixel)[index]|=
6006      ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
6007    ((GLuint *)packedPixel)[index]|=
6008      ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
6009    ((GLuint *)packedPixel)[index]|=
6010      ((GLuint)((shoveComponents[3] * 3)+0.5)	<< 30) & 0xC0000000;
6011 } /* shove2101010rev() */
6012 
scaleInternalPackedPixel(int components,void (* extractPackedPixel)(int,const void *,GLfloat[]),void (* shovePackedPixel)(const GLfloat[],int,void *),GLint widthIn,GLint heightIn,const void * dataIn,GLint widthOut,GLint heightOut,void * dataOut,GLint pixelSizeInBytes,GLint rowSizeInBytes,GLint isSwap)6013 static void scaleInternalPackedPixel(int components,
6014 				     void (*extractPackedPixel)
6015 				     (int, const void *,GLfloat []),
6016 				     void (*shovePackedPixel)
6017 				     (const GLfloat [], int, void *),
6018 				     GLint widthIn,GLint heightIn,
6019 				     const void *dataIn,
6020 				     GLint widthOut,GLint heightOut,
6021 				     void *dataOut,
6022 				     GLint pixelSizeInBytes,
6023 				     GLint rowSizeInBytes,GLint isSwap)
6024 {
6025     float convx;
6026     float convy;
6027     float percent;
6028 
6029     /* Max components in a format is 4, so... */
6030     float totals[4];
6031     float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
6032 
6033     float area;
6034     int i,j,k,xindex;
6035 
6036     const char *temp, *temp0;
6037     int outindex;
6038 
6039     int lowx_int, highx_int, lowy_int, highy_int;
6040     float x_percent, y_percent;
6041     float lowx_float, highx_float, lowy_float, highy_float;
6042     float convy_float, convx_float;
6043     int convy_int, convx_int;
6044     int l, m;
6045     const char *left, *right;
6046 
6047     if (widthIn == widthOut*2 && heightIn == heightOut*2) {
6048 	halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6049 			      widthIn, heightIn, dataIn, dataOut,
6050 			      pixelSizeInBytes,rowSizeInBytes,isSwap);
6051 	return;
6052     }
6053     convy = (float) heightIn/heightOut;
6054     convx = (float) widthIn/widthOut;
6055     convy_int = floor(convy);
6056     convy_float = convy - convy_int;
6057     convx_int = floor(convx);
6058     convx_float = convx - convx_int;
6059 
6060     area = convx * convy;
6061 
6062     lowy_int = 0;
6063     lowy_float = 0;
6064     highy_int = convy_int;
6065     highy_float = convy_float;
6066 
6067     for (i = 0; i < heightOut; i++) {
6068 	lowx_int = 0;
6069 	lowx_float = 0;
6070 	highx_int = convx_int;
6071 	highx_float = convx_float;
6072 
6073 	for (j = 0; j < widthOut; j++) {
6074 	    /*
6075 	    ** Ok, now apply box filter to box that goes from (lowx, lowy)
6076 	    ** to (highx, highy) on input data into this pixel on output
6077 	    ** data.
6078 	    */
6079 	    totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6080 
6081 	    /* calculate the value for pixels in the 1st row */
6082 	    xindex = lowx_int*pixelSizeInBytes;
6083 	    if((highy_int>lowy_int) && (highx_int>lowx_int)) {
6084 
6085 		y_percent = 1-lowy_float;
6086 		temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6087 		percent = y_percent * (1-lowx_float);
6088 #if 0
6089 		for (k = 0, temp_index = temp; k < components;
6090 		     k++, temp_index += element_size) {
6091 		    if (myswap_bytes) {
6092 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6093 		    } else {
6094 			totals[k] += *(const GLushort*)temp_index * percent;
6095 		    }
6096 		}
6097 #else
6098 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6099 		for (k = 0; k < components; k++) {
6100 		   totals[k]+= extractTotals[k] * percent;
6101 		}
6102 #endif
6103 		left = temp;
6104 		for(l = lowx_int+1; l < highx_int; l++) {
6105 		    temp += pixelSizeInBytes;
6106 #if 0
6107 		    for (k = 0, temp_index = temp; k < components;
6108 			 k++, temp_index += element_size) {
6109 			if (myswap_bytes) {
6110 			    totals[k] +=
6111 				 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6112 			} else {
6113 			    totals[k] += *(const GLushort*)temp_index * y_percent;
6114 			}
6115 		    }
6116 #else
6117 		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6118 		    for (k = 0; k < components; k++) {
6119 		       totals[k]+= extractTotals[k] * y_percent;
6120 		    }
6121 #endif
6122 		}
6123 		temp += pixelSizeInBytes;
6124 		right = temp;
6125 		percent = y_percent * highx_float;
6126 #if 0
6127 		for (k = 0, temp_index = temp; k < components;
6128 		     k++, temp_index += element_size) {
6129 		    if (myswap_bytes) {
6130 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6131 		    } else {
6132 			totals[k] += *(const GLushort*)temp_index * percent;
6133 		    }
6134 		}
6135 #else
6136 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6137 		for (k = 0; k < components; k++) {
6138 		   totals[k]+= extractTotals[k] * percent;
6139 		}
6140 #endif
6141 
6142 		/* calculate the value for pixels in the last row */
6143 
6144 		y_percent = highy_float;
6145 		percent = y_percent * (1-lowx_float);
6146 		temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
6147 #if 0
6148 		for (k = 0, temp_index = temp; k < components;
6149 		     k++, temp_index += element_size) {
6150 		    if (myswap_bytes) {
6151 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6152 		    } else {
6153 			totals[k] += *(const GLushort*)temp_index * percent;
6154 		    }
6155 		}
6156 #else
6157 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6158 		for (k = 0; k < components; k++) {
6159 		   totals[k]+= extractTotals[k] * percent;
6160 		}
6161 #endif
6162 		for(l = lowx_int+1; l < highx_int; l++) {
6163 		    temp += pixelSizeInBytes;
6164 #if 0
6165 		    for (k = 0, temp_index = temp; k < components;
6166 			 k++, temp_index += element_size) {
6167 			if (myswap_bytes) {
6168 			    totals[k] +=
6169 				 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6170 			} else {
6171 			    totals[k] += *(const GLushort*)temp_index * y_percent;
6172 			}
6173 		    }
6174 #else
6175 		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6176 		    for (k = 0; k < components; k++) {
6177 		       totals[k]+= extractTotals[k] * y_percent;
6178 		    }
6179 #endif
6180 
6181 		}
6182 		temp += pixelSizeInBytes;
6183 		percent = y_percent * highx_float;
6184 #if 0
6185 		for (k = 0, temp_index = temp; k < components;
6186 		     k++, temp_index += element_size) {
6187 		    if (myswap_bytes) {
6188 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6189 		    } else {
6190 			totals[k] += *(const GLushort*)temp_index * percent;
6191 		    }
6192 		}
6193 #else
6194 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6195 		for (k = 0; k < components; k++) {
6196 		   totals[k]+= extractTotals[k] * percent;
6197 		}
6198 #endif
6199 
6200 		/* calculate the value for pixels in the 1st and last column */
6201 		for(m = lowy_int+1; m < highy_int; m++) {
6202 		    left += rowSizeInBytes;
6203 		    right += rowSizeInBytes;
6204 #if 0
6205 		    for (k = 0; k < components;
6206 			 k++, left += element_size, right += element_size) {
6207 			if (myswap_bytes) {
6208 			    totals[k] +=
6209 				__GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
6210 				__GLU_SWAP_2_BYTES(right) * highx_float;
6211 			} else {
6212 			    totals[k] += *(const GLushort*)left * (1-lowx_float)
6213 				       + *(const GLushort*)right * highx_float;
6214 			}
6215 		    }
6216 #else
6217 		    (*extractPackedPixel)(isSwap,left,extractTotals);
6218 		    (*extractPackedPixel)(isSwap,right,extractMoreTotals);
6219 		    for (k = 0; k < components; k++) {
6220 		       totals[k]+= (extractTotals[k]*(1-lowx_float) +
6221 				   extractMoreTotals[k]*highx_float);
6222 		    }
6223 #endif
6224 		}
6225 	    } else if (highy_int > lowy_int) {
6226 		x_percent = highx_float - lowx_float;
6227 		percent = (1-lowy_float)*x_percent;
6228 		temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6229 #if 0
6230 		for (k = 0, temp_index = temp; k < components;
6231 		     k++, temp_index += element_size) {
6232 		    if (myswap_bytes) {
6233 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6234 		    } else {
6235 			totals[k] += *(const GLushort*)temp_index * percent;
6236 		    }
6237 		}
6238 #else
6239 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6240 		for (k = 0; k < components; k++) {
6241 		   totals[k]+= extractTotals[k] * percent;
6242 		}
6243 #endif
6244 		for(m = lowy_int+1; m < highy_int; m++) {
6245 		    temp += rowSizeInBytes;
6246 #if 0
6247 		    for (k = 0, temp_index = temp; k < components;
6248 			 k++, temp_index += element_size) {
6249 			if (myswap_bytes) {
6250 			    totals[k] +=
6251 				__GLU_SWAP_2_BYTES(temp_index) * x_percent;
6252 			} else {
6253 			    totals[k] += *(const GLushort*)temp_index * x_percent;
6254 			}
6255 		    }
6256 #else
6257 		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6258 		    for (k = 0; k < components; k++) {
6259 		       totals[k]+= extractTotals[k] * x_percent;
6260 		    }
6261 #endif
6262 		}
6263 		percent = x_percent * highy_float;
6264 		temp += rowSizeInBytes;
6265 #if 0
6266 		for (k = 0, temp_index = temp; k < components;
6267 		     k++, temp_index += element_size) {
6268 		    if (myswap_bytes) {
6269 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6270 		    } else {
6271 			totals[k] += *(const GLushort*)temp_index * percent;
6272 		    }
6273 		}
6274 #else
6275 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6276 		for (k = 0; k < components; k++) {
6277 		   totals[k]+= extractTotals[k] * percent;
6278 		}
6279 #endif
6280 	    } else if (highx_int > lowx_int) {
6281 		y_percent = highy_float - lowy_float;
6282 		percent = (1-lowx_float)*y_percent;
6283 		temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6284 #if 0
6285 		for (k = 0, temp_index = temp; k < components;
6286 		     k++, temp_index += element_size) {
6287 		    if (myswap_bytes) {
6288 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6289 		    } else {
6290 			totals[k] += *(const GLushort*)temp_index * percent;
6291 		    }
6292 		}
6293 #else
6294 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6295 		for (k = 0; k < components; k++) {
6296 		   totals[k]+= extractTotals[k] * percent;
6297 		}
6298 #endif
6299 		for (l = lowx_int+1; l < highx_int; l++) {
6300 		    temp += pixelSizeInBytes;
6301 #if 0
6302 		    for (k = 0, temp_index = temp; k < components;
6303 			 k++, temp_index += element_size) {
6304 			if (myswap_bytes) {
6305 			    totals[k] +=
6306 				__GLU_SWAP_2_BYTES(temp_index) * y_percent;
6307 			} else {
6308 			    totals[k] += *(const GLushort*)temp_index * y_percent;
6309 			}
6310 		    }
6311 #else
6312 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6313 		for (k = 0; k < components; k++) {
6314 		   totals[k]+= extractTotals[k] * y_percent;
6315 		}
6316 #endif
6317 		}
6318 		temp += pixelSizeInBytes;
6319 		percent = y_percent * highx_float;
6320 #if 0
6321 		for (k = 0, temp_index = temp; k < components;
6322 		     k++, temp_index += element_size) {
6323 		    if (myswap_bytes) {
6324 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6325 		    } else {
6326 			totals[k] += *(const GLushort*)temp_index * percent;
6327 		    }
6328 		}
6329 #else
6330 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6331 		for (k = 0; k < components; k++) {
6332 		   totals[k]+= extractTotals[k] * percent;
6333 		}
6334 #endif
6335 	    } else {
6336 		percent = (highy_float-lowy_float)*(highx_float-lowx_float);
6337 		temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6338 #if 0
6339 		for (k = 0, temp_index = temp; k < components;
6340 		     k++, temp_index += element_size) {
6341 		    if (myswap_bytes) {
6342 			totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6343 		    } else {
6344 			totals[k] += *(const GLushort*)temp_index * percent;
6345 		    }
6346 		}
6347 #else
6348 		(*extractPackedPixel)(isSwap,temp,extractTotals);
6349 		for (k = 0; k < components; k++) {
6350 		   totals[k]+= extractTotals[k] * percent;
6351 		}
6352 #endif
6353 	    }
6354 
6355 	    /* this is for the pixels in the body */
6356 	    temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
6357 	    for (m = lowy_int+1; m < highy_int; m++) {
6358 		temp = temp0;
6359 		for(l = lowx_int+1; l < highx_int; l++) {
6360 #if 0
6361 		    for (k = 0, temp_index = temp; k < components;
6362 			 k++, temp_index += element_size) {
6363 			if (myswap_bytes) {
6364 			    totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6365 			} else {
6366 			    totals[k] += *(const GLushort*)temp_index;
6367 			}
6368 		    }
6369 #else
6370 		    (*extractPackedPixel)(isSwap,temp,extractTotals);
6371 		    for (k = 0; k < components; k++) {
6372 		       totals[k]+= extractTotals[k];
6373 		    }
6374 #endif
6375 		    temp += pixelSizeInBytes;
6376 		}
6377 		temp0 += rowSizeInBytes;
6378 	    }
6379 
6380 	    outindex = (j + (i * widthOut)); /* * (components == 1) */
6381 #if 0
6382 	    for (k = 0; k < components; k++) {
6383 		dataout[outindex + k] = totals[k]/area;
6384 		/*printf("totals[%d] = %f\n", k, totals[k]);*/
6385 	    }
6386 #else
6387 	    for (k = 0; k < components; k++) {
6388 		shoveTotals[k]= totals[k]/area;
6389 	    }
6390 	    (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6391 #endif
6392 	    lowx_int = highx_int;
6393 	    lowx_float = highx_float;
6394 	    highx_int += convx_int;
6395 	    highx_float += convx_float;
6396 	    if(highx_float > 1) {
6397 		highx_float -= 1.0;
6398 		highx_int++;
6399 	    }
6400 	}
6401 	lowy_int = highy_int;
6402 	lowy_float = highy_float;
6403 	highy_int += convy_int;
6404 	highy_float += convy_float;
6405 	if(highy_float > 1) {
6406 	    highy_float -= 1.0;
6407 	    highy_int++;
6408 	}
6409     }
6410 
6411     assert(outindex == (widthOut*heightOut - 1));
6412 } /* scaleInternalPackedPixel() */
6413 
6414 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6415  *  inputs; not always equal. Output NEVER has row padding.
6416  */
halveImagePackedPixel(int components,void (* extractPackedPixel)(int,const void *,GLfloat[]),void (* shovePackedPixel)(const GLfloat[],int,void *),GLint width,GLint height,const void * dataIn,void * dataOut,GLint pixelSizeInBytes,GLint rowSizeInBytes,GLint isSwap)6417 static void halveImagePackedPixel(int components,
6418 				  void (*extractPackedPixel)
6419 				  (int, const void *,GLfloat []),
6420 				  void (*shovePackedPixel)
6421 				  (const GLfloat [],int, void *),
6422 				  GLint width, GLint height,
6423 				  const void *dataIn, void *dataOut,
6424 				  GLint pixelSizeInBytes,
6425 				  GLint rowSizeInBytes, GLint isSwap)
6426 {
6427    /* handle case where there is only 1 column/row */
6428    if (width == 1 || height == 1) {
6429       assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6430       halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6431 			      width,height,dataIn,dataOut,pixelSizeInBytes,
6432 			      rowSizeInBytes,isSwap);
6433       return;
6434    }
6435 
6436    {
6437       int ii, jj;
6438 
6439       int halfWidth= width / 2;
6440       int halfHeight= height / 2;
6441       const char *src= (const char *) dataIn;
6442       int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6443       int outIndex= 0;
6444 
6445       for (ii= 0; ii< halfHeight; ii++) {
6446 	 for (jj= 0; jj< halfWidth; jj++) {
6447 #define BOX4 4
6448 	    float totals[4];	/* 4 is maximum components */
6449 	    float extractTotals[BOX4][4]; /* 4 is maximum components */
6450 	    int cc;
6451 
6452 	    (*extractPackedPixel)(isSwap,src,
6453 				  &extractTotals[0][0]);
6454 	    (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6455 				  &extractTotals[1][0]);
6456 	    (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6457 				  &extractTotals[2][0]);
6458 	    (*extractPackedPixel)(isSwap,
6459 				  (src+rowSizeInBytes+pixelSizeInBytes),
6460 				  &extractTotals[3][0]);
6461 	    for (cc = 0; cc < components; cc++) {
6462 	       int kk;
6463 
6464 	       /* grab 4 pixels to average */
6465 	       totals[cc]= 0.0;
6466 	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6467 		*	       extractTotals[2][RED]+extractTotals[3][RED];
6468 		* totals[RED]/= 4.0;
6469 		*/
6470 	       for (kk = 0; kk < BOX4; kk++) {
6471 		  totals[cc]+= extractTotals[kk][cc];
6472 	       }
6473 	       totals[cc]/= (float)BOX4;
6474 	    }
6475 	    (*shovePackedPixel)(totals,outIndex,dataOut);
6476 
6477 	    outIndex++;
6478 	    /* skip over to next square of 4 */
6479 	    src+= pixelSizeInBytes + pixelSizeInBytes;
6480 	 }
6481 	 /* skip past pad bytes, if any, to get to next row */
6482 	 src+= padBytes;
6483 
6484 	 /* src is at beginning of a row here, but it's the second row of
6485 	  * the square block of 4 pixels that we just worked on so we
6486 	  * need to go one more row.
6487 	  * i.e.,
6488 	  *		      OO...
6489 	  *	      here -->OO...
6490 	  *	  but want -->OO...
6491 	  *		      OO...
6492 	  *		      ...
6493 	  */
6494 	 src+= rowSizeInBytes;
6495       }
6496 
6497       /* both pointers must reach one byte after the end */
6498       assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6499       assert(outIndex == halfWidth * halfHeight);
6500    }
6501 } /* halveImagePackedPixel() */
6502 
halve1DimagePackedPixel(int components,void (* extractPackedPixel)(int,const void *,GLfloat[]),void (* shovePackedPixel)(const GLfloat[],int,void *),GLint width,GLint height,const void * dataIn,void * dataOut,GLint pixelSizeInBytes,GLint rowSizeInBytes,GLint isSwap)6503 static void halve1DimagePackedPixel(int components,
6504 				    void (*extractPackedPixel)
6505 				    (int, const void *,GLfloat []),
6506 				    void (*shovePackedPixel)
6507 				    (const GLfloat [],int, void *),
6508 				    GLint width, GLint height,
6509 				    const void *dataIn, void *dataOut,
6510 				    GLint pixelSizeInBytes,
6511 				    GLint rowSizeInBytes, GLint isSwap)
6512 {
6513    int halfWidth= width / 2;
6514    int halfHeight= height / 2;
6515    const char *src= (const char *) dataIn;
6516    int jj;
6517 
6518    assert(width == 1 || height == 1); /* must be 1D */
6519    assert(width != height);	/* can't be square */
6520 
6521    if (height == 1) {	/* 1 row */
6522       int outIndex= 0;
6523 
6524       assert(width != 1);	/* widthxheight can't be 1x1 */
6525       halfHeight= 1;
6526 
6527       /* one horizontal row with possible pad bytes */
6528 
6529       for (jj= 0; jj< halfWidth; jj++) {
6530 #define BOX2 2
6531 	 float totals[4];	/* 4 is maximum components */
6532 	 float extractTotals[BOX2][4]; /* 4 is maximum components */
6533 	 int cc;
6534 
6535 	 /* average two at a time, instead of four */
6536 	 (*extractPackedPixel)(isSwap,src,
6537 			       &extractTotals[0][0]);
6538 	 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6539 			       &extractTotals[1][0]);
6540 	 for (cc = 0; cc < components; cc++) {
6541 	    int kk;
6542 
6543 	    /* grab 2 pixels to average */
6544 	    totals[cc]= 0.0;
6545 	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6546 	     * totals[RED]/= 2.0;
6547 	     */
6548 	    for (kk = 0; kk < BOX2; kk++) {
6549 	       totals[cc]+= extractTotals[kk][cc];
6550 	    }
6551 	    totals[cc]/= (float)BOX2;
6552 	 }
6553 	 (*shovePackedPixel)(totals,outIndex,dataOut);
6554 
6555 	 outIndex++;
6556 	 /* skip over to next group of 2 */
6557 	 src+= pixelSizeInBytes + pixelSizeInBytes;
6558       }
6559 
6560       {
6561 	 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6562 	 src+= padBytes;	/* for assertion only */
6563       }
6564       assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6565       assert(outIndex == halfWidth * halfHeight);
6566    }
6567    else if (width == 1) { /* 1 column */
6568       int outIndex= 0;
6569 
6570       assert(height != 1);	/* widthxheight can't be 1x1 */
6571       halfWidth= 1;
6572       /* one vertical column with possible pad bytes per row */
6573       /* average two at a time */
6574 
6575       for (jj= 0; jj< halfHeight; jj++) {
6576 #define BOX2 2
6577 	 float totals[4];	/* 4 is maximum components */
6578 	 float extractTotals[BOX2][4]; /* 4 is maximum components */
6579 	 int cc;
6580 
6581 	 /* average two at a time, instead of four */
6582 	 (*extractPackedPixel)(isSwap,src,
6583 			       &extractTotals[0][0]);
6584 	 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6585 			       &extractTotals[1][0]);
6586 	 for (cc = 0; cc < components; cc++) {
6587 	    int kk;
6588 
6589 	    /* grab 2 pixels to average */
6590 	    totals[cc]= 0.0;
6591 	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6592 	     * totals[RED]/= 2.0;
6593 	     */
6594 	    for (kk = 0; kk < BOX2; kk++) {
6595 	       totals[cc]+= extractTotals[kk][cc];
6596 	    }
6597 	    totals[cc]/= (float)BOX2;
6598 	 }
6599 	 (*shovePackedPixel)(totals,outIndex,dataOut);
6600 
6601 	 outIndex++;
6602 	 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6603       }
6604 
6605       assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6606       assert(outIndex == halfWidth * halfHeight);
6607    }
6608 } /* halve1DimagePackedPixel() */
6609 
6610 /*===========================================================================*/
6611 
6612 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6613 /*
6614  * This section ensures that GLU 1.3 will load and run on
6615  * a GL 1.1 implementation. It dynamically resolves the
6616  * call to glTexImage3D() which might not be available.
6617  * Or is it might be supported as an extension.
6618  * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6619  */
6620 
6621 typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
6622 						 GLenum internalFormat,
6623 						 GLsizei width, GLsizei height,
6624 						 GLsizei depth, GLint border,
6625 						 GLenum format, GLenum type,
6626 						 const GLvoid *pixels );
6627 
6628 static TexImage3Dproc pTexImage3D = 0;
6629 
6630 #if !defined(_WIN32) && !defined(__WIN32__)
6631 #  include <dlfcn.h>
6632 #  include <sys/types.h>
6633 #else
6634   WINGDIAPI PROC  WINAPI wglGetProcAddress(LPCSTR);
6635 #endif
6636 
gluTexImage3D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)6637 static void gluTexImage3D( GLenum target, GLint level,
6638 			   GLenum internalFormat,
6639 			   GLsizei width, GLsizei height,
6640 			   GLsizei depth, GLint border,
6641 			   GLenum format, GLenum type,
6642 			   const GLvoid *pixels )
6643 {
6644    if (!pTexImage3D) {
6645 #if defined(_WIN32) || defined(__WIN32__)
6646       pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
6647       if (!pTexImage3D)
6648 	 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
6649 #else
6650       void *libHandle = dlopen("libgl.so", RTLD_LAZY);
6651       pTexImage3D = (TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
6652       if (!pTexImage3D)
6653 	 pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
6654       dlclose(libHandle);
6655 #endif
6656    }
6657 
6658    /* Now call glTexImage3D */
6659    if (pTexImage3D)
6660       pTexImage3D(target, level, internalFormat, width, height,
6661 		  depth, border, format, type, pixels);
6662 }
6663 
6664 #else
6665 
6666 /* Only bind to a GL 1.2 implementation: */
6667 #define gluTexImage3D glTexImage3D
6668 
6669 #endif
6670 
imageSize3D(GLint width,GLint height,GLint depth,GLenum format,GLenum type)6671 static GLint imageSize3D(GLint width, GLint height, GLint depth,
6672 			 GLenum format, GLenum type)
6673 {
6674     int components= elements_per_group(format,type);
6675     int bytes_per_row=	bytes_per_element(type) * width;
6676 
6677 assert(width > 0 && height > 0 && depth > 0);
6678 assert(type != GL_BITMAP);
6679 
6680     return bytes_per_row * height * depth * components;
6681 } /* imageSize3D() */
6682 
fillImage3D(const PixelStorageModes * psm,GLint width,GLint height,GLint depth,GLenum format,GLenum type,GLboolean indexFormat,const void * userImage,GLushort * newImage)6683 static void fillImage3D(const PixelStorageModes *psm,
6684 			GLint width, GLint height, GLint depth, GLenum format,
6685 			GLenum type, GLboolean indexFormat,
6686 			const void *userImage, GLushort *newImage)
6687 {
6688    int myswapBytes;
6689    int components;
6690    int groupsPerLine;
6691    int elementSize;
6692    int groupSize;
6693    int rowSize;
6694    int padding;
6695    int elementsPerLine;
6696    int rowsPerImage;
6697    int imageSize;
6698    const GLubyte *start, *rowStart, *iter;
6699    GLushort *iter2;
6700    int ww, hh, dd, k;
6701 
6702    myswapBytes= psm->unpack_swap_bytes;
6703    components= elements_per_group(format,type);
6704    if (psm->unpack_row_length > 0) {
6705       groupsPerLine= psm->unpack_row_length;
6706    }
6707    else {
6708       groupsPerLine= width;
6709    }
6710    elementSize= bytes_per_element(type);
6711    groupSize= elementSize * components;
6712    if (elementSize == 1) myswapBytes= 0;
6713 
6714    /* 3dstuff begin */
6715    if (psm->unpack_image_height > 0) {
6716       rowsPerImage= psm->unpack_image_height;
6717    }
6718    else {
6719       rowsPerImage= height;
6720    }
6721    /* 3dstuff end */
6722 
6723    rowSize= groupsPerLine * groupSize;
6724    padding= rowSize % psm->unpack_alignment;
6725    if (padding) {
6726       rowSize+= psm->unpack_alignment - padding;
6727    }
6728 
6729    imageSize= rowsPerImage * rowSize; /* 3dstuff */
6730 
6731    start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
6732 				 psm->unpack_skip_pixels * groupSize +
6733 				 /*3dstuff*/
6734 				 psm->unpack_skip_images * imageSize;
6735    elementsPerLine = width * components;
6736 
6737    iter2= newImage;
6738    for (dd= 0; dd < depth; dd++) {
6739       rowStart= start;
6740 
6741       for (hh= 0; hh < height; hh++) {
6742 	 iter= rowStart;
6743 
6744 	 for (ww= 0; ww < elementsPerLine; ww++) {
6745 	    Type_Widget widget;
6746 	    float extractComponents[4];
6747 
6748 	    switch(type) {
6749 	    case GL_UNSIGNED_BYTE:
6750 	      if (indexFormat) {
6751 		  *iter2++ = *iter;
6752 	      } else {
6753 		  *iter2++ = (*iter) * 257;
6754 	      }
6755 	      break;
6756 	    case GL_BYTE:
6757 	      if (indexFormat) {
6758 		  *iter2++ = *((const GLbyte *) iter);
6759 	      } else {
6760 		  /* rough approx */
6761 		  *iter2++ = (*((const GLbyte *) iter)) * 516;
6762 	      }
6763 	      break;
6764 	    case GL_UNSIGNED_BYTE_3_3_2:
6765 	      extract332(0,iter,extractComponents);
6766 	      for (k = 0; k < 3; k++) {
6767 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6768 	      }
6769 	      break;
6770 	    case GL_UNSIGNED_BYTE_2_3_3_REV:
6771 	      extract233rev(0,iter,extractComponents);
6772 	      for (k = 0; k < 3; k++) {
6773 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6774 	      }
6775 	      break;
6776 	    case GL_UNSIGNED_SHORT_5_6_5:
6777 	      extract565(myswapBytes,iter,extractComponents);
6778 	      for (k = 0; k < 3; k++) {
6779 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6780 	      }
6781 	      break;
6782 	    case GL_UNSIGNED_SHORT_5_6_5_REV:
6783 	      extract565rev(myswapBytes,iter,extractComponents);
6784 	      for (k = 0; k < 3; k++) {
6785 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6786 	      }
6787 	      break;
6788 	    case GL_UNSIGNED_SHORT_4_4_4_4:
6789 	      extract4444(myswapBytes,iter,extractComponents);
6790 	      for (k = 0; k < 4; k++) {
6791 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6792 	      }
6793 	      break;
6794 	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
6795 	      extract4444rev(myswapBytes,iter,extractComponents);
6796 	      for (k = 0; k < 4; k++) {
6797 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6798 	      }
6799 	      break;
6800 	    case GL_UNSIGNED_SHORT_5_5_5_1:
6801 	      extract5551(myswapBytes,iter,extractComponents);
6802 	      for (k = 0; k < 4; k++) {
6803 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6804 	      }
6805 	      break;
6806 	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
6807 	      extract1555rev(myswapBytes,iter,extractComponents);
6808 	      for (k = 0; k < 4; k++) {
6809 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6810 	      }
6811 	      break;
6812 	    case GL_UNSIGNED_SHORT:
6813 	    case GL_SHORT:
6814 	      if (myswapBytes) {
6815 		  widget.ub[0] = iter[1];
6816 		  widget.ub[1] = iter[0];
6817 	      } else {
6818 		  widget.ub[0] = iter[0];
6819 		  widget.ub[1] = iter[1];
6820 	      }
6821 	      if (type == GL_SHORT) {
6822 		  if (indexFormat) {
6823 		      *iter2++ = widget.s[0];
6824 		  } else {
6825 		      /* rough approx */
6826 		      *iter2++ = widget.s[0]*2;
6827 		  }
6828 	      } else {
6829 		  *iter2++ = widget.us[0];
6830 	      }
6831 	      break;
6832 	    case GL_UNSIGNED_INT_8_8_8_8:
6833 	      extract8888(myswapBytes,iter,extractComponents);
6834 	      for (k = 0; k < 4; k++) {
6835 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6836 	      }
6837 	      break;
6838 	    case GL_UNSIGNED_INT_8_8_8_8_REV:
6839 	      extract8888rev(myswapBytes,iter,extractComponents);
6840 	      for (k = 0; k < 4; k++) {
6841 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6842 	      }
6843 	      break;
6844 	    case GL_UNSIGNED_INT_10_10_10_2:
6845 	      extract1010102(myswapBytes,iter,extractComponents);
6846 	      for (k = 0; k < 4; k++) {
6847 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6848 	      }
6849 	      break;
6850 	    case GL_UNSIGNED_INT_2_10_10_10_REV:
6851 	      extract2101010rev(myswapBytes,iter,extractComponents);
6852 	      for (k = 0; k < 4; k++) {
6853 		*iter2++ = (GLushort)(extractComponents[k]*65535);
6854 	      }
6855 	      break;
6856 	    case GL_INT:
6857 	    case GL_UNSIGNED_INT:
6858 	    case GL_FLOAT:
6859 	      if (myswapBytes) {
6860 		  widget.ub[0] = iter[3];
6861 		  widget.ub[1] = iter[2];
6862 		  widget.ub[2] = iter[1];
6863 		  widget.ub[3] = iter[0];
6864 	      } else {
6865 		  widget.ub[0] = iter[0];
6866 		  widget.ub[1] = iter[1];
6867 		  widget.ub[2] = iter[2];
6868 		  widget.ub[3] = iter[3];
6869 	      }
6870 	      if (type == GL_FLOAT) {
6871 		  if (indexFormat) {
6872 		      *iter2++ = widget.f;
6873 		  } else {
6874 		      *iter2++ = 65535 * widget.f;
6875 		  }
6876 	      } else if (type == GL_UNSIGNED_INT) {
6877 		  if (indexFormat) {
6878 		      *iter2++ = widget.ui;
6879 		  } else {
6880 		      *iter2++ = widget.ui >> 16;
6881 		  }
6882 	      } else {
6883 		  if (indexFormat) {
6884 		      *iter2++ = widget.i;
6885 		  } else {
6886 		      *iter2++ = widget.i >> 15;
6887 		  }
6888 	      }
6889 	      break;
6890 	    default:
6891 	      assert(0);
6892 	    }
6893 
6894 	    iter+= elementSize;
6895 	 } /* for ww */
6896 	 rowStart+= rowSize;
6897 
6898 	 iter= rowStart;	/* for assertion purposes */
6899       } /* for hh */
6900 
6901       start+= imageSize;
6902    } /* for dd */
6903 
6904    /* iterators should be one byte past end */
6905    if (!isTypePackedPixel(type)) {
6906       assert(iter2 == &newImage[width*height*depth*components]);
6907    }
6908    else {
6909       assert(iter2 == &newImage[width*height*depth*
6910 				elements_per_group(format,0)]);
6911    }
6912    assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
6913 					psm->unpack_skip_rows * rowSize +
6914 					psm->unpack_skip_pixels * groupSize +
6915 					/*3dstuff*/
6916 					psm->unpack_skip_images * imageSize] );
6917 } /* fillImage3D () */
6918 
scaleInternal3D(GLint components,GLint widthIn,GLint heightIn,GLint depthIn,const GLushort * dataIn,GLint widthOut,GLint heightOut,GLint depthOut,GLushort * dataOut)6919 static void scaleInternal3D(GLint components,
6920 			    GLint widthIn, GLint heightIn, GLint depthIn,
6921 			    const GLushort *dataIn,
6922 			    GLint widthOut, GLint heightOut, GLint depthOut,
6923 			    GLushort *dataOut)
6924 {
6925     float x, lowx, highx, convx, halfconvx;
6926     float y, lowy, highy, convy, halfconvy;
6927     float z, lowz, highz, convz, halfconvz;
6928     float xpercent,ypercent,zpercent;
6929     float percent;
6930     /* Max components in a format is 4, so... */
6931     float totals[4];
6932     float volume;
6933     int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
6934     int temp;
6935 
6936     convz = (float) depthIn/depthOut;
6937     convy = (float) heightIn/heightOut;
6938     convx = (float) widthIn/widthOut;
6939     halfconvx = convx/2;
6940     halfconvy = convy/2;
6941     halfconvz = convz/2;
6942     for (d = 0; d < depthOut; d++) {
6943        z = convz * (d+0.5);
6944        if (depthIn > depthOut) {
6945 	   highz = z + halfconvz;
6946 	   lowz = z - halfconvz;
6947        } else {
6948 	   highz = z + 0.5;
6949 	   lowz = z - 0.5;
6950        }
6951        for (i = 0; i < heightOut; i++) {
6952 	   y = convy * (i+0.5);
6953 	   if (heightIn > heightOut) {
6954 	       highy = y + halfconvy;
6955 	       lowy = y - halfconvy;
6956 	   } else {
6957 	       highy = y + 0.5;
6958 	       lowy = y - 0.5;
6959 	   }
6960 	   for (j = 0; j < widthOut; j++) {
6961 	       x = convx * (j+0.5);
6962 	       if (widthIn > widthOut) {
6963 		   highx = x + halfconvx;
6964 		   lowx = x - halfconvx;
6965 	       } else {
6966 		   highx = x + 0.5;
6967 		   lowx = x - 0.5;
6968 	       }
6969 
6970 	       /*
6971 	       ** Ok, now apply box filter to box that goes from (lowx, lowy,
6972 	       ** lowz) to (highx, highy, highz) on input data into this pixel
6973 	       ** on output data.
6974 	       */
6975 	       totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6976 	       volume = 0.0;
6977 
6978 	       z = lowz;
6979 	       zint = floor(z);
6980 	       while (z < highz) {
6981 		  zindex = (zint + depthIn) % depthIn;
6982 		  if (highz < zint+1) {
6983 		      zpercent = highz - z;
6984 		  } else {
6985 		      zpercent = zint+1 - z;
6986 		  }
6987 
6988 		  y = lowy;
6989 		  yint = floor(y);
6990 		  while (y < highy) {
6991 		      yindex = (yint + heightIn) % heightIn;
6992 		      if (highy < yint+1) {
6993 			  ypercent = highy - y;
6994 		      } else {
6995 			  ypercent = yint+1 - y;
6996 		      }
6997 
6998 		      x = lowx;
6999 		      xint = floor(x);
7000 
7001 		      while (x < highx) {
7002 			  xindex = (xint + widthIn) % widthIn;
7003 			  if (highx < xint+1) {
7004 			      xpercent = highx - x;
7005 			  } else {
7006 			      xpercent = xint+1 - x;
7007 			  }
7008 
7009 			  percent = xpercent * ypercent * zpercent;
7010 			  volume += percent;
7011 
7012 			  temp = (xindex + (yindex*widthIn) +
7013 				  (zindex*widthIn*heightIn)) * components;
7014 			  for (k = 0; k < components; k++) {
7015 			      assert(0 <= (temp+k) &&
7016 				     (temp+k) <
7017 				     (widthIn*heightIn*depthIn*components));
7018 			      totals[k] += dataIn[temp + k] * percent;
7019 			  }
7020 
7021 			  xint++;
7022 			  x = xint;
7023 		      } /* while x */
7024 
7025 		      yint++;
7026 		      y = yint;
7027 		  } /* while y */
7028 
7029 		  zint++;
7030 		  z = zint;
7031 	       } /* while z */
7032 
7033 	       temp = (j + (i * widthOut) +
7034 		       (d*widthOut*heightOut)) * components;
7035 	       for (k = 0; k < components; k++) {
7036 		   /* totals[] should be rounded in the case of enlarging an
7037 		    * RGB ramp when the type is 332 or 4444
7038 		    */
7039 		   assert(0 <= (temp+k) &&
7040 			  (temp+k) < (widthOut*heightOut*depthOut*components));
7041 		   dataOut[temp + k] = (totals[k]+0.5)/volume;
7042 	       }
7043 	   } /* for j */
7044        } /* for i */
7045     } /* for d */
7046 } /* scaleInternal3D() */
7047 
emptyImage3D(const PixelStorageModes * psm,GLint width,GLint height,GLint depth,GLenum format,GLenum type,GLboolean indexFormat,const GLushort * oldImage,void * userImage)7048 static void emptyImage3D(const PixelStorageModes *psm,
7049 			 GLint width, GLint height, GLint depth,
7050 			 GLenum format, GLenum type, GLboolean indexFormat,
7051 			 const GLushort *oldImage, void *userImage)
7052 {
7053    int myswapBytes;
7054    int components;
7055    int groupsPerLine;
7056    int elementSize;
7057    int groupSize;
7058    int rowSize;
7059    int padding;
7060    GLubyte *start, *rowStart, *iter;
7061    int elementsPerLine;
7062    const GLushort *iter2;
7063    int ii, jj, dd, k;
7064    int rowsPerImage;
7065    int imageSize;
7066 
7067    myswapBytes= psm->pack_swap_bytes;
7068    components = elements_per_group(format,type);
7069    if (psm->pack_row_length > 0) {
7070       groupsPerLine = psm->pack_row_length;
7071    }
7072    else {
7073       groupsPerLine = width;
7074    }
7075 
7076    elementSize= bytes_per_element(type);
7077    groupSize= elementSize * components;
7078    if (elementSize == 1) myswapBytes= 0;
7079 
7080    /* 3dstuff begin */
7081    if (psm->pack_image_height > 0) {
7082       rowsPerImage= psm->pack_image_height;
7083    }
7084    else {
7085       rowsPerImage= height;
7086    }
7087 
7088    /* 3dstuff end */
7089 
7090    rowSize = groupsPerLine * groupSize;
7091    padding = rowSize % psm->pack_alignment;
7092    if (padding) {
7093       rowSize+= psm->pack_alignment - padding;
7094    }
7095 
7096    imageSize= rowsPerImage * rowSize; /* 3dstuff */
7097 
7098    start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
7099 				  psm->pack_skip_pixels * groupSize +
7100 				  /*3dstuff*/
7101 				  psm->pack_skip_images * imageSize;
7102    elementsPerLine= width * components;
7103 
7104    iter2 = oldImage;
7105    for (dd= 0; dd < depth; dd++) {
7106       rowStart= start;
7107 
7108       for (ii= 0; ii< height; ii++) {
7109 	 iter = rowStart;
7110 
7111 	 for (jj = 0; jj < elementsPerLine; jj++) {
7112 	    Type_Widget widget;
7113 	    float shoveComponents[4];
7114 
7115 	    switch(type){
7116 	    case GL_UNSIGNED_BYTE:
7117 	      if (indexFormat) {
7118 		  *iter = *iter2++;
7119 	      } else {
7120 		  *iter = *iter2++ >> 8;
7121 	      }
7122 	      break;
7123 	    case GL_BYTE:
7124 	      if (indexFormat) {
7125 		  *((GLbyte *) iter) = *iter2++;
7126 	      } else {
7127 		  *((GLbyte *) iter) = *iter2++ >> 9;
7128 	      }
7129 	      break;
7130 	    case GL_UNSIGNED_BYTE_3_3_2:
7131 	      for (k = 0; k < 3; k++) {
7132 		 shoveComponents[k]= *iter2++ / 65535.0;
7133 	      }
7134 	      shove332(shoveComponents,0,(void *)iter);
7135 	      break;
7136 	    case GL_UNSIGNED_BYTE_2_3_3_REV:
7137 	      for (k = 0; k < 3; k++) {
7138 		 shoveComponents[k]= *iter2++ / 65535.0;
7139 	      }
7140 	      shove233rev(shoveComponents,0,(void *)iter);
7141 	      break;
7142 	    case GL_UNSIGNED_SHORT_5_6_5:
7143 	      for (k = 0; k < 3; k++) {
7144 		 shoveComponents[k]= *iter2++ / 65535.0;
7145 	      }
7146 	      shove565(shoveComponents,0,(void *)&widget.us[0]);
7147 	      if (myswapBytes) {
7148 		 iter[0] = widget.ub[1];
7149 		 iter[1] = widget.ub[0];
7150 	      }
7151 	      else {
7152 		 *(GLushort *)iter = widget.us[0];
7153 	      }
7154 	      break;
7155 	    case GL_UNSIGNED_SHORT_5_6_5_REV:
7156 	      for (k = 0; k < 3; k++) {
7157 		 shoveComponents[k]= *iter2++ / 65535.0;
7158 	      }
7159 	      shove565rev(shoveComponents,0,(void *)&widget.us[0]);
7160 	      if (myswapBytes) {
7161 		 iter[0] = widget.ub[1];
7162 		 iter[1] = widget.ub[0];
7163 	      }
7164 	      else {
7165 		 *(GLushort *)iter = widget.us[0];
7166 	      }
7167 	      break;
7168 	    case GL_UNSIGNED_SHORT_4_4_4_4:
7169 	      for (k = 0; k < 4; k++) {
7170 		 shoveComponents[k]= *iter2++ / 65535.0;
7171 	      }
7172 	      shove4444(shoveComponents,0,(void *)&widget.us[0]);
7173 	      if (myswapBytes) {
7174 		 iter[0] = widget.ub[1];
7175 		 iter[1] = widget.ub[0];
7176 	      } else {
7177 		 *(GLushort *)iter = widget.us[0];
7178 	      }
7179 	      break;
7180 	    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7181 	      for (k = 0; k < 4; k++) {
7182 		 shoveComponents[k]= *iter2++ / 65535.0;
7183 	      }
7184 	      shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
7185 	      if (myswapBytes) {
7186 		 iter[0] = widget.ub[1];
7187 		 iter[1] = widget.ub[0];
7188 	      } else {
7189 		 *(GLushort *)iter = widget.us[0];
7190 	      }
7191 	      break;
7192 	    case GL_UNSIGNED_SHORT_5_5_5_1:
7193 	      for (k = 0; k < 4; k++) {
7194 		 shoveComponents[k]= *iter2++ / 65535.0;
7195 	      }
7196 	      shove5551(shoveComponents,0,(void *)&widget.us[0]);
7197 	      if (myswapBytes) {
7198 		 iter[0] = widget.ub[1];
7199 		 iter[1] = widget.ub[0];
7200 	      } else {
7201 		 *(GLushort *)iter = widget.us[0];
7202 	      }
7203 	      break;
7204 	    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7205 	      for (k = 0; k < 4; k++) {
7206 		 shoveComponents[k]= *iter2++ / 65535.0;
7207 	      }
7208 	      shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
7209 	      if (myswapBytes) {
7210 		 iter[0] = widget.ub[1];
7211 		 iter[1] = widget.ub[0];
7212 	      } else {
7213 		 *(GLushort *)iter = widget.us[0];
7214 	      }
7215 	      break;
7216 	    case GL_UNSIGNED_SHORT:
7217 	    case GL_SHORT:
7218 	      if (type == GL_SHORT) {
7219 		  if (indexFormat) {
7220 		      widget.s[0] = *iter2++;
7221 		  } else {
7222 		      widget.s[0] = *iter2++ >> 1;
7223 		  }
7224 	      } else {
7225 		  widget.us[0] = *iter2++;
7226 	      }
7227 	      if (myswapBytes) {
7228 		  iter[0] = widget.ub[1];
7229 		  iter[1] = widget.ub[0];
7230 	      } else {
7231 		  iter[0] = widget.ub[0];
7232 		  iter[1] = widget.ub[1];
7233 	      }
7234 	      break;
7235 	    case GL_UNSIGNED_INT_8_8_8_8:
7236 	       for (k = 0; k < 4; k++) {
7237 		  shoveComponents[k]= *iter2++ / 65535.0;
7238 	       }
7239 	       shove8888(shoveComponents,0,(void *)&widget.ui);
7240 	       if (myswapBytes) {
7241 		   iter[3] = widget.ub[0];
7242 		   iter[2] = widget.ub[1];
7243 		   iter[1] = widget.ub[2];
7244 		   iter[0] = widget.ub[3];
7245 	       } else {
7246 		   *(GLuint *)iter= widget.ui;
7247 	       }
7248 	       break;
7249 	    case GL_UNSIGNED_INT_8_8_8_8_REV:
7250 	       for (k = 0; k < 4; k++) {
7251 		  shoveComponents[k]= *iter2++ / 65535.0;
7252 	       }
7253 	       shove8888rev(shoveComponents,0,(void *)&widget.ui);
7254 	       if (myswapBytes) {
7255 		   iter[3] = widget.ub[0];
7256 		   iter[2] = widget.ub[1];
7257 		   iter[1] = widget.ub[2];
7258 		   iter[0] = widget.ub[3];
7259 	       } else {
7260 		   *(GLuint *)iter= widget.ui;
7261 	       }
7262 	       break;
7263 	    case GL_UNSIGNED_INT_10_10_10_2:
7264 	       for (k = 0; k < 4; k++) {
7265 		  shoveComponents[k]= *iter2++ / 65535.0;
7266 	       }
7267 	       shove1010102(shoveComponents,0,(void *)&widget.ui);
7268 	       if (myswapBytes) {
7269 		   iter[3] = widget.ub[0];
7270 		   iter[2] = widget.ub[1];
7271 		   iter[1] = widget.ub[2];
7272 		   iter[0] = widget.ub[3];
7273 	       } else {
7274 		   *(GLuint *)iter= widget.ui;
7275 	       }
7276 	       break;
7277 	    case GL_UNSIGNED_INT_2_10_10_10_REV:
7278 	       for (k = 0; k < 4; k++) {
7279 		  shoveComponents[k]= *iter2++ / 65535.0;
7280 	       }
7281 	       shove2101010rev(shoveComponents,0,(void *)&widget.ui);
7282 	       if (myswapBytes) {
7283 		   iter[3] = widget.ub[0];
7284 		   iter[2] = widget.ub[1];
7285 		   iter[1] = widget.ub[2];
7286 		   iter[0] = widget.ub[3];
7287 	       } else {
7288 		   *(GLuint *)iter= widget.ui;
7289 	       }
7290 	       break;
7291 	    case GL_INT:
7292 	    case GL_UNSIGNED_INT:
7293 	    case GL_FLOAT:
7294 	      if (type == GL_FLOAT) {
7295 		  if (indexFormat) {
7296 		      widget.f = *iter2++;
7297 		  } else {
7298 		      widget.f = *iter2++ / (float) 65535.0;
7299 		  }
7300 	      } else if (type == GL_UNSIGNED_INT) {
7301 		  if (indexFormat) {
7302 		      widget.ui = *iter2++;
7303 		  } else {
7304 		      widget.ui = (unsigned int) *iter2++ * 65537;
7305 		  }
7306 	      } else {
7307 		  if (indexFormat) {
7308 		      widget.i = *iter2++;
7309 		  } else {
7310 		      widget.i = ((unsigned int) *iter2++ * 65537)/2;
7311 		  }
7312 	      }
7313 	      if (myswapBytes) {
7314 		  iter[3] = widget.ub[0];
7315 		  iter[2] = widget.ub[1];
7316 		  iter[1] = widget.ub[2];
7317 		  iter[0] = widget.ub[3];
7318 	      } else {
7319 		  iter[0] = widget.ub[0];
7320 		  iter[1] = widget.ub[1];
7321 		  iter[2] = widget.ub[2];
7322 		  iter[3] = widget.ub[3];
7323 	      }
7324 	      break;
7325 	    default:
7326 	       assert(0);
7327 	    }
7328 
7329 	    iter+= elementSize;
7330 	 }  /* for jj */
7331 
7332 	 rowStart+= rowSize;
7333       } /* for ii */
7334 
7335       start+= imageSize;
7336    } /* for dd */
7337 
7338    /* iterators should be one byte past end */
7339    if (!isTypePackedPixel(type)) {
7340       assert(iter2 == &oldImage[width*height*depth*components]);
7341    }
7342    else {
7343       assert(iter2 == &oldImage[width*height*depth*
7344 				elements_per_group(format,0)]);
7345    }
7346    assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
7347 					psm->unpack_skip_rows * rowSize +
7348 					psm->unpack_skip_pixels * groupSize +
7349 					/*3dstuff*/
7350 					psm->unpack_skip_images * imageSize] );
7351 } /* emptyImage3D() */
7352 
7353 static
gluScaleImage3D(GLenum format,GLint widthIn,GLint heightIn,GLint depthIn,GLenum typeIn,const void * dataIn,GLint widthOut,GLint heightOut,GLint depthOut,GLenum typeOut,void * dataOut)7354 int gluScaleImage3D(GLenum format,
7355 		    GLint widthIn, GLint heightIn, GLint depthIn,
7356 		    GLenum typeIn, const void *dataIn,
7357 		    GLint widthOut, GLint heightOut, GLint depthOut,
7358 		    GLenum typeOut, void *dataOut)
7359 {
7360    int components;
7361    GLushort *beforeImage, *afterImage;
7362    PixelStorageModes psm;
7363 
7364    if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
7365        widthOut == 0 || heightOut == 0 || depthOut == 0) {
7366       return 0;
7367    }
7368 
7369    if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
7370        widthOut < 0 || heightOut < 0 || depthOut < 0) {
7371       return GLU_INVALID_VALUE;
7372    }
7373 
7374    if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
7375        typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
7376       return GLU_INVALID_ENUM;
7377    }
7378    if (!isLegalFormatForPackedPixelType(format, typeIn)) {
7379       return GLU_INVALID_OPERATION;
7380    }
7381    if (!isLegalFormatForPackedPixelType(format, typeOut)) {
7382       return GLU_INVALID_OPERATION;
7383    }
7384 
7385    beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
7386 				    GL_UNSIGNED_SHORT));
7387    afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
7388 				   GL_UNSIGNED_SHORT));
7389    if (beforeImage == NULL || afterImage == NULL) {
7390        free(beforeImage);
7391        free(afterImage);
7392        return GLU_OUT_OF_MEMORY;
7393    }
7394    retrieveStoreModes3D(&psm);
7395 
7396    fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
7397 	       dataIn, beforeImage);
7398    components = elements_per_group(format,0);
7399    scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
7400 		   widthOut,heightOut,depthOut,afterImage);
7401    emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
7402 		is_index(format),afterImage, dataOut);
7403    free((void *) beforeImage);
7404    free((void *) afterImage);
7405 
7406    return 0;
7407 } /* gluScaleImage3D() */
7408 
7409 
closestFit3D(GLenum target,GLint width,GLint height,GLint depth,GLint internalFormat,GLenum format,GLenum type,GLint * newWidth,GLint * newHeight,GLint * newDepth)7410 static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
7411 			 GLint internalFormat, GLenum format, GLenum type,
7412 			 GLint *newWidth, GLint *newHeight, GLint *newDepth)
7413 {
7414    GLint widthPowerOf2= nearestPower(width);
7415    GLint heightPowerOf2= nearestPower(height);
7416    GLint depthPowerOf2= nearestPower(depth);
7417    GLint proxyWidth;
7418 
7419    do {
7420       /* compute level 1 width & height & depth, clamping each at 1 */
7421       GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
7422 			      widthPowerOf2 >> 1 :
7423 			      widthPowerOf2;
7424       GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
7425 			       heightPowerOf2 >> 1 :
7426 			       heightPowerOf2;
7427       GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
7428 			      depthPowerOf2 >> 1 :
7429 			      depthPowerOf2;
7430       GLenum proxyTarget = GL_PROXY_TEXTURE_3D;
7431       assert(widthAtLevelOne > 0);
7432       assert(heightAtLevelOne > 0);
7433       assert(depthAtLevelOne > 0);
7434 
7435       /* does width x height x depth at level 1 & all their mipmaps fit? */
7436       assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D);
7437       gluTexImage3D(proxyTarget, 1, /* must be non-zero */
7438                     internalFormat,
7439                     widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
7440                     0,format,type,NULL);
7441       glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
7442       /* does it fit??? */
7443       if (proxyWidth == 0) { /* nope, so try again with these sizes */
7444 	 if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
7445 	     depthPowerOf2 == 1) {
7446 	    *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
7447 	    return;
7448 	 }
7449 	 widthPowerOf2= widthAtLevelOne;
7450 	 heightPowerOf2= heightAtLevelOne;
7451 	 depthPowerOf2= depthAtLevelOne;
7452       }
7453       /* else it does fit */
7454    } while (proxyWidth == 0);
7455    /* loop must terminate! */
7456 
7457    /* return the width & height at level 0 that fits */
7458    *newWidth= widthPowerOf2;
7459    *newHeight= heightPowerOf2;
7460    *newDepth= depthPowerOf2;
7461 /*printf("Proxy Textures\n");*/
7462 } /* closestFit3D() */
7463 
halveImagePackedPixelSlice(int components,void (* extractPackedPixel)(int,const void *,GLfloat[]),void (* shovePackedPixel)(const GLfloat[],int,void *),GLint width,GLint height,GLint depth,const void * dataIn,void * dataOut,GLint pixelSizeInBytes,GLint rowSizeInBytes,GLint imageSizeInBytes,GLint isSwap)7464 static void halveImagePackedPixelSlice(int components,
7465 				       void (*extractPackedPixel)
7466 				       (int, const void *,GLfloat []),
7467 				       void (*shovePackedPixel)
7468 				       (const GLfloat [],int, void *),
7469 				       GLint width, GLint height, GLint depth,
7470 				       const void *dataIn, void *dataOut,
7471 				       GLint pixelSizeInBytes,
7472 				       GLint rowSizeInBytes,
7473 				       GLint imageSizeInBytes,
7474 				       GLint isSwap)
7475 {
7476    int ii, jj;
7477    int halfWidth= width / 2;
7478    int halfHeight= height / 2;
7479    int halfDepth= depth / 2;
7480    const char *src= (const char *)dataIn;
7481    int outIndex= 0;
7482 
7483    assert((width == 1 || height == 1) && depth >= 2);
7484 
7485    if (width == height) {	/* a 1-pixel column viewed from top */
7486       assert(width == 1 && height == 1);
7487       assert(depth >= 2);
7488 
7489       for (ii= 0; ii< halfDepth; ii++) {
7490 	 float totals[4];
7491 	 float extractTotals[BOX2][4];
7492 	 int cc;
7493 
7494 	 (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
7495 	 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7496 			       &extractTotals[1][0]);
7497 	 for (cc = 0; cc < components; cc++) {
7498 	    int kk;
7499 
7500 	    /* average 2 pixels since only a column */
7501 	    totals[cc]= 0.0;
7502 	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7503 	     * totals[RED]/= 2.0;
7504 	     */
7505 	    for (kk = 0; kk < BOX2; kk++) {
7506 	      totals[cc]+= extractTotals[kk][cc];
7507 	    }
7508 	    totals[cc]/= (float)BOX2;
7509 	 } /* for cc */
7510 
7511 	 (*shovePackedPixel)(totals,outIndex,dataOut);
7512 	 outIndex++;
7513 	 /* skip over to next group of 2 */
7514 	 src+= imageSizeInBytes + imageSizeInBytes;
7515       } /* for ii */
7516    }
7517    else if (height == 1) {	/* horizontal slice viewed from top */
7518       assert(width != 1);
7519 
7520       for (ii= 0; ii< halfDepth; ii++) {
7521 	 for (jj= 0; jj< halfWidth; jj++) {
7522 	     float totals[4];
7523 	     float extractTotals[BOX4][4];
7524 	     int cc;
7525 
7526 	     (*extractPackedPixel)(isSwap,src,
7527 				   &extractTotals[0][0]);
7528 	     (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7529 				   &extractTotals[1][0]);
7530 	     (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7531 				   &extractTotals[2][0]);
7532 	     (*extractPackedPixel)(isSwap,
7533 				   (src+imageSizeInBytes+pixelSizeInBytes),
7534 				   &extractTotals[3][0]);
7535 	     for (cc = 0; cc < components; cc++) {
7536 		int kk;
7537 
7538 		/* grab 4 pixels to average */
7539 		totals[cc]= 0.0;
7540 		/* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7541 		 *		extractTotals[2][RED]+extractTotals[3][RED];
7542 		 * totals[RED]/= 4.0;
7543 		 */
7544 		for (kk = 0; kk < BOX4; kk++) {
7545 		   totals[cc]+= extractTotals[kk][cc];
7546 		}
7547 		totals[cc]/= (float)BOX4;
7548 	     }
7549 	     (*shovePackedPixel)(totals,outIndex,dataOut);
7550 
7551 	     outIndex++;
7552 	     /* skip over to next horizontal square of 4 */
7553 	     src+= imageSizeInBytes + imageSizeInBytes;
7554 	 }
7555       }
7556 
7557       /* assert() */
7558    }
7559    else if (width == 1) {	/* vertical slice viewed from top */
7560       assert(height != 1);
7561 
7562       for (ii= 0; ii< halfDepth; ii++) {
7563 	 for (jj= 0; jj< halfHeight; jj++) {
7564 	    float totals[4];
7565 	    float extractTotals[BOX4][4];
7566 	    int cc;
7567 
7568 	    (*extractPackedPixel)(isSwap,src,
7569 				  &extractTotals[0][0]);
7570 	    (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7571 				  &extractTotals[1][0]);
7572 	    (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7573 				  &extractTotals[2][0]);
7574 	    (*extractPackedPixel)(isSwap,
7575 				  (src+imageSizeInBytes+rowSizeInBytes),
7576 				  &extractTotals[3][0]);
7577 	    for (cc = 0; cc < components; cc++) {
7578 	       int kk;
7579 
7580 	       /* grab 4 pixels to average */
7581 	       totals[cc]= 0.0;
7582 	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7583 		*	       extractTotals[2][RED]+extractTotals[3][RED];
7584 		* totals[RED]/= 4.0;
7585 		*/
7586 	       for (kk = 0; kk < BOX4; kk++) {
7587 		  totals[cc]+= extractTotals[kk][cc];
7588 	       }
7589 	       totals[cc]/= (float)BOX4;
7590 	    }
7591 	    (*shovePackedPixel)(totals,outIndex,dataOut);
7592 
7593 	    outIndex++;
7594 
7595 	    /* skip over to next vertical square of 4 */
7596 	    src+= imageSizeInBytes + imageSizeInBytes;
7597 	 }
7598       }
7599       /* assert() */
7600    }
7601 
7602 } /* halveImagePackedPixelSlice() */
7603 
halveImagePackedPixel3D(int components,void (* extractPackedPixel)(int,const void *,GLfloat[]),void (* shovePackedPixel)(const GLfloat[],int,void *),GLint width,GLint height,GLint depth,const void * dataIn,void * dataOut,GLint pixelSizeInBytes,GLint rowSizeInBytes,GLint imageSizeInBytes,GLint isSwap)7604 static void halveImagePackedPixel3D(int components,
7605 				    void (*extractPackedPixel)
7606 				    (int, const void *,GLfloat []),
7607 				    void (*shovePackedPixel)
7608 				    (const GLfloat [],int, void *),
7609 				    GLint width, GLint height, GLint depth,
7610 				    const void *dataIn, void *dataOut,
7611 				    GLint pixelSizeInBytes,
7612 				    GLint rowSizeInBytes,
7613 				    GLint imageSizeInBytes,
7614 				    GLint isSwap)
7615 {
7616    if (depth == 1) {
7617       assert(1 <= width && 1 <= height);
7618 
7619       halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
7620 			    width,height,dataIn,dataOut,pixelSizeInBytes,
7621 			    rowSizeInBytes,isSwap);
7622       return;
7623    }
7624    /* a horizontal or vertical slice viewed from top */
7625    else if (width == 1 || height == 1) {
7626       assert(1 <= depth);
7627 
7628       halveImagePackedPixelSlice(components,
7629 				 extractPackedPixel,shovePackedPixel,
7630 				 width, height, depth, dataIn, dataOut,
7631 				 pixelSizeInBytes, rowSizeInBytes,
7632 				 imageSizeInBytes, isSwap);
7633       return;
7634    }
7635    {
7636       int ii, jj, dd;
7637 
7638       int halfWidth= width / 2;
7639       int halfHeight= height / 2;
7640       int halfDepth= depth / 2;
7641       const char *src= (const char *) dataIn;
7642       int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
7643       int outIndex= 0;
7644 
7645       for (dd= 0; dd < halfDepth; dd++) {
7646 	 for (ii= 0; ii< halfHeight; ii++) {
7647 	    for (jj= 0; jj< halfWidth; jj++) {
7648 #define BOX8 8
7649 	       float totals[4]; /* 4 is maximum components */
7650 	       float extractTotals[BOX8][4]; /* 4 is maximum components */
7651 	       int cc;
7652 
7653 	       (*extractPackedPixel)(isSwap,src,
7654 				     &extractTotals[0][0]);
7655 	       (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7656 				     &extractTotals[1][0]);
7657 	       (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7658 				     &extractTotals[2][0]);
7659 	       (*extractPackedPixel)(isSwap,
7660 				     (src+rowSizeInBytes+pixelSizeInBytes),
7661 				     &extractTotals[3][0]);
7662 
7663 	       (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7664 				     &extractTotals[4][0]);
7665 	       (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
7666 				     &extractTotals[5][0]);
7667 	       (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
7668 				     &extractTotals[6][0]);
7669 	       (*extractPackedPixel)(isSwap,
7670 				     (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
7671 				     &extractTotals[7][0]);
7672 	       for (cc = 0; cc < components; cc++) {
7673 		  int kk;
7674 
7675 		  /* grab 8 pixels to average */
7676 		  totals[cc]= 0.0;
7677 		  /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7678 		   *		  extractTotals[2][RED]+extractTotals[3][RED]+
7679 		   *		  extractTotals[4][RED]+extractTotals[5][RED]+
7680 		   *		  extractTotals[6][RED]+extractTotals[7][RED];
7681 		   * totals[RED]/= 8.0;
7682 		   */
7683 		  for (kk = 0; kk < BOX8; kk++) {
7684 		     totals[cc]+= extractTotals[kk][cc];
7685 		  }
7686 		  totals[cc]/= (float)BOX8;
7687 	       }
7688 	       (*shovePackedPixel)(totals,outIndex,dataOut);
7689 
7690 	       outIndex++;
7691 	       /* skip over to next square of 4 */
7692 	       src+= pixelSizeInBytes + pixelSizeInBytes;
7693 	    }
7694 	    /* skip past pad bytes, if any, to get to next row */
7695 	    src+= padBytes;
7696 
7697 	    /* src is at beginning of a row here, but it's the second row of
7698 	     * the square block of 4 pixels that we just worked on so we
7699 	     * need to go one more row.
7700 	     * i.e.,
7701 	     *			 OO...
7702 	     *		 here -->OO...
7703 	     *	     but want -->OO...
7704 	     *			 OO...
7705 	     *			 ...
7706 	     */
7707 	    src+= rowSizeInBytes;
7708 	 }
7709 
7710 	 src+= imageSizeInBytes;
7711       } /* for dd */
7712 
7713       /* both pointers must reach one byte after the end */
7714       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
7715       assert(outIndex == halfWidth * halfHeight * halfDepth);
7716    } /* for dd */
7717 
7718 } /* halveImagePackedPixel3D() */
7719 
gluBuild3DMipmapLevelsCore(GLenum target,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLsizei widthPowerOf2,GLsizei heightPowerOf2,GLsizei depthPowerOf2,GLenum format,GLenum type,GLint userLevel,GLint baseLevel,GLint maxLevel,const void * data)7720 static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
7721 				      GLsizei width,
7722 				      GLsizei height,
7723 				      GLsizei depth,
7724 				      GLsizei widthPowerOf2,
7725 				      GLsizei heightPowerOf2,
7726 				      GLsizei depthPowerOf2,
7727 				      GLenum format, GLenum type,
7728 				      GLint userLevel,
7729 				      GLint baseLevel,GLint maxLevel,
7730 				      const void *data)
7731 {
7732    GLint newWidth, newHeight, newDepth;
7733    GLint level, levels;
7734    const void *usersImage;
7735    void *srcImage, *dstImage;
7736    __GLU_INIT_SWAP_IMAGE;
7737    GLint memReq;
7738    GLint cmpts;
7739 
7740    GLint myswapBytes, groupsPerLine, elementSize, groupSize;
7741    GLint rowsPerImage, imageSize;
7742    GLint rowSize, padding;
7743    PixelStorageModes psm;
7744 
7745    assert(checkMipmapArgs(internalFormat,format,type) == 0);
7746    assert(width >= 1 && height >= 1 && depth >= 1);
7747    assert(type != GL_BITMAP);
7748 
7749    srcImage = dstImage = NULL;
7750 
7751    newWidth= widthPowerOf2;
7752    newHeight= heightPowerOf2;
7753    newDepth= depthPowerOf2;
7754    levels = computeLog(newWidth);
7755    level = computeLog(newHeight);
7756    if (level > levels) levels=level;
7757    level = computeLog(newDepth);
7758    if (level > levels) levels=level;
7759 
7760    levels+= userLevel;
7761 
7762    retrieveStoreModes3D(&psm);
7763    myswapBytes = psm.unpack_swap_bytes;
7764    cmpts = elements_per_group(format,type);
7765    if (psm.unpack_row_length > 0) {
7766        groupsPerLine = psm.unpack_row_length;
7767    } else {
7768        groupsPerLine = width;
7769    }
7770 
7771    elementSize = bytes_per_element(type);
7772    groupSize = elementSize * cmpts;
7773    if (elementSize == 1) myswapBytes = 0;
7774 
7775    /* 3dstuff begin */
7776    if (psm.unpack_image_height > 0) {
7777       rowsPerImage= psm.unpack_image_height;
7778    }
7779    else {
7780       rowsPerImage= height;
7781    }
7782 
7783    /* 3dstuff end */
7784    rowSize = groupsPerLine * groupSize;
7785    padding = (rowSize % psm.unpack_alignment);
7786    if (padding) {
7787        rowSize += psm.unpack_alignment - padding;
7788    }
7789 
7790    imageSize= rowsPerImage * rowSize; /* 3dstuff */
7791 
7792    usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
7793 				  psm.unpack_skip_pixels * groupSize +
7794 				  /* 3dstuff */
7795 				  psm.unpack_skip_images * imageSize;
7796 
7797    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
7798    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
7799    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
7800    glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
7801    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
7802 
7803    level = userLevel;
7804 
7805    if (width == newWidth && height == newHeight && depth == newDepth) {
7806        /* Use usersImage for level userLevel */
7807        if (baseLevel <= level && level <= maxLevel) {
7808 	  gluTexImage3D(target, level, internalFormat, width,
7809 		       height, depth, 0, format, type,
7810 		       usersImage);
7811        }
7812        if(levels == 0) { /* we're done. clean up and return */
7813 	 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7814 	 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7815 	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7816 	 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7817 	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7818 	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7819 	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7820 	 return 0;
7821        }
7822        {
7823 	  int nextWidth= newWidth/2;
7824 	  int nextHeight= newHeight/2;
7825 	  int nextDepth= newDepth/2;
7826 
7827 	  /* clamp to 1 */
7828 	  if (nextWidth < 1) nextWidth= 1;
7829 	  if (nextHeight < 1) nextHeight= 1;
7830 	  if (nextDepth < 1) nextDepth= 1;
7831        memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
7832        }
7833        switch(type) {
7834        case GL_UNSIGNED_BYTE:
7835 	 dstImage = (GLubyte *)malloc(memReq);
7836 	 break;
7837        case GL_BYTE:
7838 	 dstImage = (GLbyte *)malloc(memReq);
7839 	 break;
7840        case GL_UNSIGNED_SHORT:
7841 	 dstImage = (GLushort *)malloc(memReq);
7842 	 break;
7843        case GL_SHORT:
7844 	 dstImage = (GLshort *)malloc(memReq);
7845 	 break;
7846        case GL_UNSIGNED_INT:
7847 	 dstImage = (GLuint *)malloc(memReq);
7848 	 break;
7849        case GL_INT:
7850 	 dstImage = (GLint *)malloc(memReq);
7851 	 break;
7852        case GL_FLOAT:
7853 	 dstImage = (GLfloat *)malloc(memReq);
7854 	 break;
7855        case GL_UNSIGNED_BYTE_3_3_2:
7856        case GL_UNSIGNED_BYTE_2_3_3_REV:
7857 	 dstImage = (GLubyte *)malloc(memReq);
7858 	 break;
7859        case GL_UNSIGNED_SHORT_5_6_5:
7860        case GL_UNSIGNED_SHORT_5_6_5_REV:
7861        case GL_UNSIGNED_SHORT_4_4_4_4:
7862        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7863        case GL_UNSIGNED_SHORT_5_5_5_1:
7864        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7865 	 dstImage = (GLushort *)malloc(memReq);
7866 	 break;
7867        case GL_UNSIGNED_INT_8_8_8_8:
7868        case GL_UNSIGNED_INT_8_8_8_8_REV:
7869        case GL_UNSIGNED_INT_10_10_10_2:
7870        case GL_UNSIGNED_INT_2_10_10_10_REV:
7871 	 dstImage = (GLuint *)malloc(memReq);
7872 	 break;
7873        default:
7874 	 return GLU_INVALID_ENUM; /* assertion */
7875        }
7876        if (dstImage == NULL) {
7877 	 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7878 	 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7879 	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7880 	 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7881 	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7882 	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7883 	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7884 	 return GLU_OUT_OF_MEMORY;
7885        }
7886        else
7887 	 switch(type) {
7888 	 case GL_UNSIGNED_BYTE:
7889 	   if (depth > 1) {
7890 	     halveImage3D(cmpts,extractUbyte,shoveUbyte,
7891 			  width,height,depth,
7892 			  usersImage,dstImage,elementSize,groupSize,rowSize,
7893 			  imageSize,myswapBytes);
7894 	   }
7895 	   else {
7896 	     halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
7897 			      elementSize,rowSize,groupSize);
7898 	   }
7899 	   break;
7900 	 case GL_BYTE:
7901 	   if (depth > 1) {
7902 	   halveImage3D(cmpts,extractSbyte,shoveSbyte,
7903 			width,height,depth,
7904 			usersImage,dstImage,elementSize,groupSize,rowSize,
7905 			imageSize,myswapBytes);
7906 	   }
7907 	   else {
7908 	     halveImage_byte(cmpts,width,height,usersImage,dstImage,
7909 			     elementSize,rowSize,groupSize);
7910 	   }
7911 	   break;
7912 	 case GL_UNSIGNED_SHORT:
7913 	   if (depth > 1) {
7914 	   halveImage3D(cmpts,extractUshort,shoveUshort,
7915 			width,height,depth,
7916 			usersImage,dstImage,elementSize,groupSize,rowSize,
7917 			imageSize,myswapBytes);
7918 	   }
7919 	   else {
7920 	     halveImage_ushort(cmpts,width,height,usersImage,dstImage,
7921 			       elementSize,rowSize,groupSize,myswapBytes);
7922 	   }
7923 	   break;
7924 	 case GL_SHORT:
7925 	   if (depth > 1) {
7926 	   halveImage3D(cmpts,extractSshort,shoveSshort,
7927 			width,height,depth,
7928 			usersImage,dstImage,elementSize,groupSize,rowSize,
7929 			imageSize,myswapBytes);
7930 	   }
7931 	   else {
7932 	     halveImage_short(cmpts,width,height,usersImage,dstImage,
7933 			      elementSize,rowSize,groupSize,myswapBytes);
7934 	   }
7935 	   break;
7936 	 case GL_UNSIGNED_INT:
7937 	   if (depth > 1) {
7938 	   halveImage3D(cmpts,extractUint,shoveUint,
7939 			width,height,depth,
7940 			usersImage,dstImage,elementSize,groupSize,rowSize,
7941 			imageSize,myswapBytes);
7942 	   }
7943 	   else {
7944 	     halveImage_uint(cmpts,width,height,usersImage,dstImage,
7945 			     elementSize,rowSize,groupSize,myswapBytes);
7946 	   }
7947 	   break;
7948 	 case GL_INT:
7949 	   if (depth > 1) {
7950 	   halveImage3D(cmpts,extractSint,shoveSint,
7951 			width,height,depth,
7952 			usersImage,dstImage,elementSize,groupSize,rowSize,
7953 			imageSize,myswapBytes);
7954 	   }
7955 	   else {
7956 	     halveImage_int(cmpts,width,height,usersImage,dstImage,
7957 			    elementSize,rowSize,groupSize,myswapBytes);
7958 	   }
7959 	   break;
7960 	 case GL_FLOAT:
7961 	   if (depth > 1 ) {
7962 	   halveImage3D(cmpts,extractFloat,shoveFloat,
7963 			width,height,depth,
7964 			usersImage,dstImage,elementSize,groupSize,rowSize,
7965 			imageSize,myswapBytes);
7966 	   }
7967 	   else {
7968 	     halveImage_float(cmpts,width,height,usersImage,dstImage,
7969 			      elementSize,rowSize,groupSize,myswapBytes);
7970 	   }
7971 	   break;
7972 	 case GL_UNSIGNED_BYTE_3_3_2:
7973 	   assert(format == GL_RGB);
7974 	   halveImagePackedPixel3D(3,extract332,shove332,
7975 				   width,height,depth,usersImage,dstImage,
7976 				   elementSize,rowSize,imageSize,myswapBytes);
7977 	   break;
7978 	 case GL_UNSIGNED_BYTE_2_3_3_REV:
7979 	   assert(format == GL_RGB);
7980 	   halveImagePackedPixel3D(3,extract233rev,shove233rev,
7981 				   width,height,depth,usersImage,dstImage,
7982 				   elementSize,rowSize,imageSize,myswapBytes);
7983 	   break;
7984 	 case GL_UNSIGNED_SHORT_5_6_5:
7985 	   halveImagePackedPixel3D(3,extract565,shove565,
7986 				   width,height,depth,usersImage,dstImage,
7987 				   elementSize,rowSize,imageSize,myswapBytes);
7988 	   break;
7989 	 case GL_UNSIGNED_SHORT_5_6_5_REV:
7990 	   halveImagePackedPixel3D(3,extract565rev,shove565rev,
7991 				   width,height,depth,usersImage,dstImage,
7992 				   elementSize,rowSize,imageSize,myswapBytes);
7993 	   break;
7994 	 case GL_UNSIGNED_SHORT_4_4_4_4:
7995 	   halveImagePackedPixel3D(4,extract4444,shove4444,
7996 				   width,height,depth,usersImage,dstImage,
7997 				   elementSize,rowSize,imageSize,myswapBytes);
7998 	   break;
7999 	 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8000 	   halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8001 				   width,height,depth,usersImage,dstImage,
8002 				   elementSize,rowSize,imageSize,myswapBytes);
8003 	   break;
8004 	 case GL_UNSIGNED_SHORT_5_5_5_1:
8005 	   halveImagePackedPixel3D(4,extract5551,shove5551,
8006 				   width,height,depth,usersImage,dstImage,
8007 				   elementSize,rowSize,imageSize,myswapBytes);
8008 	   break;
8009 	 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8010 	   halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8011 				   width,height,depth,usersImage,dstImage,
8012 				   elementSize,rowSize,imageSize,myswapBytes);
8013 	   break;
8014 	 case GL_UNSIGNED_INT_8_8_8_8:
8015 	   halveImagePackedPixel3D(4,extract8888,shove8888,
8016 				   width,height,depth,usersImage,dstImage,
8017 				   elementSize,rowSize,imageSize,myswapBytes);
8018 	   break;
8019 	 case GL_UNSIGNED_INT_8_8_8_8_REV:
8020 	   halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8021 				   width,height,depth,usersImage,dstImage,
8022 				   elementSize,rowSize,imageSize,myswapBytes);
8023 	   break;
8024 	 case GL_UNSIGNED_INT_10_10_10_2:
8025 	   halveImagePackedPixel3D(4,extract1010102,shove1010102,
8026 				   width,height,depth,usersImage,dstImage,
8027 				   elementSize,rowSize,imageSize,myswapBytes);
8028 	   break;
8029 	 case GL_UNSIGNED_INT_2_10_10_10_REV:
8030 	   halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8031 				   width,height,depth,usersImage,dstImage,
8032 				   elementSize,rowSize,imageSize,myswapBytes);
8033 	   break;
8034 	 default:
8035 	   assert(0);
8036 	   break;
8037 	 }
8038        newWidth = width/2;
8039        newHeight = height/2;
8040        newDepth = depth/2;
8041        /* clamp to 1 */
8042        if (newWidth < 1) newWidth= 1;
8043        if (newHeight < 1) newHeight= 1;
8044        if (newDepth < 1) newDepth= 1;
8045 
8046        myswapBytes = 0;
8047        rowSize = newWidth * groupSize;
8048        imageSize= rowSize * newHeight; /* 3dstuff */
8049        memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8050        /* Swap srcImage and dstImage */
8051        __GLU_SWAP_IMAGE(srcImage,dstImage);
8052        switch(type) {
8053        case GL_UNSIGNED_BYTE:
8054 	 dstImage = (GLubyte *)malloc(memReq);
8055 	 break;
8056        case GL_BYTE:
8057 	 dstImage = (GLbyte *)malloc(memReq);
8058 	 break;
8059        case GL_UNSIGNED_SHORT:
8060 	 dstImage = (GLushort *)malloc(memReq);
8061 	 break;
8062        case GL_SHORT:
8063 	 dstImage = (GLshort *)malloc(memReq);
8064 	 break;
8065        case GL_UNSIGNED_INT:
8066 	 dstImage = (GLuint *)malloc(memReq);
8067 	 break;
8068        case GL_INT:
8069 	 dstImage = (GLint *)malloc(memReq);
8070 	 break;
8071        case GL_FLOAT:
8072 	 dstImage = (GLfloat *)malloc(memReq);
8073 	 break;
8074        case GL_UNSIGNED_BYTE_3_3_2:
8075        case GL_UNSIGNED_BYTE_2_3_3_REV:
8076 	 dstImage = (GLubyte *)malloc(memReq);
8077 	 break;
8078        case GL_UNSIGNED_SHORT_5_6_5:
8079        case GL_UNSIGNED_SHORT_5_6_5_REV:
8080        case GL_UNSIGNED_SHORT_4_4_4_4:
8081        case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8082        case GL_UNSIGNED_SHORT_5_5_5_1:
8083        case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8084 	 dstImage = (GLushort *)malloc(memReq);
8085 	 break;
8086        case GL_UNSIGNED_INT_8_8_8_8:
8087        case GL_UNSIGNED_INT_8_8_8_8_REV:
8088        case GL_UNSIGNED_INT_10_10_10_2:
8089        case GL_UNSIGNED_INT_2_10_10_10_REV:
8090 	 dstImage = (GLuint *)malloc(memReq);
8091 	 break;
8092        default:
8093 	 return GLU_INVALID_ENUM; /* assertion */
8094        }
8095        if (dstImage == NULL) {
8096 	 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8097 	 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8098 	 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8099 	 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8100 	 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8101 	 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8102 	 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8103 	 free(srcImage);
8104 	 return GLU_OUT_OF_MEMORY;
8105        }
8106        /* level userLevel+1 is in srcImage; level userLevel already saved */
8107        level = userLevel+1;
8108    } else {/* user's image is *not* nice power-of-2 sized square */
8109        memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8110        switch(type) {
8111 	   case GL_UNSIGNED_BYTE:
8112 	       dstImage = (GLubyte *)malloc(memReq);
8113 	       break;
8114 	   case GL_BYTE:
8115 	       dstImage = (GLbyte *)malloc(memReq);
8116 	       break;
8117 	   case GL_UNSIGNED_SHORT:
8118 	       dstImage = (GLushort *)malloc(memReq);
8119 	       break;
8120 	   case GL_SHORT:
8121 	       dstImage = (GLshort *)malloc(memReq);
8122 	       break;
8123 	   case GL_UNSIGNED_INT:
8124 	       dstImage = (GLuint *)malloc(memReq);
8125 	       break;
8126 	   case GL_INT:
8127 	       dstImage = (GLint *)malloc(memReq);
8128 	       break;
8129 	   case GL_FLOAT:
8130 	       dstImage = (GLfloat *)malloc(memReq);
8131 	       break;
8132 	   case GL_UNSIGNED_BYTE_3_3_2:
8133 	   case GL_UNSIGNED_BYTE_2_3_3_REV:
8134 	       dstImage = (GLubyte *)malloc(memReq);
8135 	       break;
8136 	   case GL_UNSIGNED_SHORT_5_6_5:
8137 	   case GL_UNSIGNED_SHORT_5_6_5_REV:
8138 	   case GL_UNSIGNED_SHORT_4_4_4_4:
8139 	   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8140 	   case GL_UNSIGNED_SHORT_5_5_5_1:
8141 	   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8142 	       dstImage = (GLushort *)malloc(memReq);
8143 	       break;
8144 	   case GL_UNSIGNED_INT_8_8_8_8:
8145 	   case GL_UNSIGNED_INT_8_8_8_8_REV:
8146 	   case GL_UNSIGNED_INT_10_10_10_2:
8147 	   case GL_UNSIGNED_INT_2_10_10_10_REV:
8148 	       dstImage = (GLuint *)malloc(memReq);
8149 	       break;
8150 	   default:
8151 	       return GLU_INVALID_ENUM; /* assertion */
8152        }
8153 
8154        if (dstImage == NULL) {
8155 	   glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8156 	   glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8157 	   glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8158 	   glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8159 	   glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8160 	   glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8161 	   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8162 	   return GLU_OUT_OF_MEMORY;
8163        }
8164        /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8165        width,height,depth,newWidth,newHeight,newDepth);*/
8166 
8167        gluScaleImage3D(format, width, height, depth, type, usersImage,
8168 		       newWidth, newHeight, newDepth, type, dstImage);
8169 
8170        myswapBytes = 0;
8171        rowSize = newWidth * groupSize;
8172        imageSize = rowSize * newHeight; /* 3dstuff */
8173        /* Swap dstImage and srcImage */
8174        __GLU_SWAP_IMAGE(srcImage,dstImage);
8175 
8176        if(levels != 0) { /* use as little memory as possible */
8177 	 {
8178 	    int nextWidth= newWidth/2;
8179 	    int nextHeight= newHeight/2;
8180 	    int nextDepth= newDepth/2;
8181 	    if (nextWidth < 1) nextWidth= 1;
8182 	    if (nextHeight < 1) nextHeight= 1;
8183 	    if (nextDepth < 1) nextDepth= 1;
8184 
8185 	 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
8186 	 }
8187 	 switch(type) {
8188 	 case GL_UNSIGNED_BYTE:
8189 	   dstImage = (GLubyte *)malloc(memReq);
8190 	   break;
8191 	 case GL_BYTE:
8192 	   dstImage = (GLbyte *)malloc(memReq);
8193 	   break;
8194 	 case GL_UNSIGNED_SHORT:
8195 	   dstImage = (GLushort *)malloc(memReq);
8196 	   break;
8197 	 case GL_SHORT:
8198 	   dstImage = (GLshort *)malloc(memReq);
8199 	   break;
8200 	 case GL_UNSIGNED_INT:
8201 	   dstImage = (GLuint *)malloc(memReq);
8202 	   break;
8203 	 case GL_INT:
8204 	   dstImage = (GLint *)malloc(memReq);
8205 	   break;
8206 	 case GL_FLOAT:
8207 	   dstImage = (GLfloat *)malloc(memReq);
8208 	   break;
8209 	 case GL_UNSIGNED_BYTE_3_3_2:
8210 	 case GL_UNSIGNED_BYTE_2_3_3_REV:
8211 	   dstImage = (GLubyte *)malloc(memReq);
8212 	   break;
8213 	 case GL_UNSIGNED_SHORT_5_6_5:
8214 	 case GL_UNSIGNED_SHORT_5_6_5_REV:
8215 	 case GL_UNSIGNED_SHORT_4_4_4_4:
8216 	 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8217 	 case GL_UNSIGNED_SHORT_5_5_5_1:
8218 	 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8219 	   dstImage = (GLushort *)malloc(memReq);
8220 	   break;
8221 	 case GL_UNSIGNED_INT_8_8_8_8:
8222 	 case GL_UNSIGNED_INT_8_8_8_8_REV:
8223 	 case GL_UNSIGNED_INT_10_10_10_2:
8224 	 case GL_UNSIGNED_INT_2_10_10_10_REV:
8225 	   dstImage = (GLuint *)malloc(memReq);
8226 	   break;
8227 	 default:
8228 	   return GLU_INVALID_ENUM; /* assertion */
8229 	 }
8230 	 if (dstImage == NULL) {
8231 	   glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8232 	   glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8233 	   glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8234 	   glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8235 	   glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8236 	   glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8237 	   glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8238 	   free(srcImage);
8239 	   return GLU_OUT_OF_MEMORY;
8240 	 }
8241        }
8242        /* level userLevel is in srcImage; nothing saved yet */
8243        level = userLevel;
8244    }
8245 
8246    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
8247    if (baseLevel <= level && level <= maxLevel) {
8248      gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
8249 		  0,format, type, (void *)srcImage);
8250    }
8251    level++; /* update current level for the loop */
8252    for (; level <= levels; level++) {
8253        switch(type) {
8254 	   case GL_UNSIGNED_BYTE:
8255 	       if (newDepth > 1) {
8256 	       halveImage3D(cmpts,extractUbyte,shoveUbyte,
8257 			    newWidth,newHeight,newDepth,
8258 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8259 			    imageSize,myswapBytes);
8260 	       }
8261 	       else {
8262 		 halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
8263 				  elementSize,rowSize,groupSize);
8264 	       }
8265 	       break;
8266 	   case GL_BYTE:
8267 	       if (newDepth > 1) {
8268 	       halveImage3D(cmpts,extractSbyte,shoveSbyte,
8269 			    newWidth,newHeight,newDepth,
8270 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8271 			    imageSize,myswapBytes);
8272 	       }
8273 	       else {
8274 		 halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
8275 				  elementSize,rowSize,groupSize);
8276 	       }
8277 	       break;
8278 	   case GL_UNSIGNED_SHORT:
8279 	       if (newDepth > 1) {
8280 	       halveImage3D(cmpts,extractUshort,shoveUshort,
8281 			    newWidth,newHeight,newDepth,
8282 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8283 			    imageSize,myswapBytes);
8284 	       }
8285 	       else {
8286 		 halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
8287 				   elementSize,rowSize,groupSize,myswapBytes);
8288 	       }
8289 	       break;
8290 	   case GL_SHORT:
8291 	       if (newDepth > 1) {
8292 	       halveImage3D(cmpts,extractSshort,shoveSshort,
8293 			    newWidth,newHeight,newDepth,
8294 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8295 			    imageSize,myswapBytes);
8296 	       }
8297 	       else {
8298 		 halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
8299 				  elementSize,rowSize,groupSize,myswapBytes);
8300 	       }
8301 	       break;
8302 	   case GL_UNSIGNED_INT:
8303 	       if (newDepth > 1) {
8304 	       halveImage3D(cmpts,extractUint,shoveUint,
8305 			    newWidth,newHeight,newDepth,
8306 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8307 			    imageSize,myswapBytes);
8308 	       }
8309 	       else {
8310 		 halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
8311 				 elementSize,rowSize,groupSize,myswapBytes);
8312 	       }
8313 	       break;
8314 	   case GL_INT:
8315 	       if (newDepth > 1) {
8316 	       halveImage3D(cmpts,extractSint,shoveSint,
8317 			    newWidth,newHeight,newDepth,
8318 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8319 			    imageSize,myswapBytes);
8320 	       }
8321 	       else {
8322 		 halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
8323 				elementSize,rowSize,groupSize,myswapBytes);
8324 	       }
8325 	       break;
8326 	   case GL_FLOAT:
8327 	       if (newDepth > 1) {
8328 	       halveImage3D(cmpts,extractFloat,shoveFloat,
8329 			    newWidth,newHeight,newDepth,
8330 			    srcImage,dstImage,elementSize,groupSize,rowSize,
8331 			    imageSize,myswapBytes);
8332 	       }
8333 	       else {
8334 		 halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
8335 				  elementSize,rowSize,groupSize,myswapBytes);
8336 	       }
8337 	       break;
8338 	   case GL_UNSIGNED_BYTE_3_3_2:
8339 	       halveImagePackedPixel3D(3,extract332,shove332,
8340 				       newWidth,newHeight,newDepth,
8341 				       srcImage,dstImage,elementSize,rowSize,
8342 				       imageSize,myswapBytes);
8343 	       break;
8344 	   case GL_UNSIGNED_BYTE_2_3_3_REV:
8345 	       halveImagePackedPixel3D(3,extract233rev,shove233rev,
8346 				       newWidth,newHeight,newDepth,
8347 				       srcImage,dstImage,elementSize,rowSize,
8348 				       imageSize,myswapBytes);
8349 	       break;
8350 	   case GL_UNSIGNED_SHORT_5_6_5:
8351 	       halveImagePackedPixel3D(3,extract565,shove565,
8352 				       newWidth,newHeight,newDepth,
8353 				       srcImage,dstImage,elementSize,rowSize,
8354 				       imageSize,myswapBytes);
8355 	       break;
8356 	   case GL_UNSIGNED_SHORT_5_6_5_REV:
8357 	       halveImagePackedPixel3D(3,extract565rev,shove565rev,
8358 				       newWidth,newHeight,newDepth,
8359 				       srcImage,dstImage,elementSize,rowSize,
8360 				       imageSize,myswapBytes);
8361 	       break;
8362 	   case GL_UNSIGNED_SHORT_4_4_4_4:
8363 	       halveImagePackedPixel3D(4,extract4444,shove4444,
8364 				       newWidth,newHeight,newDepth,
8365 				       srcImage,dstImage,elementSize,rowSize,
8366 				       imageSize,myswapBytes);
8367 	       break;
8368 	   case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8369 	       halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8370 				       newWidth,newHeight,newDepth,
8371 				       srcImage,dstImage,elementSize,rowSize,
8372 				       imageSize,myswapBytes);
8373 	       break;
8374 	   case GL_UNSIGNED_SHORT_5_5_5_1:
8375 	       halveImagePackedPixel3D(4,extract5551,shove5551,
8376 				       newWidth,newHeight,newDepth,
8377 				       srcImage,dstImage,elementSize,rowSize,
8378 				       imageSize,myswapBytes);
8379 	       break;
8380 	   case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8381 	       halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8382 				       newWidth,newHeight,newDepth,
8383 				       srcImage,dstImage,elementSize,rowSize,
8384 				       imageSize,myswapBytes);
8385 	       break;
8386 	   case GL_UNSIGNED_INT_8_8_8_8:
8387 	       halveImagePackedPixel3D(4,extract8888,shove8888,
8388 				       newWidth,newHeight,newDepth,
8389 				       srcImage,dstImage,elementSize,rowSize,
8390 				       imageSize,myswapBytes);
8391 	       break;
8392 	   case GL_UNSIGNED_INT_8_8_8_8_REV:
8393 	       halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8394 				       newWidth,newHeight,newDepth,
8395 				       srcImage,dstImage,elementSize,rowSize,
8396 				       imageSize,myswapBytes);
8397 	       break;
8398 	   case GL_UNSIGNED_INT_10_10_10_2:
8399 	       halveImagePackedPixel3D(4,extract1010102,shove1010102,
8400 				       newWidth,newHeight,newDepth,
8401 				       srcImage,dstImage,elementSize,rowSize,
8402 				       imageSize,myswapBytes);
8403 	       break;
8404 	   case GL_UNSIGNED_INT_2_10_10_10_REV:
8405 	       halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8406 				       newWidth,newHeight,newDepth,
8407 				       srcImage,dstImage,elementSize,rowSize,
8408 				       imageSize,myswapBytes);
8409 	       break;
8410 	   default:
8411 	       assert(0);
8412 	       break;
8413        }
8414 
8415        __GLU_SWAP_IMAGE(srcImage,dstImage);
8416 
8417        if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
8418        if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
8419        if (newDepth > 1) newDepth /= 2;
8420        {
8421 	  /* call tex image with srcImage untouched since it's not padded */
8422 	  if (baseLevel <= level && level <= maxLevel) {
8423 	    gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
8424 			 newDepth,0, format, type, (void *) srcImage);
8425 	  }
8426        }
8427    } /* for level */
8428    glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8429    glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8430    glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8431    glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8432    glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8433    glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8434    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8435 
8436    free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
8437    if (dstImage) { /* if it's non-rectangular and only 1 level */
8438      free(dstImage);
8439    }
8440    return 0;
8441 } /* gluBuild3DMipmapLevelsCore() */
8442 
8443 GLint GLAPIENTRY
gluBuild3DMipmapLevels(GLenum target,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLint userLevel,GLint baseLevel,GLint maxLevel,const void * data)8444 gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
8445 			     GLsizei width, GLsizei height, GLsizei depth,
8446 			     GLenum format, GLenum type,
8447 			     GLint userLevel, GLint baseLevel, GLint maxLevel,
8448 			     const void *data)
8449 {
8450    int level, levels;
8451 
8452    int rc= checkMipmapArgs(internalFormat,format,type);
8453    if (rc != 0) return rc;
8454 
8455    if (width < 1 || height < 1 || depth < 1) {
8456        return GLU_INVALID_VALUE;
8457    }
8458 
8459    if(type == GL_BITMAP) {
8460       return GLU_INVALID_ENUM;
8461    }
8462 
8463    levels = computeLog(width);
8464    level = computeLog(height);
8465    if (level > levels) levels=level;
8466    level = computeLog(depth);
8467    if (level > levels) levels=level;
8468 
8469    levels+= userLevel;
8470    if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
8471       return GLU_INVALID_VALUE;
8472 
8473    return gluBuild3DMipmapLevelsCore(target, internalFormat,
8474 				     width, height, depth,
8475 				     width, height, depth,
8476 				     format, type,
8477 				     userLevel, baseLevel, maxLevel,
8478 				     data);
8479 } /* gluBuild3DMipmapLevels() */
8480 
8481 GLint GLAPIENTRY
gluBuild3DMipmaps(GLenum target,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * data)8482 gluBuild3DMipmaps(GLenum target, GLint internalFormat,
8483 			GLsizei width, GLsizei height, GLsizei depth,
8484 			GLenum format, GLenum type, const void *data)
8485 {
8486    GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
8487    int level, levels;
8488 
8489    int rc= checkMipmapArgs(internalFormat,format,type);
8490    if (rc != 0) return rc;
8491 
8492    if (width < 1 || height < 1 || depth < 1) {
8493        return GLU_INVALID_VALUE;
8494    }
8495 
8496    if(type == GL_BITMAP) {
8497       return GLU_INVALID_ENUM;
8498    }
8499 
8500    closestFit3D(target,width,height,depth,internalFormat,format,type,
8501 		&widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
8502 
8503    levels = computeLog(widthPowerOf2);
8504    level = computeLog(heightPowerOf2);
8505    if (level > levels) levels=level;
8506    level = computeLog(depthPowerOf2);
8507    if (level > levels) levels=level;
8508 
8509    return gluBuild3DMipmapLevelsCore(target, internalFormat,
8510 				     width, height, depth,
8511 				     widthPowerOf2, heightPowerOf2,
8512 				     depthPowerOf2,
8513 				     format, type, 0, 0, levels,
8514 				     data);
8515 } /* gluBuild3DMipmaps() */
8516 
extractUbyte(int isSwap,const void * ubyte)8517 static GLdouble extractUbyte(int isSwap, const void *ubyte)
8518 {
8519    isSwap= isSwap;		/* turn off warnings */
8520 
8521    assert(*((const GLubyte *)ubyte) <= 255);
8522 
8523    return (GLdouble)(*((const GLubyte *)ubyte));
8524 } /* extractUbyte() */
8525 
shoveUbyte(GLdouble value,int index,void * data)8526 static void shoveUbyte(GLdouble value, int index, void *data)
8527 {
8528    assert(0.0 <= value && value < 256.0);
8529 
8530    ((GLubyte *)data)[index]= (GLubyte)value;
8531 } /* shoveUbyte() */
8532 
extractSbyte(int isSwap,const void * sbyte)8533 static GLdouble extractSbyte(int isSwap, const void *sbyte)
8534 {
8535    isSwap= isSwap;		/* turn off warnings */
8536 
8537    assert(*((const GLbyte *)sbyte) <= 127);
8538 
8539    return (GLdouble)(*((const GLbyte *)sbyte));
8540 } /* extractSbyte() */
8541 
shoveSbyte(GLdouble value,int index,void * data)8542 static void shoveSbyte(GLdouble value, int index, void *data)
8543 {
8544    ((GLbyte *)data)[index]= (GLbyte)value;
8545 } /* shoveSbyte() */
8546 
extractUshort(int isSwap,const void * uitem)8547 static GLdouble extractUshort(int isSwap, const void *uitem)
8548 {
8549    GLushort ushort;
8550 
8551    if (isSwap) {
8552      ushort= __GLU_SWAP_2_BYTES(uitem);
8553    }
8554    else {
8555      ushort= *(const GLushort *)uitem;
8556    }
8557 
8558    assert(ushort <= 65535);
8559 
8560    return (GLdouble)ushort;
8561 } /* extractUshort() */
8562 
shoveUshort(GLdouble value,int index,void * data)8563 static void shoveUshort(GLdouble value, int index, void *data)
8564 {
8565    assert(0.0 <= value && value < 65536.0);
8566 
8567    ((GLushort *)data)[index]= (GLushort)value;
8568 } /* shoveUshort() */
8569 
extractSshort(int isSwap,const void * sitem)8570 static GLdouble extractSshort(int isSwap, const void *sitem)
8571 {
8572    GLshort sshort;
8573 
8574    if (isSwap) {
8575      sshort= __GLU_SWAP_2_BYTES(sitem);
8576    }
8577    else {
8578      sshort= *(const GLshort *)sitem;
8579    }
8580 
8581    assert(sshort <= 32767);
8582 
8583    return (GLdouble)sshort;
8584 } /* extractSshort() */
8585 
shoveSshort(GLdouble value,int index,void * data)8586 static void shoveSshort(GLdouble value, int index, void *data)
8587 {
8588    assert(0.0 <= value && value < 32768.0);
8589 
8590    ((GLshort *)data)[index]= (GLshort)value;
8591 } /* shoveSshort() */
8592 
extractUint(int isSwap,const void * uitem)8593 static GLdouble extractUint(int isSwap, const void *uitem)
8594 {
8595    GLuint uint;
8596 
8597    if (isSwap) {
8598      uint= __GLU_SWAP_4_BYTES(uitem);
8599    }
8600    else {
8601      uint= *(const GLuint *)uitem;
8602    }
8603 
8604    assert(uint <= 0xffffffff);
8605 
8606    return (GLdouble)uint;
8607 } /* extractUint() */
8608 
shoveUint(GLdouble value,int index,void * data)8609 static void shoveUint(GLdouble value, int index, void *data)
8610 {
8611    assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
8612 
8613    ((GLuint *)data)[index]= (GLuint)value;
8614 } /* shoveUint() */
8615 
extractSint(int isSwap,const void * sitem)8616 static GLdouble extractSint(int isSwap, const void *sitem)
8617 {
8618    GLint sint;
8619 
8620    if (isSwap) {
8621      sint= __GLU_SWAP_4_BYTES(sitem);
8622    }
8623    else {
8624      sint= *(const GLint *)sitem;
8625    }
8626 
8627    assert(sint <= 0x7fffffff);
8628 
8629    return (GLdouble)sint;
8630 } /* extractSint() */
8631 
shoveSint(GLdouble value,int index,void * data)8632 static void shoveSint(GLdouble value, int index, void *data)
8633 {
8634    assert(0.0 <= value && value <= (GLdouble) INT_MAX);
8635 
8636    ((GLint *)data)[index]= (GLint)value;
8637 } /* shoveSint() */
8638 
extractFloat(int isSwap,const void * item)8639 static GLdouble extractFloat(int isSwap, const void *item)
8640 {
8641    GLfloat ffloat;
8642 
8643    if (isSwap) {
8644      ffloat= __GLU_SWAP_4_BYTES(item);
8645    }
8646    else {
8647      ffloat= *(const GLfloat *)item;
8648    }
8649 
8650    assert(ffloat <= 1.0);
8651 
8652    return (GLdouble)ffloat;
8653 } /* extractFloat() */
8654 
shoveFloat(GLdouble value,int index,void * data)8655 static void shoveFloat(GLdouble value, int index, void *data)
8656 {
8657    assert(0.0 <= value && value <= 1.0);
8658 
8659    ((GLfloat *)data)[index]= value;
8660 } /* shoveFloat() */
8661 
halveImageSlice(int components,GLdouble (* extract)(int,const void *),void (* shove)(GLdouble,int,void *),GLint width,GLint height,GLint depth,const void * dataIn,void * dataOut,GLint elementSizeInBytes,GLint groupSizeInBytes,GLint rowSizeInBytes,GLint imageSizeInBytes,GLint isSwap)8662 static void halveImageSlice(int components,
8663 			    GLdouble (*extract)(int, const void *),
8664 			    void (*shove)(GLdouble, int, void *),
8665 			    GLint width, GLint height, GLint depth,
8666 			    const void *dataIn, void *dataOut,
8667 			    GLint elementSizeInBytes,
8668 			    GLint groupSizeInBytes,
8669 			    GLint rowSizeInBytes,
8670 			    GLint imageSizeInBytes,
8671 			    GLint isSwap)
8672 {
8673    int ii, jj;
8674    int halfWidth= width / 2;
8675    int halfHeight= height / 2;
8676    int halfDepth= depth / 2;
8677    const char *src= (const char *)dataIn;
8678    int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes);
8679    int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8680    int outIndex= 0;
8681 
8682    assert((width == 1 || height == 1) && depth >= 2);
8683 
8684    if (width == height) {	/* a 1-pixel column viewed from top */
8685       /* printf("1-column\n");*/
8686       assert(width == 1 && height == 1);
8687       assert(depth >= 2);
8688 
8689       for (ii= 0; ii< halfDepth; ii++) {
8690 	 int cc;
8691 
8692 	 for (cc = 0; cc < components; cc++) {
8693 	    double totals[4];
8694 	    double extractTotals[BOX2][4];
8695 	    int kk;
8696 
8697 	    extractTotals[0][cc]= (*extract)(isSwap,src);
8698 	    extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
8699 
8700 	    /* average 2 pixels since only a column */
8701 	    totals[cc]= 0.0;
8702 	    /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8703 	     * totals[RED]/= 2.0;
8704 	     */
8705 	    for (kk = 0; kk < BOX2; kk++) {
8706 	      totals[cc]+= extractTotals[kk][cc];
8707 	    }
8708 	    totals[cc]/= (double)BOX2;
8709 
8710 	    (*shove)(totals[cc],outIndex,dataOut);
8711 	    outIndex++;
8712 	    src+= elementSizeInBytes;
8713 	 } /* for cc */
8714 
8715 	 /* skip over to next group of 2 */
8716 	 src+= rowSizeInBytes;
8717       } /* for ii */
8718 
8719       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8720       assert(outIndex == halfDepth * components);
8721    }
8722    else if (height == 1) {	/* horizontal slice viewed from top */
8723       /* printf("horizontal slice\n"); */
8724       assert(width != 1);
8725 
8726       for (ii= 0; ii< halfDepth; ii++) {
8727 	 for (jj= 0; jj< halfWidth; jj++) {
8728 	    int cc;
8729 
8730 	    for (cc = 0; cc < components; cc++) {
8731 	       int kk;
8732 	       double totals[4];
8733 	       double extractTotals[BOX4][4];
8734 
8735 	       extractTotals[0][cc]=(*extract)(isSwap,src);
8736 	       extractTotals[1][cc]=(*extract)(isSwap,
8737 					       (src+groupSizeInBytes));
8738 	       extractTotals[2][cc]=(*extract)(isSwap,
8739 					       (src+imageSizeInBytes));
8740 	       extractTotals[3][cc]=(*extract)(isSwap,
8741 					       (src+imageSizeInBytes+groupSizeInBytes));
8742 
8743 	       /* grab 4 pixels to average */
8744 	       totals[cc]= 0.0;
8745 	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8746 		*	       extractTotals[2][RED]+extractTotals[3][RED];
8747 		* totals[RED]/= 4.0;
8748 		*/
8749 	       for (kk = 0; kk < BOX4; kk++) {
8750 		  totals[cc]+= extractTotals[kk][cc];
8751 	       }
8752 	       totals[cc]/= (double)BOX4;
8753 
8754 	       (*shove)(totals[cc],outIndex,dataOut);
8755 	       outIndex++;
8756 
8757 	       src+= elementSizeInBytes;
8758 	    } /* for cc */
8759 
8760 	    /* skip over to next horizontal square of 4 */
8761 	    src+= groupSizeInBytes;
8762 	 } /* for jj */
8763 	 src+= rowPadBytes;
8764 
8765 	 src+= rowSizeInBytes;
8766       } /* for ii */
8767 
8768       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8769       assert(outIndex == halfWidth * halfDepth * components);
8770    }
8771    else if (width == 1) {	/* vertical slice viewed from top */
8772       /* printf("vertical slice\n"); */
8773       assert(height != 1);
8774 
8775       for (ii= 0; ii< halfDepth; ii++) {
8776 	 for (jj= 0; jj< halfHeight; jj++) {
8777 	    int cc;
8778 
8779 	    for (cc = 0; cc < components; cc++) {
8780 	       int kk;
8781 	       double totals[4];
8782 	       double extractTotals[BOX4][4];
8783 
8784 	       extractTotals[0][cc]=(*extract)(isSwap,src);
8785 	       extractTotals[1][cc]=(*extract)(isSwap,
8786 					       (src+rowSizeInBytes));
8787 	       extractTotals[2][cc]=(*extract)(isSwap,
8788 					       (src+imageSizeInBytes));
8789 	       extractTotals[3][cc]=(*extract)(isSwap,
8790 					       (src+imageSizeInBytes+rowSizeInBytes));
8791 
8792 	       /* grab 4 pixels to average */
8793 	       totals[cc]= 0.0;
8794 	       /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8795 		*	       extractTotals[2][RED]+extractTotals[3][RED];
8796 		* totals[RED]/= 4.0;
8797 		*/
8798 	       for (kk = 0; kk < BOX4; kk++) {
8799 		  totals[cc]+= extractTotals[kk][cc];
8800 	       }
8801 	       totals[cc]/= (double)BOX4;
8802 
8803 	       (*shove)(totals[cc],outIndex,dataOut);
8804 	       outIndex++;
8805 
8806 	       src+= elementSizeInBytes;
8807 	    } /* for cc */
8808 	    src+= rowPadBytes;
8809 
8810 	    /* skip over to next vertical square of 4 */
8811 	    src+= rowSizeInBytes;
8812 	 } /* for jj */
8813          src+= imagePadBytes;
8814 
8815 	 src+= imageSizeInBytes;
8816       } /* for ii */
8817 
8818       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8819       assert(outIndex == halfHeight * halfDepth * components);
8820    }
8821 
8822 } /* halveImageSlice() */
8823 
halveImage3D(int components,GLdouble (* extract)(int,const void *),void (* shove)(GLdouble,int,void *),GLint width,GLint height,GLint depth,const void * dataIn,void * dataOut,GLint elementSizeInBytes,GLint groupSizeInBytes,GLint rowSizeInBytes,GLint imageSizeInBytes,GLint isSwap)8824 static void halveImage3D(int components,
8825 			 GLdouble (*extract)(int, const void *),
8826 			 void (*shove)(GLdouble, int, void *),
8827 			 GLint width, GLint height, GLint depth,
8828 			 const void *dataIn, void *dataOut,
8829 			 GLint elementSizeInBytes,
8830 			 GLint groupSizeInBytes,
8831 			 GLint rowSizeInBytes,
8832 			 GLint imageSizeInBytes,
8833 			 GLint isSwap)
8834 {
8835    assert(depth > 1);
8836 
8837    /* a horizontal/vertical/one-column slice viewed from top */
8838    if (width == 1 || height == 1) {
8839       assert(1 <= depth);
8840 
8841       halveImageSlice(components,extract,shove, width, height, depth,
8842 		      dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
8843 		      rowSizeInBytes, imageSizeInBytes, isSwap);
8844       return;
8845    }
8846    {
8847       int ii, jj, dd;
8848 
8849       int halfWidth= width / 2;
8850       int halfHeight= height / 2;
8851       int halfDepth= depth / 2;
8852       const char *src= (const char *) dataIn;
8853       int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes);
8854       int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8855       int outIndex= 0;
8856 
8857       for (dd= 0; dd < halfDepth; dd++) {
8858 	 for (ii= 0; ii< halfHeight; ii++) {
8859 	    for (jj= 0; jj< halfWidth; jj++) {
8860 	       int cc;
8861 
8862 	       for (cc= 0; cc < components; cc++) {
8863 		  int kk;
8864 #define BOX8 8
8865 		  double totals[4];	/* 4 is maximum components */
8866 		  double extractTotals[BOX8][4]; /* 4 is maximum components */
8867 
8868 		  extractTotals[0][cc]= (*extract)(isSwap,src);
8869 		  extractTotals[1][cc]= (*extract)(isSwap,
8870 						   (src+groupSizeInBytes));
8871 		  extractTotals[2][cc]= (*extract)(isSwap,
8872 						   (src+rowSizeInBytes));
8873 		  extractTotals[3][cc]= (*extract)(isSwap,
8874 						   (src+rowSizeInBytes+groupSizeInBytes));
8875 
8876 		  extractTotals[4][cc]= (*extract)(isSwap,
8877 						   (src+imageSizeInBytes));
8878 
8879 		  extractTotals[5][cc]= (*extract)(isSwap,
8880 						   (src+groupSizeInBytes+imageSizeInBytes));
8881 		  extractTotals[6][cc]= (*extract)(isSwap,
8882 						   (src+rowSizeInBytes+imageSizeInBytes));
8883 		  extractTotals[7][cc]= (*extract)(isSwap,
8884 						   (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
8885 
8886 		  totals[cc]= 0.0;
8887 
8888 		  /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8889 		   *		  extractTotals[2][RED]+extractTotals[3][RED]+
8890 		   *		  extractTotals[4][RED]+extractTotals[5][RED]+
8891 		   *		  extractTotals[6][RED]+extractTotals[7][RED];
8892 		   * totals[RED]/= 8.0;
8893 		   */
8894 		  for (kk = 0; kk < BOX8; kk++) {
8895 		     totals[cc]+= extractTotals[kk][cc];
8896 		  }
8897 		  totals[cc]/= (double)BOX8;
8898 
8899 		  (*shove)(totals[cc],outIndex,dataOut);
8900 
8901 		  outIndex++;
8902 
8903 		  src+= elementSizeInBytes; /* go to next component */
8904 	       } /* for cc */
8905 
8906 	       /* skip over to next square of 4 */
8907 	       src+= groupSizeInBytes;
8908 	    } /* for jj */
8909 	    /* skip past pad bytes, if any, to get to next row */
8910 	    src+= rowPadBytes;
8911 
8912 	    /* src is at beginning of a row here, but it's the second row of
8913 	     * the square block of 4 pixels that we just worked on so we
8914 	     * need to go one more row.
8915 	     * i.e.,
8916 	     *			 OO...
8917 	     *		 here -->OO...
8918 	     *	     but want -->OO...
8919 	     *			 OO...
8920 	     *			 ...
8921 	     */
8922 	    src+= rowSizeInBytes;
8923 	 } /* for ii */
8924 
8925 	 /* skip past pad bytes, if any, to get to next image */
8926 	 src+= imagePadBytes;
8927 
8928 	 src+= imageSizeInBytes;
8929       } /* for dd */
8930 
8931       /* both pointers must reach one byte after the end */
8932       assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8933       assert(outIndex == halfWidth * halfHeight * halfDepth * components);
8934    }
8935 } /* halveImage3D() */
8936 
8937 
8938 
8939 /*** mipmap.c ***/
8940 
8941