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