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