2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
37 #include <limits.h> /* UINT_MAX */
50 /* Pixel storage modes */
53 GLint pack_row_length;
55 GLint pack_skip_pixels;
57 GLint pack_swap_bytes;
58 GLint pack_skip_images;
59 GLint pack_image_height;
61 GLint unpack_alignment;
62 GLint unpack_row_length;
63 GLint unpack_skip_rows;
64 GLint unpack_skip_pixels;
65 GLint unpack_lsb_first;
66 GLint unpack_swap_bytes;
67 GLint unpack_skip_images;
68 GLint unpack_image_height;
71 static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
74 GLenum, GLenum, GLint, GLint, GLint,
76 static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
79 GLenum, GLenum, GLint, GLint, GLint,
81 static int gluBuild3DMipmapLevelsCore(GLenum, GLint,
82 GLsizei, GLsizei, GLsizei,
83 GLsizei, GLsizei, GLsizei,
84 GLenum, GLenum, GLint, GLint, GLint,
88 * internal function declarations
90 static GLfloat bytes_per_element(GLenum type);
91 static GLint elements_per_group(GLenum format, GLenum type);
92 static GLint is_index(GLenum format);
93 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
94 static void fill_image(const PixelStorageModes *,
95 GLint width, GLint height, GLenum format,
96 GLenum type, GLboolean index_format,
97 const void *userdata, GLushort *newimage);
98 static void empty_image(const PixelStorageModes *,
99 GLint width, GLint height, GLenum format,
100 GLenum type, GLboolean index_format,
101 const GLushort *oldimage, void *userdata);
102 static void scale_internal(GLint components, GLint widthin, GLint heightin,
103 const GLushort *datain,
104 GLint widthout, GLint heightout,
107 static void scale_internal_ubyte(GLint components, GLint widthin,
108 GLint heightin, const GLubyte *datain,
109 GLint widthout, GLint heightout,
110 GLubyte *dataout, GLint element_size,
111 GLint ysize, GLint group_size);
112 static void scale_internal_byte(GLint components, GLint widthin,
113 GLint heightin, const GLbyte *datain,
114 GLint widthout, GLint heightout,
115 GLbyte *dataout, GLint element_size,
116 GLint ysize, GLint group_size);
117 static void scale_internal_ushort(GLint components, GLint widthin,
118 GLint heightin, const GLushort *datain,
119 GLint widthout, GLint heightout,
120 GLushort *dataout, GLint element_size,
121 GLint ysize, GLint group_size,
123 static void scale_internal_short(GLint components, GLint widthin,
124 GLint heightin, const GLshort *datain,
125 GLint widthout, GLint heightout,
126 GLshort *dataout, GLint element_size,
127 GLint ysize, GLint group_size,
129 static void scale_internal_uint(GLint components, GLint widthin,
130 GLint heightin, const GLuint *datain,
131 GLint widthout, GLint heightout,
132 GLuint *dataout, GLint element_size,
133 GLint ysize, GLint group_size,
135 static void scale_internal_int(GLint components, GLint widthin,
136 GLint heightin, const GLint *datain,
137 GLint widthout, GLint heightout,
138 GLint *dataout, GLint element_size,
139 GLint ysize, GLint group_size,
141 static void scale_internal_float(GLint components, GLint widthin,
142 GLint heightin, const GLfloat *datain,
143 GLint widthout, GLint heightout,
144 GLfloat *dataout, GLint element_size,
145 GLint ysize, GLint group_size,
148 static int checkMipmapArgs(GLenum, GLenum, GLenum);
149 static GLboolean legalFormat(GLenum);
150 static GLboolean legalType(GLenum);
151 static GLboolean isTypePackedPixel(GLenum);
152 static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
153 static GLboolean isLegalLevels(GLint, GLint, GLint, GLint);
154 static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
157 /* all extract/shove routines must return double to handle unsigned ints */
158 static GLdouble extractUbyte(int, const void *);
159 static void shoveUbyte(GLdouble, int, void *);
160 static GLdouble extractSbyte(int, const void *);
161 static void shoveSbyte(GLdouble, int, void *);
162 static GLdouble extractUshort(int, const void *);
163 static void shoveUshort(GLdouble, int, void *);
164 static GLdouble extractSshort(int, const void *);
165 static void shoveSshort(GLdouble, int, void *);
166 static GLdouble extractUint(int, const void *);
167 static void shoveUint(GLdouble, int, void *);
168 static GLdouble extractSint(int, const void *);
169 static void shoveSint(GLdouble, int, void *);
170 static GLdouble extractFloat(int, const void *);
171 static void shoveFloat(GLdouble, int, void *);
172 static void halveImageSlice(int, GLdouble (*)(int, const void *),
173 void (*)(GLdouble, int, void *),
175 const void *, void *,
176 GLint, GLint, GLint, GLint, GLint);
177 static void halveImage3D(int, GLdouble (*)(int, const void *),
178 void (*)(GLdouble, int, void *),
180 const void *, void *,
181 GLint, GLint, GLint, GLint, GLint);
183 /* packedpixel type scale routines */
184 static void extract332(int,const void *, GLfloat []);
185 static void shove332(const GLfloat [],int ,void *);
186 static void extract233rev(int,const void *, GLfloat []);
187 static void shove233rev(const GLfloat [],int ,void *);
188 static void extract565(int,const void *, GLfloat []);
189 static void shove565(const GLfloat [],int ,void *);
190 static void extract565rev(int,const void *, GLfloat []);
191 static void shove565rev(const GLfloat [],int ,void *);
192 static void extract4444(int,const void *, GLfloat []);
193 static void shove4444(const GLfloat [],int ,void *);
194 static void extract4444rev(int,const void *, GLfloat []);
195 static void shove4444rev(const GLfloat [],int ,void *);
196 static void extract5551(int,const void *, GLfloat []);
197 static void shove5551(const GLfloat [],int ,void *);
198 static void extract1555rev(int,const void *, GLfloat []);
199 static void shove1555rev(const GLfloat [],int ,void *);
200 static void extract8888(int,const void *, GLfloat []);
201 static void shove8888(const GLfloat [],int ,void *);
202 static void extract8888rev(int,const void *, GLfloat []);
203 static void shove8888rev(const GLfloat [],int ,void *);
204 static void extract1010102(int,const void *, GLfloat []);
205 static void shove1010102(const GLfloat [],int ,void *);
206 static void extract2101010rev(int,const void *, GLfloat []);
207 static void shove2101010rev(const GLfloat [],int ,void *);
208 static void scaleInternalPackedPixel(int,
209 void (*)(int, const void *,GLfloat []),
210 void (*)(const GLfloat [],int, void *),
211 GLint,GLint, const void *,
212 GLint,GLint,void *,GLint,GLint,GLint);
213 static void halveImagePackedPixel(int,
214 void (*)(int, const void *,GLfloat []),
215 void (*)(const GLfloat [],int, void *),
216 GLint, GLint, const void *,
217 void *, GLint, GLint, GLint);
218 static void halve1DimagePackedPixel(int,
219 void (*)(int, const void *,GLfloat []),
220 void (*)(const GLfloat [],int, void *),
221 GLint, GLint, const void *,
222 void *, GLint, GLint, GLint);
224 static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
225 GLubyte *, GLint, GLint, GLint);
226 static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
227 GLint, GLint, GLint);
228 static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
229 GLushort *, GLint, GLint, GLint, GLint);
230 static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
231 GLint, GLint, GLint, GLint);
232 static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
233 GLint, GLint, GLint, GLint);
234 static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
235 GLint, GLint, GLint, GLint);
236 static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
237 GLint, GLint, GLint, GLint);
239 static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum);
240 static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
241 GLenum, GLboolean, const void *, GLushort *);
242 static void emptyImage3D(const PixelStorageModes *,
243 GLint, GLint, GLint, GLenum,
245 const GLushort *, void *);
246 static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
247 GLint, GLint, GLint, GLushort *);
249 static void retrieveStoreModes(PixelStorageModes *psm)
251 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
252 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
253 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
254 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
255 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
256 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
258 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
259 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
260 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
261 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
262 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
263 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
266 static void retrieveStoreModes3D(PixelStorageModes *psm)
268 glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
269 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
270 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
271 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
272 glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
273 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
274 glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images);
275 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height);
277 glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
278 glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
279 glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
280 glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
281 glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
282 glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
283 glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
284 glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
287 static int computeLog(GLuint value)
294 if (value == 0) return -1;
299 if (value != 1) return -1;
308 ** Compute the nearest power of 2 number. This algorithm is a little
309 ** strange, but it works quite well.
311 static int nearestPower(GLuint value)
318 if (value == 0) return -1;
323 } else if (value == 3) {
331 #define __GLU_SWAP_2_BYTES(s)\
332 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
334 #define __GLU_SWAP_4_BYTES(s)\
335 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
336 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
337 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
339 static void halveImage(GLint components, GLuint width, GLuint height,
340 const GLushort *datain, GLushort *dataout)
343 int newwidth, newheight;
348 newwidth = width / 2;
349 newheight = height / 2;
350 delta = width * components;
355 for (i = 0; i < newheight; i++) {
356 for (j = 0; j < newwidth; j++) {
357 for (k = 0; k < components; k++) {
358 s[0] = (t[0] + t[components] + t[delta] +
359 t[delta+components] + 2) / 4;
368 static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
369 const GLubyte *datain, GLubyte *dataout,
370 GLint element_size, GLint ysize, GLint group_size)
373 int newwidth, newheight;
378 /* handle case where there is only 1 column/row */
379 if (width == 1 || height == 1) {
380 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
381 halve1Dimage_ubyte(components,width,height,datain,dataout,
382 element_size,ysize,group_size);
386 newwidth = width / 2;
387 newheight = height / 2;
388 padBytes = ysize - (width*group_size);
390 t = (const char *)datain;
393 for (i = 0; i < newheight; i++) {
394 for (j = 0; j < newwidth; j++) {
395 for (k = 0; k < components; k++) {
396 s[0] = (*(const GLubyte*)t +
397 *(const GLubyte*)(t+group_size) +
398 *(const GLubyte*)(t+ysize) +
399 *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
400 s++; t += element_size;
410 static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
411 const GLubyte *dataIn, GLubyte *dataOut,
412 GLint element_size, GLint ysize,
415 GLint halfWidth= width / 2;
416 GLint halfHeight= height / 2;
417 const char *src= (const char *) dataIn;
418 GLubyte *dest= dataOut;
421 assert(width == 1 || height == 1); /* must be 1D */
422 assert(width != height); /* can't be square */
424 if (height == 1) { /* 1 row */
425 assert(width != 1); /* widthxheight can't be 1x1 */
428 for (jj= 0; jj< halfWidth; jj++) {
430 for (kk= 0; kk< components; kk++) {
431 *dest= (*(const GLubyte*)src +
432 *(const GLubyte*)(src+group_size)) / 2;
437 src+= group_size; /* skip to next 2 */
440 int padBytes= ysize - (width*group_size);
441 src+= padBytes; /* for assertion only */
444 else if (width == 1) { /* 1 column */
445 int padBytes= ysize - (width * group_size);
446 assert(height != 1); /* widthxheight can't be 1x1 */
448 /* one vertical column with possible pad bytes per row */
449 /* average two at a time */
451 for (jj= 0; jj< halfHeight; jj++) {
453 for (kk= 0; kk< components; kk++) {
454 *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
459 src+= padBytes; /* add pad bytes, if any, to get to end to row */
464 assert(src == &((const char *)dataIn)[ysize*height]);
465 assert((char *)dest == &((char *)dataOut)
466 [components * element_size * halfWidth * halfHeight]);
467 } /* halve1Dimage_ubyte() */
469 static void halveImage_byte(GLint components, GLuint width, GLuint height,
470 const GLbyte *datain, GLbyte *dataout,
472 GLint ysize, GLint group_size)
475 int newwidth, newheight;
480 /* handle case where there is only 1 column/row */
481 if (width == 1 || height == 1) {
482 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
483 halve1Dimage_byte(components,width,height,datain,dataout,
484 element_size,ysize,group_size);
488 newwidth = width / 2;
489 newheight = height / 2;
490 padBytes = ysize - (width*group_size);
492 t = (const char *)datain;
495 for (i = 0; i < newheight; i++) {
496 for (j = 0; j < newwidth; j++) {
497 for (k = 0; k < components; k++) {
498 s[0] = (*(const GLbyte*)t +
499 *(const GLbyte*)(t+group_size) +
500 *(const GLbyte*)(t+ysize) +
501 *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
502 s++; t += element_size;
511 static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
512 const GLbyte *dataIn, GLbyte *dataOut,
513 GLint element_size,GLint ysize, GLint group_size)
515 GLint halfWidth= width / 2;
516 GLint halfHeight= height / 2;
517 const char *src= (const char *) dataIn;
518 GLbyte *dest= dataOut;
521 assert(width == 1 || height == 1); /* must be 1D */
522 assert(width != height); /* can't be square */
524 if (height == 1) { /* 1 row */
525 assert(width != 1); /* widthxheight can't be 1x1 */
528 for (jj= 0; jj< halfWidth; jj++) {
530 for (kk= 0; kk< components; kk++) {
531 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
536 src+= group_size; /* skip to next 2 */
539 int padBytes= ysize - (width*group_size);
540 src+= padBytes; /* for assertion only */
543 else if (width == 1) { /* 1 column */
544 int padBytes= ysize - (width * group_size);
545 assert(height != 1); /* widthxheight can't be 1x1 */
547 /* one vertical column with possible pad bytes per row */
548 /* average two at a time */
550 for (jj= 0; jj< halfHeight; jj++) {
552 for (kk= 0; kk< components; kk++) {
553 *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
558 src+= padBytes; /* add pad bytes, if any, to get to end to row */
562 assert(src == &((const char *)dataIn)[ysize*height]);
565 assert((char *)dest == &((char *)dataOut)
566 [components * element_size * halfWidth * halfHeight]);
567 } /* halve1Dimage_byte() */
569 static void halveImage_ushort(GLint components, GLuint width, GLuint height,
570 const GLushort *datain, GLushort *dataout,
571 GLint element_size, GLint ysize, GLint group_size,
575 int newwidth, newheight;
580 /* handle case where there is only 1 column/row */
581 if (width == 1 || height == 1) {
582 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
583 halve1Dimage_ushort(components,width,height,datain,dataout,
584 element_size,ysize,group_size, myswap_bytes);
588 newwidth = width / 2;
589 newheight = height / 2;
590 padBytes = ysize - (width*group_size);
592 t = (const char *)datain;
596 for (i = 0; i < newheight; i++) {
597 for (j = 0; j < newwidth; j++) {
598 for (k = 0; k < components; k++) {
599 s[0] = (*(const GLushort*)t +
600 *(const GLushort*)(t+group_size) +
601 *(const GLushort*)(t+ysize) +
602 *(const GLushort*)(t+ysize+group_size) + 2) / 4;
603 s++; t += element_size;
611 for (i = 0; i < newheight; i++) {
612 for (j = 0; j < newwidth; j++) {
613 for (k = 0; k < components; k++) {
614 s[0] = (__GLU_SWAP_2_BYTES(t) +
615 __GLU_SWAP_2_BYTES(t+group_size) +
616 __GLU_SWAP_2_BYTES(t+ysize) +
617 __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
618 s++; t += element_size;
627 static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
628 const GLushort *dataIn, GLushort *dataOut,
629 GLint element_size, GLint ysize,
630 GLint group_size, GLint myswap_bytes)
632 GLint halfWidth= width / 2;
633 GLint halfHeight= height / 2;
634 const char *src= (const char *) dataIn;
635 GLushort *dest= dataOut;
638 assert(width == 1 || height == 1); /* must be 1D */
639 assert(width != height); /* can't be square */
641 if (height == 1) { /* 1 row */
642 assert(width != 1); /* widthxheight can't be 1x1 */
645 for (jj= 0; jj< halfWidth; jj++) {
647 for (kk= 0; kk< components; kk++) {
649 GLushort ushort[BOX2];
651 ushort[0]= __GLU_SWAP_2_BYTES(src);
652 ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
655 ushort[0]= *(const GLushort*)src;
656 ushort[1]= *(const GLushort*)(src+group_size);
659 *dest= (ushort[0] + ushort[1]) / 2;
663 src+= group_size; /* skip to next 2 */
666 int padBytes= ysize - (width*group_size);
667 src+= padBytes; /* for assertion only */
670 else if (width == 1) { /* 1 column */
671 int padBytes= ysize - (width * group_size);
672 assert(height != 1); /* widthxheight can't be 1x1 */
674 /* one vertical column with possible pad bytes per row */
675 /* average two at a time */
677 for (jj= 0; jj< halfHeight; jj++) {
679 for (kk= 0; kk< components; kk++) {
681 GLushort ushort[BOX2];
683 ushort[0]= __GLU_SWAP_2_BYTES(src);
684 ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
687 ushort[0]= *(const GLushort*)src;
688 ushort[1]= *(const GLushort*)(src+ysize);
690 *dest= (ushort[0] + ushort[1]) / 2;
695 src+= padBytes; /* add pad bytes, if any, to get to end to row */
699 assert(src == &((const char *)dataIn)[ysize*height]);
702 assert((char *)dest == &((char *)dataOut)
703 [components * element_size * halfWidth * halfHeight]);
705 } /* halve1Dimage_ushort() */
708 static void halveImage_short(GLint components, GLuint width, GLuint height,
709 const GLshort *datain, GLshort *dataout,
710 GLint element_size, GLint ysize, GLint group_size,
714 int newwidth, newheight;
719 /* handle case where there is only 1 column/row */
720 if (width == 1 || height == 1) {
721 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
722 halve1Dimage_short(components,width,height,datain,dataout,
723 element_size,ysize,group_size, myswap_bytes);
727 newwidth = width / 2;
728 newheight = height / 2;
729 padBytes = ysize - (width*group_size);
731 t = (const char *)datain;
735 for (i = 0; i < newheight; i++) {
736 for (j = 0; j < newwidth; j++) {
737 for (k = 0; k < components; k++) {
738 s[0] = (*(const GLshort*)t +
739 *(const GLshort*)(t+group_size) +
740 *(const GLshort*)(t+ysize) +
741 *(const GLshort*)(t+ysize+group_size) + 2) / 4;
742 s++; t += element_size;
750 for (i = 0; i < newheight; i++) {
751 for (j = 0; j < newwidth; j++) {
752 for (k = 0; k < components; k++) {
755 b = __GLU_SWAP_2_BYTES(t);
756 buf = *(const GLshort*)&b;
757 b = __GLU_SWAP_2_BYTES(t+group_size);
758 buf += *(const GLshort*)&b;
759 b = __GLU_SWAP_2_BYTES(t+ysize);
760 buf += *(const GLshort*)&b;
761 b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
762 buf += *(const GLshort*)&b;
763 s[0] = (GLshort)((buf+2)/4);
764 s++; t += element_size;
773 static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
774 const GLshort *dataIn, GLshort *dataOut,
775 GLint element_size, GLint ysize,
776 GLint group_size, GLint myswap_bytes)
778 GLint halfWidth= width / 2;
779 GLint halfHeight= height / 2;
780 const char *src= (const char *) dataIn;
781 GLshort *dest= dataOut;
784 assert(width == 1 || height == 1); /* must be 1D */
785 assert(width != height); /* can't be square */
787 if (height == 1) { /* 1 row */
788 assert(width != 1); /* widthxheight can't be 1x1 */
791 for (jj= 0; jj< halfWidth; jj++) {
793 for (kk= 0; kk< components; kk++) {
795 GLshort sshort[BOX2];
797 sshort[0]= __GLU_SWAP_2_BYTES(src);
798 sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
801 sshort[0]= *(const GLshort*)src;
802 sshort[1]= *(const GLshort*)(src+group_size);
805 *dest= (sshort[0] + sshort[1]) / 2;
809 src+= group_size; /* skip to next 2 */
812 int padBytes= ysize - (width*group_size);
813 src+= padBytes; /* for assertion only */
816 else if (width == 1) { /* 1 column */
817 int padBytes= ysize - (width * group_size);
818 assert(height != 1); /* widthxheight can't be 1x1 */
820 /* one vertical column with possible pad bytes per row */
821 /* average two at a time */
823 for (jj= 0; jj< halfHeight; jj++) {
825 for (kk= 0; kk< components; kk++) {
827 GLshort sshort[BOX2];
829 sshort[0]= __GLU_SWAP_2_BYTES(src);
830 sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
833 sshort[0]= *(const GLshort*)src;
834 sshort[1]= *(const GLshort*)(src+ysize);
836 *dest= (sshort[0] + sshort[1]) / 2;
841 src+= padBytes; /* add pad bytes, if any, to get to end to row */
845 assert(src == &((const char *)dataIn)[ysize*height]);
848 assert((char *)dest == &((char *)dataOut)
849 [components * element_size * halfWidth * halfHeight]);
851 } /* halve1Dimage_short() */
854 static void halveImage_uint(GLint components, GLuint width, GLuint height,
855 const GLuint *datain, GLuint *dataout,
856 GLint element_size, GLint ysize, GLint group_size,
860 int newwidth, newheight;
865 /* handle case where there is only 1 column/row */
866 if (width == 1 || height == 1) {
867 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
868 halve1Dimage_uint(components,width,height,datain,dataout,
869 element_size,ysize,group_size, myswap_bytes);
873 newwidth = width / 2;
874 newheight = height / 2;
875 padBytes = ysize - (width*group_size);
877 t = (const char *)datain;
881 for (i = 0; i < newheight; i++) {
882 for (j = 0; j < newwidth; j++) {
883 for (k = 0; k < components; k++) {
884 /* need to cast to double to hold large unsigned ints */
885 s[0] = ((double)*(const GLuint*)t +
886 (double)*(const GLuint*)(t+group_size) +
887 (double)*(const GLuint*)(t+ysize) +
888 (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
889 s++; t += element_size;
898 for (i = 0; i < newheight; i++) {
899 for (j = 0; j < newwidth; j++) {
900 for (k = 0; k < components; k++) {
901 /* need to cast to double to hold large unsigned ints */
903 buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
904 (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
905 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
906 (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
907 s[0] = (GLuint)(buf/4 + 0.5);
909 s++; t += element_size;
919 static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
920 const GLuint *dataIn, GLuint *dataOut,
921 GLint element_size, GLint ysize,
922 GLint group_size, GLint myswap_bytes)
924 GLint halfWidth= width / 2;
925 GLint halfHeight= height / 2;
926 const char *src= (const char *) dataIn;
927 GLuint *dest= dataOut;
930 assert(width == 1 || height == 1); /* must be 1D */
931 assert(width != height); /* can't be square */
933 if (height == 1) { /* 1 row */
934 assert(width != 1); /* widthxheight can't be 1x1 */
937 for (jj= 0; jj< halfWidth; jj++) {
939 for (kk= 0; kk< components; kk++) {
943 uint[0]= __GLU_SWAP_4_BYTES(src);
944 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
947 uint[0]= *(const GLuint*)src;
948 uint[1]= *(const GLuint*)(src+group_size);
950 *dest= ((double)uint[0]+(double)uint[1])/2.0;
955 src+= group_size; /* skip to next 2 */
958 int padBytes= ysize - (width*group_size);
959 src+= padBytes; /* for assertion only */
962 else if (width == 1) { /* 1 column */
963 int padBytes= ysize - (width * group_size);
964 assert(height != 1); /* widthxheight can't be 1x1 */
966 /* one vertical column with possible pad bytes per row */
967 /* average two at a time */
969 for (jj= 0; jj< halfHeight; jj++) {
971 for (kk= 0; kk< components; kk++) {
975 uint[0]= __GLU_SWAP_4_BYTES(src);
976 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
979 uint[0]= *(const GLuint*)src;
980 uint[1]= *(const GLuint*)(src+ysize);
982 *dest= ((double)uint[0]+(double)uint[1])/2.0;
987 src+= padBytes; /* add pad bytes, if any, to get to end to row */
991 assert(src == &((const char *)dataIn)[ysize*height]);
994 assert((char *)dest == &((char *)dataOut)
995 [components * element_size * halfWidth * halfHeight]);
997 } /* halve1Dimage_uint() */
999 static void halveImage_int(GLint components, GLuint width, GLuint height,
1000 const GLint *datain, GLint *dataout, GLint element_size,
1001 GLint ysize, GLint group_size, GLint myswap_bytes)
1004 int newwidth, newheight;
1009 /* handle case where there is only 1 column/row */
1010 if (width == 1 || height == 1) {
1011 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1012 halve1Dimage_int(components,width,height,datain,dataout,
1013 element_size,ysize,group_size, myswap_bytes);
1017 newwidth = width / 2;
1018 newheight = height / 2;
1019 padBytes = ysize - (width*group_size);
1021 t = (const char *)datain;
1023 /* Piece o' cake! */
1025 for (i = 0; i < newheight; i++) {
1026 for (j = 0; j < newwidth; j++) {
1027 for (k = 0; k < components; k++) {
1028 s[0] = ((float)*(const GLint*)t +
1029 (float)*(const GLint*)(t+group_size) +
1030 (float)*(const GLint*)(t+ysize) +
1031 (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
1032 s++; t += element_size;
1040 for (i = 0; i < newheight; i++) {
1041 for (j = 0; j < newwidth; j++) {
1042 for (k = 0; k < components; k++) {
1045 b = __GLU_SWAP_4_BYTES(t);
1047 b = __GLU_SWAP_4_BYTES(t+group_size);
1049 b = __GLU_SWAP_4_BYTES(t+ysize);
1051 b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1053 s[0] = (GLint)(buf/4 + 0.5);
1055 s++; t += element_size;
1065 static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
1066 const GLint *dataIn, GLint *dataOut,
1067 GLint element_size, GLint ysize,
1068 GLint group_size, GLint myswap_bytes)
1070 GLint halfWidth= width / 2;
1071 GLint halfHeight= height / 2;
1072 const char *src= (const char *) dataIn;
1073 GLint *dest= dataOut;
1076 assert(width == 1 || height == 1); /* must be 1D */
1077 assert(width != height); /* can't be square */
1079 if (height == 1) { /* 1 row */
1080 assert(width != 1); /* widthxheight can't be 1x1 */
1083 for (jj= 0; jj< halfWidth; jj++) {
1085 for (kk= 0; kk< components; kk++) {
1089 uint[0]= __GLU_SWAP_4_BYTES(src);
1090 uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
1093 uint[0]= *(const GLuint*)src;
1094 uint[1]= *(const GLuint*)(src+group_size);
1096 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1101 src+= group_size; /* skip to next 2 */
1104 int padBytes= ysize - (width*group_size);
1105 src+= padBytes; /* for assertion only */
1108 else if (width == 1) { /* 1 column */
1109 int padBytes= ysize - (width * group_size);
1110 assert(height != 1); /* widthxheight can't be 1x1 */
1112 /* one vertical column with possible pad bytes per row */
1113 /* average two at a time */
1115 for (jj= 0; jj< halfHeight; jj++) {
1117 for (kk= 0; kk< components; kk++) {
1121 uint[0]= __GLU_SWAP_4_BYTES(src);
1122 uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
1125 uint[0]= *(const GLuint*)src;
1126 uint[1]= *(const GLuint*)(src+ysize);
1128 *dest= ((float)uint[0]+(float)uint[1])/2.0;
1133 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1137 assert(src == &((const char *)dataIn)[ysize*height]);
1140 assert((char *)dest == &((char *)dataOut)
1141 [components * element_size * halfWidth * halfHeight]);
1143 } /* halve1Dimage_int() */
1146 static void halveImage_float(GLint components, GLuint width, GLuint height,
1147 const GLfloat *datain, GLfloat *dataout,
1148 GLint element_size, GLint ysize, GLint group_size,
1152 int newwidth, newheight;
1157 /* handle case where there is only 1 column/row */
1158 if (width == 1 || height == 1) {
1159 assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
1160 halve1Dimage_float(components,width,height,datain,dataout,
1161 element_size,ysize,group_size, myswap_bytes);
1165 newwidth = width / 2;
1166 newheight = height / 2;
1167 padBytes = ysize - (width*group_size);
1169 t = (const char *)datain;
1171 /* Piece o' cake! */
1173 for (i = 0; i < newheight; i++) {
1174 for (j = 0; j < newwidth; j++) {
1175 for (k = 0; k < components; k++) {
1176 s[0] = (*(const GLfloat*)t +
1177 *(const GLfloat*)(t+group_size) +
1178 *(const GLfloat*)(t+ysize) +
1179 *(const GLfloat*)(t+ysize+group_size)) / 4;
1180 s++; t += element_size;
1188 for (i = 0; i < newheight; i++) {
1189 for (j = 0; j < newwidth; j++) {
1190 for (k = 0; k < components; k++) {
1191 union { GLuint b; GLfloat f; } swapbuf;
1192 swapbuf.b = __GLU_SWAP_4_BYTES(t);
1194 swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
1196 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
1198 swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
1201 s++; t += element_size;
1211 static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
1212 const GLfloat *dataIn, GLfloat *dataOut,
1213 GLint element_size, GLint ysize,
1214 GLint group_size, GLint myswap_bytes)
1216 GLint halfWidth= width / 2;
1217 GLint halfHeight= height / 2;
1218 const char *src= (const char *) dataIn;
1219 GLfloat *dest= dataOut;
1222 assert(width == 1 || height == 1); /* must be 1D */
1223 assert(width != height); /* can't be square */
1225 if (height == 1) { /* 1 row */
1226 assert(width != 1); /* widthxheight can't be 1x1 */
1229 for (jj= 0; jj< halfWidth; jj++) {
1231 for (kk= 0; kk< components; kk++) {
1233 GLfloat sfloat[BOX2];
1235 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1236 sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
1239 sfloat[0]= *(const GLfloat*)src;
1240 sfloat[1]= *(const GLfloat*)(src+group_size);
1243 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1247 src+= group_size; /* skip to next 2 */
1250 int padBytes= ysize - (width*group_size);
1251 src+= padBytes; /* for assertion only */
1254 else if (width == 1) { /* 1 column */
1255 int padBytes= ysize - (width * group_size);
1256 assert(height != 1); /* widthxheight can't be 1x1 */
1258 /* one vertical column with possible pad bytes per row */
1259 /* average two at a time */
1261 for (jj= 0; jj< halfHeight; jj++) {
1263 for (kk= 0; kk< components; kk++) {
1265 GLfloat sfloat[BOX2];
1267 sfloat[0]= __GLU_SWAP_4_BYTES(src);
1268 sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
1271 sfloat[0]= *(const GLfloat*)src;
1272 sfloat[1]= *(const GLfloat*)(src+ysize);
1274 *dest= (sfloat[0] + sfloat[1]) / 2.0;
1279 src+= padBytes; /* add pad bytes, if any, to get to end to row */
1280 src+= ysize; /* skip to odd row */
1284 assert(src == &((const char *)dataIn)[ysize*height]);
1285 assert((char *)dest == &((char *)dataOut)
1286 [components * element_size * halfWidth * halfHeight]);
1287 } /* halve1Dimage_float() */
1289 static void scale_internal(GLint components, GLint widthin, GLint heightin,
1290 const GLushort *datain,
1291 GLint widthout, GLint heightout,
1294 float x, lowx, highx, convx, halfconvx;
1295 float y, lowy, highy, convy, halfconvy;
1296 float xpercent,ypercent;
1298 /* Max components in a format is 4, so... */
1301 int i,j,k,yint,xint,xindex,yindex;
1304 if (widthin == widthout*2 && heightin == heightout*2) {
1305 halveImage(components, widthin, heightin, datain, dataout);
1308 convy = (float) heightin/heightout;
1309 convx = (float) widthin/widthout;
1310 halfconvx = convx/2;
1311 halfconvy = convy/2;
1312 for (i = 0; i < heightout; i++) {
1313 y = convy * (i+0.5);
1314 if (heightin > heightout) {
1315 highy = y + halfconvy;
1316 lowy = y - halfconvy;
1321 for (j = 0; j < widthout; j++) {
1322 x = convx * (j+0.5);
1323 if (widthin > widthout) {
1324 highx = x + halfconvx;
1325 lowx = x - halfconvx;
1332 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1333 ** to (highx, highy) on input data into this pixel on output
1336 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1342 yindex = (yint + heightin) % heightin;
1343 if (highy < yint+1) {
1344 ypercent = highy - y;
1346 ypercent = yint+1 - y;
1353 xindex = (xint + widthin) % widthin;
1354 if (highx < xint+1) {
1355 xpercent = highx - x;
1357 xpercent = xint+1 - x;
1360 percent = xpercent * ypercent;
1362 temp = (xindex + (yindex * widthin)) * components;
1363 for (k = 0; k < components; k++) {
1364 totals[k] += datain[temp + k] * percent;
1374 temp = (j + (i * widthout)) * components;
1375 for (k = 0; k < components; k++) {
1376 /* totals[] should be rounded in the case of enlarging an RGB
1377 * ramp when the type is 332 or 4444
1379 dataout[temp + k] = (totals[k]+0.5)/area;
1385 static void scale_internal_ubyte(GLint components, GLint widthin,
1386 GLint heightin, const GLubyte *datain,
1387 GLint widthout, GLint heightout,
1388 GLubyte *dataout, GLint element_size,
1389 GLint ysize, GLint group_size)
1394 /* Max components in a format is 4, so... */
1399 const char *temp, *temp0;
1400 const char *temp_index;
1403 int lowx_int, highx_int, lowy_int, highy_int;
1404 float x_percent, y_percent;
1405 float lowx_float, highx_float, lowy_float, highy_float;
1406 float convy_float, convx_float;
1407 int convy_int, convx_int;
1409 const char *left, *right;
1411 if (widthin == widthout*2 && heightin == heightout*2) {
1412 halveImage_ubyte(components, widthin, heightin,
1413 (const GLubyte *)datain, (GLubyte *)dataout,
1414 element_size, ysize, group_size);
1417 convy = (float) heightin/heightout;
1418 convx = (float) widthin/widthout;
1419 convy_int = floor(convy);
1420 convy_float = convy - convy_int;
1421 convx_int = floor(convx);
1422 convx_float = convx - convx_int;
1424 area = convx * convy;
1428 highy_int = convy_int;
1429 highy_float = convy_float;
1431 for (i = 0; i < heightout; i++) {
1432 /* Clamp here to be sure we don't read beyond input buffer. */
1433 if (highy_int >= heightin)
1434 highy_int = heightin - 1;
1437 highx_int = convx_int;
1438 highx_float = convx_float;
1440 for (j = 0; j < widthout; j++) {
1443 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1444 ** to (highx, highy) on input data into this pixel on output
1447 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1449 /* calculate the value for pixels in the 1st row */
1450 xindex = lowx_int*group_size;
1451 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1453 y_percent = 1-lowy_float;
1454 temp = (const char *)datain + xindex + lowy_int * ysize;
1455 percent = y_percent * (1-lowx_float);
1456 for (k = 0, temp_index = temp; k < components;
1457 k++, temp_index += element_size) {
1458 totals[k] += (GLubyte)(*(temp_index)) * percent;
1461 for(l = lowx_int+1; l < highx_int; l++) {
1463 for (k = 0, temp_index = temp; k < components;
1464 k++, temp_index += element_size) {
1465 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1470 percent = y_percent * highx_float;
1471 for (k = 0, temp_index = temp; k < components;
1472 k++, temp_index += element_size) {
1473 totals[k] += (GLubyte)(*(temp_index)) * percent;
1476 /* calculate the value for pixels in the last row */
1477 y_percent = highy_float;
1478 percent = y_percent * (1-lowx_float);
1479 temp = (const char *)datain + xindex + highy_int * ysize;
1480 for (k = 0, temp_index = temp; k < components;
1481 k++, temp_index += element_size) {
1482 totals[k] += (GLubyte)(*(temp_index)) * percent;
1484 for(l = lowx_int+1; l < highx_int; l++) {
1486 for (k = 0, temp_index = temp; k < components;
1487 k++, temp_index += element_size) {
1488 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1492 percent = y_percent * highx_float;
1493 for (k = 0, temp_index = temp; k < components;
1494 k++, temp_index += element_size) {
1495 totals[k] += (GLubyte)(*(temp_index)) * percent;
1499 /* calculate the value for pixels in the 1st and last column */
1500 for(m = lowy_int+1; m < highy_int; m++) {
1503 for (k = 0; k < components;
1504 k++, left += element_size, right += element_size) {
1505 totals[k] += (GLubyte)(*(left))*(1-lowx_float)
1506 +(GLubyte)(*(right))*highx_float;
1509 } else if (highy_int > lowy_int) {
1510 x_percent = highx_float - lowx_float;
1511 percent = (1-lowy_float)*x_percent;
1512 temp = (const char *)datain + xindex + lowy_int*ysize;
1513 for (k = 0, temp_index = temp; k < components;
1514 k++, temp_index += element_size) {
1515 totals[k] += (GLubyte)(*(temp_index)) * percent;
1517 for(m = lowy_int+1; m < highy_int; m++) {
1519 for (k = 0, temp_index = temp; k < components;
1520 k++, temp_index += element_size) {
1521 totals[k] += (GLubyte)(*(temp_index)) * x_percent;
1524 percent = x_percent * highy_float;
1526 for (k = 0, temp_index = temp; k < components;
1527 k++, temp_index += element_size) {
1528 totals[k] += (GLubyte)(*(temp_index)) * percent;
1530 } else if (highx_int > lowx_int) {
1531 y_percent = highy_float - lowy_float;
1532 percent = (1-lowx_float)*y_percent;
1533 temp = (const char *)datain + xindex + lowy_int*ysize;
1534 for (k = 0, temp_index = temp; k < components;
1535 k++, temp_index += element_size) {
1536 totals[k] += (GLubyte)(*(temp_index)) * percent;
1538 for (l = lowx_int+1; l < highx_int; l++) {
1540 for (k = 0, temp_index = temp; k < components;
1541 k++, temp_index += element_size) {
1542 totals[k] += (GLubyte)(*(temp_index)) * y_percent;
1546 percent = y_percent * highx_float;
1547 for (k = 0, temp_index = temp; k < components;
1548 k++, temp_index += element_size) {
1549 totals[k] += (GLubyte)(*(temp_index)) * percent;
1552 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1553 temp = (const char *)datain + xindex + lowy_int * ysize;
1554 for (k = 0, temp_index = temp; k < components;
1555 k++, temp_index += element_size) {
1556 totals[k] += (GLubyte)(*(temp_index)) * percent;
1562 /* this is for the pixels in the body */
1563 temp0 = (const char *)datain + xindex + group_size +
1565 for (m = lowy_int+1; m < highy_int; m++) {
1567 for(l = lowx_int+1; l < highx_int; l++) {
1568 for (k = 0, temp_index = temp; k < components;
1569 k++, temp_index += element_size) {
1570 totals[k] += (GLubyte)(*(temp_index));
1577 outindex = (j + (i * widthout)) * components;
1578 for (k = 0; k < components; k++) {
1579 dataout[outindex + k] = totals[k]/area;
1580 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1582 lowx_int = highx_int;
1583 lowx_float = highx_float;
1584 highx_int += convx_int;
1585 highx_float += convx_float;
1586 if(highx_float > 1) {
1591 lowy_int = highy_int;
1592 lowy_float = highy_float;
1593 highy_int += convy_int;
1594 highy_float += convy_float;
1595 if(highy_float > 1) {
1602 static void scale_internal_byte(GLint components, GLint widthin,
1603 GLint heightin, const GLbyte *datain,
1604 GLint widthout, GLint heightout,
1605 GLbyte *dataout, GLint element_size,
1606 GLint ysize, GLint group_size)
1611 /* Max components in a format is 4, so... */
1616 const char *temp, *temp0;
1617 const char *temp_index;
1620 int lowx_int, highx_int, lowy_int, highy_int;
1621 float x_percent, y_percent;
1622 float lowx_float, highx_float, lowy_float, highy_float;
1623 float convy_float, convx_float;
1624 int convy_int, convx_int;
1626 const char *left, *right;
1628 if (widthin == widthout*2 && heightin == heightout*2) {
1629 halveImage_byte(components, widthin, heightin,
1630 (const GLbyte *)datain, (GLbyte *)dataout,
1631 element_size, ysize, group_size);
1634 convy = (float) heightin/heightout;
1635 convx = (float) widthin/widthout;
1636 convy_int = floor(convy);
1637 convy_float = convy - convy_int;
1638 convx_int = floor(convx);
1639 convx_float = convx - convx_int;
1641 area = convx * convy;
1645 highy_int = convy_int;
1646 highy_float = convy_float;
1648 for (i = 0; i < heightout; i++) {
1649 /* Clamp here to be sure we don't read beyond input buffer. */
1650 if (highy_int >= heightin)
1651 highy_int = heightin - 1;
1654 highx_int = convx_int;
1655 highx_float = convx_float;
1657 for (j = 0; j < widthout; j++) {
1660 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1661 ** to (highx, highy) on input data into this pixel on output
1664 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1666 /* calculate the value for pixels in the 1st row */
1667 xindex = lowx_int*group_size;
1668 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1670 y_percent = 1-lowy_float;
1671 temp = (const char *)datain + xindex + lowy_int * ysize;
1672 percent = y_percent * (1-lowx_float);
1673 for (k = 0, temp_index = temp; k < components;
1674 k++, temp_index += element_size) {
1675 totals[k] += (GLbyte)(*(temp_index)) * percent;
1678 for(l = lowx_int+1; l < highx_int; l++) {
1680 for (k = 0, temp_index = temp; k < components;
1681 k++, temp_index += element_size) {
1682 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1687 percent = y_percent * highx_float;
1688 for (k = 0, temp_index = temp; k < components;
1689 k++, temp_index += element_size) {
1690 totals[k] += (GLbyte)(*(temp_index)) * percent;
1693 /* calculate the value for pixels in the last row */
1694 y_percent = highy_float;
1695 percent = y_percent * (1-lowx_float);
1696 temp = (const char *)datain + xindex + highy_int * ysize;
1697 for (k = 0, temp_index = temp; k < components;
1698 k++, temp_index += element_size) {
1699 totals[k] += (GLbyte)(*(temp_index)) * percent;
1701 for(l = lowx_int+1; l < highx_int; l++) {
1703 for (k = 0, temp_index = temp; k < components;
1704 k++, temp_index += element_size) {
1705 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1709 percent = y_percent * highx_float;
1710 for (k = 0, temp_index = temp; k < components;
1711 k++, temp_index += element_size) {
1712 totals[k] += (GLbyte)(*(temp_index)) * percent;
1716 /* calculate the value for pixels in the 1st and last column */
1717 for(m = lowy_int+1; m < highy_int; m++) {
1720 for (k = 0; k < components;
1721 k++, left += element_size, right += element_size) {
1722 totals[k] += (GLbyte)(*(left))*(1-lowx_float)
1723 +(GLbyte)(*(right))*highx_float;
1726 } else if (highy_int > lowy_int) {
1727 x_percent = highx_float - lowx_float;
1728 percent = (1-lowy_float)*x_percent;
1729 temp = (const char *)datain + xindex + lowy_int*ysize;
1730 for (k = 0, temp_index = temp; k < components;
1731 k++, temp_index += element_size) {
1732 totals[k] += (GLbyte)(*(temp_index)) * percent;
1734 for(m = lowy_int+1; m < highy_int; m++) {
1736 for (k = 0, temp_index = temp; k < components;
1737 k++, temp_index += element_size) {
1738 totals[k] += (GLbyte)(*(temp_index)) * x_percent;
1741 percent = x_percent * highy_float;
1743 for (k = 0, temp_index = temp; k < components;
1744 k++, temp_index += element_size) {
1745 totals[k] += (GLbyte)(*(temp_index)) * percent;
1747 } else if (highx_int > lowx_int) {
1748 y_percent = highy_float - lowy_float;
1749 percent = (1-lowx_float)*y_percent;
1750 temp = (const char *)datain + xindex + lowy_int*ysize;
1751 for (k = 0, temp_index = temp; k < components;
1752 k++, temp_index += element_size) {
1753 totals[k] += (GLbyte)(*(temp_index)) * percent;
1755 for (l = lowx_int+1; l < highx_int; l++) {
1757 for (k = 0, temp_index = temp; k < components;
1758 k++, temp_index += element_size) {
1759 totals[k] += (GLbyte)(*(temp_index)) * y_percent;
1763 percent = y_percent * highx_float;
1764 for (k = 0, temp_index = temp; k < components;
1765 k++, temp_index += element_size) {
1766 totals[k] += (GLbyte)(*(temp_index)) * percent;
1769 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
1770 temp = (const char *)datain + xindex + lowy_int * ysize;
1771 for (k = 0, temp_index = temp; k < components;
1772 k++, temp_index += element_size) {
1773 totals[k] += (GLbyte)(*(temp_index)) * percent;
1779 /* this is for the pixels in the body */
1780 temp0 = (const char *)datain + xindex + group_size +
1782 for (m = lowy_int+1; m < highy_int; m++) {
1784 for(l = lowx_int+1; l < highx_int; l++) {
1785 for (k = 0, temp_index = temp; k < components;
1786 k++, temp_index += element_size) {
1787 totals[k] += (GLbyte)(*(temp_index));
1794 outindex = (j + (i * widthout)) * components;
1795 for (k = 0; k < components; k++) {
1796 dataout[outindex + k] = totals[k]/area;
1797 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1799 lowx_int = highx_int;
1800 lowx_float = highx_float;
1801 highx_int += convx_int;
1802 highx_float += convx_float;
1803 if(highx_float > 1) {
1808 lowy_int = highy_int;
1809 lowy_float = highy_float;
1810 highy_int += convy_int;
1811 highy_float += convy_float;
1812 if(highy_float > 1) {
1819 static void scale_internal_ushort(GLint components, GLint widthin,
1820 GLint heightin, const GLushort *datain,
1821 GLint widthout, GLint heightout,
1822 GLushort *dataout, GLint element_size,
1823 GLint ysize, GLint group_size,
1829 /* Max components in a format is 4, so... */
1834 const char *temp, *temp0;
1835 const char *temp_index;
1838 int lowx_int, highx_int, lowy_int, highy_int;
1839 float x_percent, y_percent;
1840 float lowx_float, highx_float, lowy_float, highy_float;
1841 float convy_float, convx_float;
1842 int convy_int, convx_int;
1844 const char *left, *right;
1846 if (widthin == widthout*2 && heightin == heightout*2) {
1847 halveImage_ushort(components, widthin, heightin,
1848 (const GLushort *)datain, (GLushort *)dataout,
1849 element_size, ysize, group_size, myswap_bytes);
1852 convy = (float) heightin/heightout;
1853 convx = (float) widthin/widthout;
1854 convy_int = floor(convy);
1855 convy_float = convy - convy_int;
1856 convx_int = floor(convx);
1857 convx_float = convx - convx_int;
1859 area = convx * convy;
1863 highy_int = convy_int;
1864 highy_float = convy_float;
1866 for (i = 0; i < heightout; i++) {
1867 /* Clamp here to be sure we don't read beyond input buffer. */
1868 if (highy_int >= heightin)
1869 highy_int = heightin - 1;
1872 highx_int = convx_int;
1873 highx_float = convx_float;
1875 for (j = 0; j < widthout; j++) {
1877 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1878 ** to (highx, highy) on input data into this pixel on output
1881 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
1883 /* calculate the value for pixels in the 1st row */
1884 xindex = lowx_int*group_size;
1885 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
1887 y_percent = 1-lowy_float;
1888 temp = (const char *)datain + xindex + lowy_int * ysize;
1889 percent = y_percent * (1-lowx_float);
1890 for (k = 0, temp_index = temp; k < components;
1891 k++, temp_index += element_size) {
1893 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1895 totals[k] += *(const GLushort*)temp_index * percent;
1899 for(l = lowx_int+1; l < highx_int; l++) {
1901 for (k = 0, temp_index = temp; k < components;
1902 k++, temp_index += element_size) {
1905 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1907 totals[k] += *(const GLushort*)temp_index * y_percent;
1913 percent = y_percent * highx_float;
1914 for (k = 0, temp_index = temp; k < components;
1915 k++, temp_index += element_size) {
1917 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1919 totals[k] += *(const GLushort*)temp_index * percent;
1923 /* calculate the value for pixels in the last row */
1924 y_percent = highy_float;
1925 percent = y_percent * (1-lowx_float);
1926 temp = (const char *)datain + xindex + highy_int * ysize;
1927 for (k = 0, temp_index = temp; k < components;
1928 k++, temp_index += element_size) {
1930 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1932 totals[k] += *(const GLushort*)temp_index * percent;
1935 for(l = lowx_int+1; l < highx_int; l++) {
1937 for (k = 0, temp_index = temp; k < components;
1938 k++, temp_index += element_size) {
1941 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
1943 totals[k] += *(const GLushort*)temp_index * y_percent;
1948 percent = y_percent * highx_float;
1949 for (k = 0, temp_index = temp; k < components;
1950 k++, temp_index += element_size) {
1952 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1954 totals[k] += *(const GLushort*)temp_index * percent;
1958 /* calculate the value for pixels in the 1st and last column */
1959 for(m = lowy_int+1; m < highy_int; m++) {
1962 for (k = 0; k < components;
1963 k++, left += element_size, right += element_size) {
1966 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
1967 __GLU_SWAP_2_BYTES(right) * highx_float;
1969 totals[k] += *(const GLushort*)left * (1-lowx_float)
1970 + *(const GLushort*)right * highx_float;
1974 } else if (highy_int > lowy_int) {
1975 x_percent = highx_float - lowx_float;
1976 percent = (1-lowy_float)*x_percent;
1977 temp = (const char *)datain + xindex + lowy_int*ysize;
1978 for (k = 0, temp_index = temp; k < components;
1979 k++, temp_index += element_size) {
1981 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
1983 totals[k] += *(const GLushort*)temp_index * percent;
1986 for(m = lowy_int+1; m < highy_int; m++) {
1988 for (k = 0, temp_index = temp; k < components;
1989 k++, temp_index += element_size) {
1992 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
1994 totals[k] += *(const GLushort*)temp_index * x_percent;
1998 percent = x_percent * highy_float;
2000 for (k = 0, temp_index = temp; k < components;
2001 k++, temp_index += element_size) {
2003 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2005 totals[k] += *(const GLushort*)temp_index * percent;
2008 } else if (highx_int > lowx_int) {
2009 y_percent = highy_float - lowy_float;
2010 percent = (1-lowx_float)*y_percent;
2011 temp = (const char *)datain + xindex + lowy_int*ysize;
2012 for (k = 0, temp_index = temp; k < components;
2013 k++, temp_index += element_size) {
2015 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2017 totals[k] += *(const GLushort*)temp_index * percent;
2020 for (l = lowx_int+1; l < highx_int; l++) {
2022 for (k = 0, temp_index = temp; k < components;
2023 k++, temp_index += element_size) {
2026 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
2028 totals[k] += *(const GLushort*)temp_index * y_percent;
2033 percent = y_percent * highx_float;
2034 for (k = 0, temp_index = temp; k < components;
2035 k++, temp_index += element_size) {
2037 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2039 totals[k] += *(const GLushort*)temp_index * percent;
2043 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2044 temp = (const char *)datain + xindex + lowy_int * ysize;
2045 for (k = 0, temp_index = temp; k < components;
2046 k++, temp_index += element_size) {
2048 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
2050 totals[k] += *(const GLushort*)temp_index * percent;
2055 /* this is for the pixels in the body */
2056 temp0 = (const char *)datain + xindex + group_size +
2058 for (m = lowy_int+1; m < highy_int; m++) {
2060 for(l = lowx_int+1; l < highx_int; l++) {
2061 for (k = 0, temp_index = temp; k < components;
2062 k++, temp_index += element_size) {
2064 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
2066 totals[k] += *(const GLushort*)temp_index;
2074 outindex = (j + (i * widthout)) * components;
2075 for (k = 0; k < components; k++) {
2076 dataout[outindex + k] = totals[k]/area;
2077 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2079 lowx_int = highx_int;
2080 lowx_float = highx_float;
2081 highx_int += convx_int;
2082 highx_float += convx_float;
2083 if(highx_float > 1) {
2088 lowy_int = highy_int;
2089 lowy_float = highy_float;
2090 highy_int += convy_int;
2091 highy_float += convy_float;
2092 if(highy_float > 1) {
2099 static void scale_internal_short(GLint components, GLint widthin,
2100 GLint heightin, const GLshort *datain,
2101 GLint widthout, GLint heightout,
2102 GLshort *dataout, GLint element_size,
2103 GLint ysize, GLint group_size,
2109 /* Max components in a format is 4, so... */
2114 const char *temp, *temp0;
2115 const char *temp_index;
2118 int lowx_int, highx_int, lowy_int, highy_int;
2119 float x_percent, y_percent;
2120 float lowx_float, highx_float, lowy_float, highy_float;
2121 float convy_float, convx_float;
2122 int convy_int, convx_int;
2124 const char *left, *right;
2126 GLushort swapbuf; /* unsigned buffer */
2128 if (widthin == widthout*2 && heightin == heightout*2) {
2129 halveImage_short(components, widthin, heightin,
2130 (const GLshort *)datain, (GLshort *)dataout,
2131 element_size, ysize, group_size, myswap_bytes);
2134 convy = (float) heightin/heightout;
2135 convx = (float) widthin/widthout;
2136 convy_int = floor(convy);
2137 convy_float = convy - convy_int;
2138 convx_int = floor(convx);
2139 convx_float = convx - convx_int;
2141 area = convx * convy;
2145 highy_int = convy_int;
2146 highy_float = convy_float;
2148 for (i = 0; i < heightout; i++) {
2149 /* Clamp here to be sure we don't read beyond input buffer. */
2150 if (highy_int >= heightin)
2151 highy_int = heightin - 1;
2154 highx_int = convx_int;
2155 highx_float = convx_float;
2157 for (j = 0; j < widthout; j++) {
2159 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2160 ** to (highx, highy) on input data into this pixel on output
2163 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2165 /* calculate the value for pixels in the 1st row */
2166 xindex = lowx_int*group_size;
2167 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2169 y_percent = 1-lowy_float;
2170 temp = (const char *)datain + xindex + lowy_int * ysize;
2171 percent = y_percent * (1-lowx_float);
2172 for (k = 0, temp_index = temp; k < components;
2173 k++, temp_index += element_size) {
2175 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2176 totals[k] += *(const GLshort*)&swapbuf * percent;
2178 totals[k] += *(const GLshort*)temp_index * percent;
2182 for(l = lowx_int+1; l < highx_int; l++) {
2184 for (k = 0, temp_index = temp; k < components;
2185 k++, temp_index += element_size) {
2187 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2188 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2190 totals[k] += *(const GLshort*)temp_index * y_percent;
2196 percent = y_percent * highx_float;
2197 for (k = 0, temp_index = temp; k < components;
2198 k++, temp_index += element_size) {
2200 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2201 totals[k] += *(const GLshort*)&swapbuf * percent;
2203 totals[k] += *(const GLshort*)temp_index * percent;
2207 /* calculate the value for pixels in the last row */
2208 y_percent = highy_float;
2209 percent = y_percent * (1-lowx_float);
2210 temp = (const char *)datain + xindex + highy_int * ysize;
2211 for (k = 0, temp_index = temp; k < components;
2212 k++, temp_index += element_size) {
2214 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2215 totals[k] += *(const GLshort*)&swapbuf * percent;
2217 totals[k] += *(const GLshort*)temp_index * percent;
2220 for(l = lowx_int+1; l < highx_int; l++) {
2222 for (k = 0, temp_index = temp; k < components;
2223 k++, temp_index += element_size) {
2225 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2226 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2228 totals[k] += *(const GLshort*)temp_index * y_percent;
2233 percent = y_percent * highx_float;
2234 for (k = 0, temp_index = temp; k < components;
2235 k++, temp_index += element_size) {
2237 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2238 totals[k] += *(const GLshort*)&swapbuf * percent;
2240 totals[k] += *(const GLshort*)temp_index * percent;
2244 /* calculate the value for pixels in the 1st and last column */
2245 for(m = lowy_int+1; m < highy_int; m++) {
2248 for (k = 0; k < components;
2249 k++, left += element_size, right += element_size) {
2251 swapbuf = __GLU_SWAP_2_BYTES(left);
2252 totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
2253 swapbuf = __GLU_SWAP_2_BYTES(right);
2254 totals[k] += *(const GLshort*)&swapbuf * highx_float;
2256 totals[k] += *(const GLshort*)left * (1-lowx_float)
2257 + *(const GLshort*)right * highx_float;
2261 } else if (highy_int > lowy_int) {
2262 x_percent = highx_float - lowx_float;
2263 percent = (1-lowy_float)*x_percent;
2264 temp = (const char *)datain + xindex + lowy_int*ysize;
2265 for (k = 0, temp_index = temp; k < components;
2266 k++, temp_index += element_size) {
2268 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2269 totals[k] += *(const GLshort*)&swapbuf * percent;
2271 totals[k] += *(const GLshort*)temp_index * percent;
2274 for(m = lowy_int+1; m < highy_int; m++) {
2276 for (k = 0, temp_index = temp; k < components;
2277 k++, temp_index += element_size) {
2279 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2280 totals[k] += *(const GLshort*)&swapbuf * x_percent;
2282 totals[k] += *(const GLshort*)temp_index * x_percent;
2286 percent = x_percent * highy_float;
2288 for (k = 0, temp_index = temp; k < components;
2289 k++, temp_index += element_size) {
2291 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2292 totals[k] += *(const GLshort*)&swapbuf * percent;
2294 totals[k] += *(const GLshort*)temp_index * percent;
2297 } else if (highx_int > lowx_int) {
2298 y_percent = highy_float - lowy_float;
2299 percent = (1-lowx_float)*y_percent;
2301 temp = (const char *)datain + xindex + lowy_int*ysize;
2302 for (k = 0, temp_index = temp; k < components;
2303 k++, temp_index += element_size) {
2305 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2306 totals[k] += *(const GLshort*)&swapbuf * percent;
2308 totals[k] += *(const GLshort*)temp_index * percent;
2311 for (l = lowx_int+1; l < highx_int; l++) {
2313 for (k = 0, temp_index = temp; k < components;
2314 k++, temp_index += element_size) {
2316 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2317 totals[k] += *(const GLshort*)&swapbuf * y_percent;
2319 totals[k] += *(const GLshort*)temp_index * y_percent;
2324 percent = y_percent * highx_float;
2325 for (k = 0, temp_index = temp; k < components;
2326 k++, temp_index += element_size) {
2328 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2329 totals[k] += *(const GLshort*)&swapbuf * percent;
2331 totals[k] += *(const GLshort*)temp_index * percent;
2335 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2336 temp = (const char *)datain + xindex + lowy_int * ysize;
2337 for (k = 0, temp_index = temp; k < components;
2338 k++, temp_index += element_size) {
2340 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2341 totals[k] += *(const GLshort*)&swapbuf * percent;
2343 totals[k] += *(const GLshort*)temp_index * percent;
2348 /* this is for the pixels in the body */
2349 temp0 = (const char *)datain + xindex + group_size +
2351 for (m = lowy_int+1; m < highy_int; m++) {
2353 for(l = lowx_int+1; l < highx_int; l++) {
2354 for (k = 0, temp_index = temp; k < components;
2355 k++, temp_index += element_size) {
2357 swapbuf = __GLU_SWAP_2_BYTES(temp_index);
2358 totals[k] += *(const GLshort*)&swapbuf;
2360 totals[k] += *(const GLshort*)temp_index;
2368 outindex = (j + (i * widthout)) * components;
2369 for (k = 0; k < components; k++) {
2370 dataout[outindex + k] = totals[k]/area;
2371 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2373 lowx_int = highx_int;
2374 lowx_float = highx_float;
2375 highx_int += convx_int;
2376 highx_float += convx_float;
2377 if(highx_float > 1) {
2382 lowy_int = highy_int;
2383 lowy_float = highy_float;
2384 highy_int += convy_int;
2385 highy_float += convy_float;
2386 if(highy_float > 1) {
2393 static void scale_internal_uint(GLint components, GLint widthin,
2394 GLint heightin, const GLuint *datain,
2395 GLint widthout, GLint heightout,
2396 GLuint *dataout, GLint element_size,
2397 GLint ysize, GLint group_size,
2403 /* Max components in a format is 4, so... */
2408 const char *temp, *temp0;
2409 const char *temp_index;
2412 int lowx_int, highx_int, lowy_int, highy_int;
2413 float x_percent, y_percent;
2414 float lowx_float, highx_float, lowy_float, highy_float;
2415 float convy_float, convx_float;
2416 int convy_int, convx_int;
2418 const char *left, *right;
2420 if (widthin == widthout*2 && heightin == heightout*2) {
2421 halveImage_uint(components, widthin, heightin,
2422 (const GLuint *)datain, (GLuint *)dataout,
2423 element_size, ysize, group_size, myswap_bytes);
2426 convy = (float) heightin/heightout;
2427 convx = (float) widthin/widthout;
2428 convy_int = floor(convy);
2429 convy_float = convy - convy_int;
2430 convx_int = floor(convx);
2431 convx_float = convx - convx_int;
2433 area = convx * convy;
2437 highy_int = convy_int;
2438 highy_float = convy_float;
2440 for (i = 0; i < heightout; i++) {
2441 /* Clamp here to be sure we don't read beyond input buffer. */
2442 if (highy_int >= heightin)
2443 highy_int = heightin - 1;
2446 highx_int = convx_int;
2447 highx_float = convx_float;
2449 for (j = 0; j < widthout; j++) {
2451 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2452 ** to (highx, highy) on input data into this pixel on output
2455 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2457 /* calculate the value for pixels in the 1st row */
2458 xindex = lowx_int*group_size;
2459 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2461 y_percent = 1-lowy_float;
2462 temp = (const char *)datain + xindex + lowy_int * ysize;
2463 percent = y_percent * (1-lowx_float);
2464 for (k = 0, temp_index = temp; k < components;
2465 k++, temp_index += element_size) {
2467 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2469 totals[k] += *(const GLuint*)temp_index * percent;
2473 for(l = lowx_int+1; l < highx_int; l++) {
2475 for (k = 0, temp_index = temp; k < components;
2476 k++, temp_index += element_size) {
2479 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2481 totals[k] += *(const GLuint*)temp_index * y_percent;
2487 percent = y_percent * highx_float;
2488 for (k = 0, temp_index = temp; k < components;
2489 k++, temp_index += element_size) {
2491 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2493 totals[k] += *(const GLuint*)temp_index * percent;
2497 /* calculate the value for pixels in the last row */
2498 y_percent = highy_float;
2499 percent = y_percent * (1-lowx_float);
2500 temp = (const char *)datain + xindex + highy_int * ysize;
2501 for (k = 0, temp_index = temp; k < components;
2502 k++, temp_index += element_size) {
2504 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2506 totals[k] += *(const GLuint*)temp_index * percent;
2509 for(l = lowx_int+1; l < highx_int; l++) {
2511 for (k = 0, temp_index = temp; k < components;
2512 k++, temp_index += element_size) {
2515 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2517 totals[k] += *(const GLuint*)temp_index * y_percent;
2522 percent = y_percent * highx_float;
2523 for (k = 0, temp_index = temp; k < components;
2524 k++, temp_index += element_size) {
2526 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2528 totals[k] += *(const GLuint*)temp_index * percent;
2532 /* calculate the value for pixels in the 1st and last column */
2533 for(m = lowy_int+1; m < highy_int; m++) {
2536 for (k = 0; k < components;
2537 k++, left += element_size, right += element_size) {
2540 __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
2541 + __GLU_SWAP_4_BYTES(right) * highx_float;
2543 totals[k] += *(const GLuint*)left * (1-lowx_float)
2544 + *(const GLuint*)right * highx_float;
2548 } else if (highy_int > lowy_int) {
2549 x_percent = highx_float - lowx_float;
2550 percent = (1-lowy_float)*x_percent;
2551 temp = (const char *)datain + xindex + lowy_int*ysize;
2552 for (k = 0, temp_index = temp; k < components;
2553 k++, temp_index += element_size) {
2555 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2557 totals[k] += *(const GLuint*)temp_index * percent;
2560 for(m = lowy_int+1; m < highy_int; m++) {
2562 for (k = 0, temp_index = temp; k < components;
2563 k++, temp_index += element_size) {
2566 __GLU_SWAP_4_BYTES(temp_index) * x_percent;
2568 totals[k] += *(const GLuint*)temp_index * x_percent;
2572 percent = x_percent * highy_float;
2574 for (k = 0, temp_index = temp; k < components;
2575 k++, temp_index += element_size) {
2577 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2579 totals[k] += *(const GLuint*)temp_index * percent;
2582 } else if (highx_int > lowx_int) {
2583 y_percent = highy_float - lowy_float;
2584 percent = (1-lowx_float)*y_percent;
2586 temp = (const char *)datain + xindex + lowy_int*ysize;
2587 for (k = 0, temp_index = temp; k < components;
2588 k++, temp_index += element_size) {
2590 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2592 totals[k] += *(const GLuint*)temp_index * percent;
2595 for (l = lowx_int+1; l < highx_int; l++) {
2597 for (k = 0, temp_index = temp; k < components;
2598 k++, temp_index += element_size) {
2601 __GLU_SWAP_4_BYTES(temp_index) * y_percent;
2603 totals[k] += *(const GLuint*)temp_index * y_percent;
2608 percent = y_percent * highx_float;
2609 for (k = 0, temp_index = temp; k < components;
2610 k++, temp_index += element_size) {
2612 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2614 totals[k] += *(const GLuint*)temp_index * percent;
2618 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2619 temp = (const char *)datain + xindex + lowy_int * ysize;
2620 for (k = 0, temp_index = temp; k < components;
2621 k++, temp_index += element_size) {
2623 totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
2625 totals[k] += *(const GLuint*)temp_index * percent;
2630 /* this is for the pixels in the body */
2631 temp0 = (const char *)datain + xindex + group_size +
2633 for (m = lowy_int+1; m < highy_int; m++) {
2635 for(l = lowx_int+1; l < highx_int; l++) {
2636 for (k = 0, temp_index = temp; k < components;
2637 k++, temp_index += element_size) {
2639 totals[k] += __GLU_SWAP_4_BYTES(temp_index);
2641 totals[k] += *(const GLuint*)temp_index;
2649 outindex = (j + (i * widthout)) * components;
2650 for (k = 0; k < components; k++) {
2651 /* clamp at UINT_MAX */
2652 float value= totals[k]/area;
2653 if (value >= (float) UINT_MAX) { /* need '=' */
2654 dataout[outindex + k] = UINT_MAX;
2656 else dataout[outindex + k] = value;
2658 lowx_int = highx_int;
2659 lowx_float = highx_float;
2660 highx_int += convx_int;
2661 highx_float += convx_float;
2662 if(highx_float > 1) {
2667 lowy_int = highy_int;
2668 lowy_float = highy_float;
2669 highy_int += convy_int;
2670 highy_float += convy_float;
2671 if(highy_float > 1) {
2680 static void scale_internal_int(GLint components, GLint widthin,
2681 GLint heightin, const GLint *datain,
2682 GLint widthout, GLint heightout,
2683 GLint *dataout, GLint element_size,
2684 GLint ysize, GLint group_size,
2690 /* Max components in a format is 4, so... */
2695 const char *temp, *temp0;
2696 const char *temp_index;
2699 int lowx_int, highx_int, lowy_int, highy_int;
2700 float x_percent, y_percent;
2701 float lowx_float, highx_float, lowy_float, highy_float;
2702 float convy_float, convx_float;
2703 int convy_int, convx_int;
2705 const char *left, *right;
2707 GLuint swapbuf; /* unsigned buffer */
2709 if (widthin == widthout*2 && heightin == heightout*2) {
2710 halveImage_int(components, widthin, heightin,
2711 (const GLint *)datain, (GLint *)dataout,
2712 element_size, ysize, group_size, myswap_bytes);
2715 convy = (float) heightin/heightout;
2716 convx = (float) widthin/widthout;
2717 convy_int = floor(convy);
2718 convy_float = convy - convy_int;
2719 convx_int = floor(convx);
2720 convx_float = convx - convx_int;
2722 area = convx * convy;
2726 highy_int = convy_int;
2727 highy_float = convy_float;
2729 for (i = 0; i < heightout; i++) {
2730 /* Clamp here to be sure we don't read beyond input buffer. */
2731 if (highy_int >= heightin)
2732 highy_int = heightin - 1;
2735 highx_int = convx_int;
2736 highx_float = convx_float;
2738 for (j = 0; j < widthout; j++) {
2740 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2741 ** to (highx, highy) on input data into this pixel on output
2744 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
2746 /* calculate the value for pixels in the 1st row */
2747 xindex = lowx_int*group_size;
2748 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
2750 y_percent = 1-lowy_float;
2751 temp = (const char *)datain + xindex + lowy_int * ysize;
2752 percent = y_percent * (1-lowx_float);
2753 for (k = 0, temp_index = temp; k < components;
2754 k++, temp_index += element_size) {
2756 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2757 totals[k] += *(const GLint*)&swapbuf * percent;
2759 totals[k] += *(const GLint*)temp_index * percent;
2763 for(l = lowx_int+1; l < highx_int; l++) {
2765 for (k = 0, temp_index = temp; k < components;
2766 k++, temp_index += element_size) {
2768 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2769 totals[k] += *(const GLint*)&swapbuf * y_percent;
2771 totals[k] += *(const GLint*)temp_index * y_percent;
2777 percent = y_percent * highx_float;
2778 for (k = 0, temp_index = temp; k < components;
2779 k++, temp_index += element_size) {
2781 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2782 totals[k] += *(const GLint*)&swapbuf * percent;
2784 totals[k] += *(const GLint*)temp_index * percent;
2788 /* calculate the value for pixels in the last row */
2789 y_percent = highy_float;
2790 percent = y_percent * (1-lowx_float);
2791 temp = (const char *)datain + xindex + highy_int * ysize;
2792 for (k = 0, temp_index = temp; k < components;
2793 k++, temp_index += element_size) {
2795 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2796 totals[k] += *(const GLint*)&swapbuf * percent;
2798 totals[k] += *(const GLint*)temp_index * percent;
2801 for(l = lowx_int+1; l < highx_int; l++) {
2803 for (k = 0, temp_index = temp; k < components;
2804 k++, temp_index += element_size) {
2806 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2807 totals[k] += *(const GLint*)&swapbuf * y_percent;
2809 totals[k] += *(const GLint*)temp_index * y_percent;
2814 percent = y_percent * highx_float;
2815 for (k = 0, temp_index = temp; k < components;
2816 k++, temp_index += element_size) {
2818 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2819 totals[k] += *(const GLint*)&swapbuf * percent;
2821 totals[k] += *(const GLint*)temp_index * percent;
2825 /* calculate the value for pixels in the 1st and last column */
2826 for(m = lowy_int+1; m < highy_int; m++) {
2829 for (k = 0; k < components;
2830 k++, left += element_size, right += element_size) {
2832 swapbuf = __GLU_SWAP_4_BYTES(left);
2833 totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
2834 swapbuf = __GLU_SWAP_4_BYTES(right);
2835 totals[k] += *(const GLint*)&swapbuf * highx_float;
2837 totals[k] += *(const GLint*)left * (1-lowx_float)
2838 + *(const GLint*)right * highx_float;
2842 } else if (highy_int > lowy_int) {
2843 x_percent = highx_float - lowx_float;
2844 percent = (1-lowy_float)*x_percent;
2845 temp = (const char *)datain + xindex + lowy_int*ysize;
2846 for (k = 0, temp_index = temp; k < components;
2847 k++, temp_index += element_size) {
2849 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2850 totals[k] += *(const GLint*)&swapbuf * percent;
2852 totals[k] += *(const GLint*)temp_index * percent;
2855 for(m = lowy_int+1; m < highy_int; m++) {
2857 for (k = 0, temp_index = temp; k < components;
2858 k++, temp_index += element_size) {
2860 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2861 totals[k] += *(const GLint*)&swapbuf * x_percent;
2863 totals[k] += *(const GLint*)temp_index * x_percent;
2867 percent = x_percent * highy_float;
2869 for (k = 0, temp_index = temp; k < components;
2870 k++, temp_index += element_size) {
2872 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2873 totals[k] += *(const GLint*)&swapbuf * percent;
2875 totals[k] += *(const GLint*)temp_index * percent;
2878 } else if (highx_int > lowx_int) {
2879 y_percent = highy_float - lowy_float;
2880 percent = (1-lowx_float)*y_percent;
2882 temp = (const char *)datain + xindex + lowy_int*ysize;
2883 for (k = 0, temp_index = temp; k < components;
2884 k++, temp_index += element_size) {
2886 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2887 totals[k] += *(const GLint*)&swapbuf * percent;
2889 totals[k] += *(const GLint*)temp_index * percent;
2892 for (l = lowx_int+1; l < highx_int; l++) {
2894 for (k = 0, temp_index = temp; k < components;
2895 k++, temp_index += element_size) {
2897 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2898 totals[k] += *(const GLint*)&swapbuf * y_percent;
2900 totals[k] += *(const GLint*)temp_index * y_percent;
2905 percent = y_percent * highx_float;
2906 for (k = 0, temp_index = temp; k < components;
2907 k++, temp_index += element_size) {
2909 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2910 totals[k] += *(const GLint*)&swapbuf * percent;
2912 totals[k] += *(const GLint*)temp_index * percent;
2916 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
2917 temp = (const char *)datain + xindex + lowy_int * ysize;
2918 for (k = 0, temp_index = temp; k < components;
2919 k++, temp_index += element_size) {
2921 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2922 totals[k] += *(const GLint*)&swapbuf * percent;
2924 totals[k] += *(const GLint*)temp_index * percent;
2929 /* this is for the pixels in the body */
2930 temp0 = (const char *)datain + xindex + group_size +
2932 for (m = lowy_int+1; m < highy_int; m++) {
2934 for(l = lowx_int+1; l < highx_int; l++) {
2935 for (k = 0, temp_index = temp; k < components;
2936 k++, temp_index += element_size) {
2938 swapbuf = __GLU_SWAP_4_BYTES(temp_index);
2939 totals[k] += *(const GLint*)&swapbuf;
2941 totals[k] += *(const GLint*)temp_index;
2949 outindex = (j + (i * widthout)) * components;
2950 for (k = 0; k < components; k++) {
2951 dataout[outindex + k] = totals[k]/area;
2952 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2954 lowx_int = highx_int;
2955 lowx_float = highx_float;
2956 highx_int += convx_int;
2957 highx_float += convx_float;
2958 if(highx_float > 1) {
2963 lowy_int = highy_int;
2964 lowy_float = highy_float;
2965 highy_int += convy_int;
2966 highy_float += convy_float;
2967 if(highy_float > 1) {
2976 static void scale_internal_float(GLint components, GLint widthin,
2977 GLint heightin, const GLfloat *datain,
2978 GLint widthout, GLint heightout,
2979 GLfloat *dataout, GLint element_size,
2980 GLint ysize, GLint group_size,
2986 /* Max components in a format is 4, so... */
2991 const char *temp, *temp0;
2992 const char *temp_index;
2995 int lowx_int, highx_int, lowy_int, highy_int;
2996 float x_percent, y_percent;
2997 float lowx_float, highx_float, lowy_float, highy_float;
2998 float convy_float, convx_float;
2999 int convy_int, convx_int;
3001 const char *left, *right;
3003 union { GLuint b; GLfloat f; } swapbuf;
3005 if (widthin == widthout*2 && heightin == heightout*2) {
3006 halveImage_float(components, widthin, heightin,
3007 (const GLfloat *)datain, (GLfloat *)dataout,
3008 element_size, ysize, group_size, myswap_bytes);
3011 convy = (float) heightin/heightout;
3012 convx = (float) widthin/widthout;
3013 convy_int = floor(convy);
3014 convy_float = convy - convy_int;
3015 convx_int = floor(convx);
3016 convx_float = convx - convx_int;
3018 area = convx * convy;
3022 highy_int = convy_int;
3023 highy_float = convy_float;
3025 for (i = 0; i < heightout; i++) {
3026 /* Clamp here to be sure we don't read beyond input buffer. */
3027 if (highy_int >= heightin)
3028 highy_int = heightin - 1;
3031 highx_int = convx_int;
3032 highx_float = convx_float;
3034 for (j = 0; j < widthout; j++) {
3036 ** Ok, now apply box filter to box that goes from (lowx, lowy)
3037 ** to (highx, highy) on input data into this pixel on output
3040 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
3042 /* calculate the value for pixels in the 1st row */
3043 xindex = lowx_int*group_size;
3044 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
3046 y_percent = 1-lowy_float;
3047 temp = (const char *)datain + xindex + lowy_int * ysize;
3048 percent = y_percent * (1-lowx_float);
3049 for (k = 0, temp_index = temp; k < components;
3050 k++, temp_index += element_size) {
3052 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3053 totals[k] += swapbuf.f * percent;
3055 totals[k] += *(const GLfloat*)temp_index * percent;
3059 for(l = lowx_int+1; l < highx_int; l++) {
3061 for (k = 0, temp_index = temp; k < components;
3062 k++, temp_index += element_size) {
3064 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3065 totals[k] += swapbuf.f * y_percent;
3067 totals[k] += *(const GLfloat*)temp_index * y_percent;
3073 percent = y_percent * highx_float;
3074 for (k = 0, temp_index = temp; k < components;
3075 k++, temp_index += element_size) {
3077 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3078 totals[k] += swapbuf.f * percent;
3080 totals[k] += *(const GLfloat*)temp_index * percent;
3084 /* calculate the value for pixels in the last row */
3085 y_percent = highy_float;
3086 percent = y_percent * (1-lowx_float);
3087 temp = (const char *)datain + xindex + highy_int * ysize;
3088 for (k = 0, temp_index = temp; k < components;
3089 k++, temp_index += element_size) {
3091 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3092 totals[k] += swapbuf.f * percent;
3094 totals[k] += *(const GLfloat*)temp_index * percent;
3097 for(l = lowx_int+1; l < highx_int; l++) {
3099 for (k = 0, temp_index = temp; k < components;
3100 k++, temp_index += element_size) {
3102 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3103 totals[k] += swapbuf.f * y_percent;
3105 totals[k] += *(const GLfloat*)temp_index * y_percent;
3110 percent = y_percent * highx_float;
3111 for (k = 0, temp_index = temp; k < components;
3112 k++, temp_index += element_size) {
3114 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3115 totals[k] += swapbuf.f * percent;
3117 totals[k] += *(const GLfloat*)temp_index * percent;
3121 /* calculate the value for pixels in the 1st and last column */
3122 for(m = lowy_int+1; m < highy_int; m++) {
3125 for (k = 0; k < components;
3126 k++, left += element_size, right += element_size) {
3128 swapbuf.b = __GLU_SWAP_4_BYTES(left);
3129 totals[k] += swapbuf.f * (1-lowx_float);
3130 swapbuf.b = __GLU_SWAP_4_BYTES(right);
3131 totals[k] += swapbuf.f * highx_float;
3133 totals[k] += *(const GLfloat*)left * (1-lowx_float)
3134 + *(const GLfloat*)right * highx_float;
3138 } else if (highy_int > lowy_int) {
3139 x_percent = highx_float - lowx_float;
3140 percent = (1-lowy_float)*x_percent;
3141 temp = (const char *)datain + xindex + lowy_int*ysize;
3142 for (k = 0, temp_index = temp; k < components;
3143 k++, temp_index += element_size) {
3145 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3146 totals[k] += swapbuf.f * percent;
3148 totals[k] += *(const GLfloat*)temp_index * percent;
3151 for(m = lowy_int+1; m < highy_int; m++) {
3153 for (k = 0, temp_index = temp; k < components;
3154 k++, temp_index += element_size) {
3156 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3157 totals[k] += swapbuf.f * x_percent;
3159 totals[k] += *(const GLfloat*)temp_index * x_percent;
3163 percent = x_percent * highy_float;
3165 for (k = 0, temp_index = temp; k < components;
3166 k++, temp_index += element_size) {
3168 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3169 totals[k] += swapbuf.f * percent;
3171 totals[k] += *(const GLfloat*)temp_index * percent;
3174 } else if (highx_int > lowx_int) {
3175 y_percent = highy_float - lowy_float;
3176 percent = (1-lowx_float)*y_percent;
3178 temp = (const char *)datain + xindex + lowy_int*ysize;
3179 for (k = 0, temp_index = temp; k < components;
3180 k++, temp_index += element_size) {
3182 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3183 totals[k] += swapbuf.f * percent;
3185 totals[k] += *(const GLfloat*)temp_index * percent;
3188 for (l = lowx_int+1; l < highx_int; l++) {
3190 for (k = 0, temp_index = temp; k < components;
3191 k++, temp_index += element_size) {
3193 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3194 totals[k] += swapbuf.f * y_percent;
3196 totals[k] += *(const GLfloat*)temp_index * y_percent;
3201 percent = y_percent * highx_float;
3202 for (k = 0, temp_index = temp; k < components;
3203 k++, temp_index += element_size) {
3205 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3206 totals[k] += swapbuf.f * percent;
3208 totals[k] += *(const GLfloat*)temp_index * percent;
3212 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
3213 temp = (const char *)datain + xindex + lowy_int * ysize;
3214 for (k = 0, temp_index = temp; k < components;
3215 k++, temp_index += element_size) {
3217 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3218 totals[k] += swapbuf.f * percent;
3220 totals[k] += *(const GLfloat*)temp_index * percent;
3225 /* this is for the pixels in the body */
3226 temp0 = (const char *)datain + xindex + group_size +
3228 for (m = lowy_int+1; m < highy_int; m++) {
3230 for(l = lowx_int+1; l < highx_int; l++) {
3231 for (k = 0, temp_index = temp; k < components;
3232 k++, temp_index += element_size) {
3234 swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
3235 totals[k] += swapbuf.f;
3237 totals[k] += *(const GLfloat*)temp_index;
3245 outindex = (j + (i * widthout)) * components;
3246 for (k = 0; k < components; k++) {
3247 dataout[outindex + k] = totals[k]/area;
3248 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3250 lowx_int = highx_int;
3251 lowx_float = highx_float;
3252 highx_int += convx_int;
3253 highx_float += convx_float;
3254 if(highx_float > 1) {
3259 lowy_int = highy_int;
3260 lowy_float = highy_float;
3261 highy_int += convy_int;
3262 highy_float += convy_float;
3263 if(highy_float > 1) {
3270 static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
3272 if (!legalFormat(format) || !legalType(type)) {
3273 return GLU_INVALID_ENUM;
3275 if (format == GL_STENCIL_INDEX) {
3276 return GLU_INVALID_ENUM;
3279 if (!isLegalFormatForPackedPixelType(format, type)) {
3280 return GLU_INVALID_OPERATION;
3284 } /* checkMipmapArgs() */
3286 static GLboolean legalFormat(GLenum format)
3289 case GL_COLOR_INDEX:
3290 case GL_STENCIL_INDEX:
3291 case GL_DEPTH_COMPONENT:
3299 case GL_LUMINANCE_ALPHA:
3309 static GLboolean legalType(GLenum type)
3314 case GL_UNSIGNED_BYTE:
3316 case GL_UNSIGNED_SHORT:
3318 case GL_UNSIGNED_INT:
3320 case GL_UNSIGNED_BYTE_3_3_2:
3321 case GL_UNSIGNED_BYTE_2_3_3_REV:
3322 case GL_UNSIGNED_SHORT_5_6_5:
3323 case GL_UNSIGNED_SHORT_5_6_5_REV:
3324 case GL_UNSIGNED_SHORT_4_4_4_4:
3325 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3326 case GL_UNSIGNED_SHORT_5_5_5_1:
3327 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3328 case GL_UNSIGNED_INT_8_8_8_8:
3329 case GL_UNSIGNED_INT_8_8_8_8_REV:
3330 case GL_UNSIGNED_INT_10_10_10_2:
3331 case GL_UNSIGNED_INT_2_10_10_10_REV:
3339 static GLboolean isTypePackedPixel(GLenum type)
3341 assert(legalType(type));
3343 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
3344 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
3345 type == GL_UNSIGNED_SHORT_5_6_5 ||
3346 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
3347 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3348 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3349 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3350 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3351 type == GL_UNSIGNED_INT_8_8_8_8 ||
3352 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3353 type == GL_UNSIGNED_INT_10_10_10_2 ||
3354 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
3358 } /* isTypePackedPixel() */
3360 /* Determines if the packed pixel type is compatible with the format */
3361 static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
3363 /* if not a packed pixel type then return true */
3364 if (!isTypePackedPixel(type)) {
3368 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3369 if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
3370 type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
3371 && format != GL_RGB)
3374 /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
3375 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3377 if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
3378 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
3379 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
3380 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
3381 type == GL_UNSIGNED_INT_8_8_8_8 ||
3382 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
3383 type == GL_UNSIGNED_INT_10_10_10_2 ||
3384 type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
3385 (format != GL_RGBA &&
3386 format != GL_BGRA)) {
3391 } /* isLegalFormatForPackedPixelType() */
3393 static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel,
3396 if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel ||
3397 totalLevels < maxLevel)
3399 else return GL_TRUE;
3400 } /* isLegalLevels() */
3402 /* Given user requested texture size, determine if it fits. If it
3403 * doesn't then halve both sides and make the determination again
3404 * until it does fit (for IR only).
3405 * Note that proxy textures are not implemented in RE* even though
3406 * they advertise the texture extension.
3407 * Note that proxy textures are implemented but not according to spec in
3410 static void closestFit(GLenum target, GLint width, GLint height,
3411 GLint internalFormat, GLenum format, GLenum type,
3412 GLint *newWidth, GLint *newHeight)
3414 /* Use proxy textures if OpenGL version is >= 1.1 */
3415 if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
3417 GLint widthPowerOf2= nearestPower(width);
3418 GLint heightPowerOf2= nearestPower(height);
3422 /* compute level 1 width & height, clamping each at 1 */
3423 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
3424 widthPowerOf2 >> 1 :
3426 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
3427 heightPowerOf2 >> 1 :
3430 assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
3432 /* does width x height at level 1 & all their mipmaps fit? */
3433 if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
3434 proxyTarget = GL_PROXY_TEXTURE_2D;
3435 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3437 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3439 #if defined(GL_ARB_texture_cube_map)
3440 if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
3441 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
3442 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
3443 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
3444 (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
3445 (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
3446 proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
3447 glTexImage2D(proxyTarget, 1, /* must be non-zero */
3449 widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
3451 #endif /* GL_ARB_texture_cube_map */
3453 assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
3454 proxyTarget = GL_PROXY_TEXTURE_1D;
3455 glTexImage1D(proxyTarget, 1, /* must be non-zero */
3456 internalFormat,widthAtLevelOne,0,format,type,NULL);
3458 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
3459 /* does it fit??? */
3460 if (proxyWidth == 0) { /* nope, so try again with these sizes */
3461 if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
3462 /* An 1x1 texture couldn't fit for some reason, so
3463 * break out. This should never happen. But things
3464 * happen. The disadvantage with this if-statement is
3465 * that we will never be aware of when this happens
3466 * since it will silently branch out.
3468 goto noProxyTextures;
3470 widthPowerOf2= widthAtLevelOne;
3471 heightPowerOf2= heightAtLevelOne;
3473 /* else it does fit */
3474 } while (proxyWidth == 0);
3475 /* loop must terminate! */
3477 /* return the width & height at level 0 that fits */
3478 *newWidth= widthPowerOf2;
3479 *newHeight= heightPowerOf2;
3480 /*printf("Proxy Textures\n");*/
3481 } /* if gluCheckExtension() */
3482 else { /* no texture extension, so do this instead */
3487 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3488 /* clamp user's texture sizes to maximum sizes, if necessary */
3489 *newWidth = nearestPower(width);
3490 if (*newWidth > maxsize) *newWidth = maxsize;
3491 *newHeight = nearestPower(height);
3492 if (*newHeight > maxsize) *newHeight = maxsize;
3493 /*printf("NO proxy textures\n");*/
3495 } /* closestFit() */
3498 gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
3499 GLenum typein, const void *datain,
3500 GLsizei widthout, GLsizei heightout, GLenum typeout,
3504 GLushort *beforeImage;
3505 GLushort *afterImage;
3506 PixelStorageModes psm;
3508 if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
3511 if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
3512 return GLU_INVALID_VALUE;
3514 if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
3515 return GLU_INVALID_ENUM;
3517 if (!isLegalFormatForPackedPixelType(format, typein)) {
3518 return GLU_INVALID_OPERATION;
3520 if (!isLegalFormatForPackedPixelType(format, typeout)) {
3521 return GLU_INVALID_OPERATION;
3524 malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
3526 malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
3527 if (beforeImage == NULL || afterImage == NULL) {
3530 return GLU_OUT_OF_MEMORY;
3533 retrieveStoreModes(&psm);
3534 fill_image(&psm,widthin, heightin, format, typein, is_index(format),
3535 datain, beforeImage);
3536 components = elements_per_group(format, 0);
3537 scale_internal(components, widthin, heightin, beforeImage,
3538 widthout, heightout, afterImage);
3539 empty_image(&psm,widthout, heightout, format, typeout,
3540 is_index(format), afterImage, dataout);
3541 free((GLbyte *) beforeImage);
3542 free((GLbyte *) afterImage);
3547 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
3549 GLsizei widthPowerOf2,
3550 GLenum format, GLenum type,
3551 GLint userLevel, GLint baseLevel,GLint maxLevel,
3555 GLint level, levels;
3557 GLint newImage_width;
3558 GLushort *otherImage;
3559 GLushort *imageTemp;
3562 PixelStorageModes psm;
3564 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3569 newwidth= widthPowerOf2;
3570 levels = computeLog(newwidth);
3574 retrieveStoreModes(&psm);
3575 newImage = (GLushort *)
3576 malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
3577 newImage_width = width;
3578 if (newImage == NULL) {
3579 return GLU_OUT_OF_MEMORY;
3581 fill_image(&psm,width, 1, format, type, is_index(format),
3583 cmpts = elements_per_group(format,type);
3584 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3585 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3586 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3587 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3589 ** If swap_bytes was set, swapping occurred in fill_image.
3591 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3593 for (level = userLevel; level <= levels; level++) {
3594 if (newImage_width == newwidth) {
3595 /* Use newImage for this level */
3596 if (baseLevel <= level && level <= maxLevel) {
3597 glTexImage1D(target, level, internalFormat, newImage_width,
3598 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3601 if (otherImage == NULL) {
3602 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
3603 otherImage = (GLushort *) malloc(memreq);
3604 if (otherImage == NULL) {
3605 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3606 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3607 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3608 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3609 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3611 return GLU_OUT_OF_MEMORY;
3614 scale_internal(cmpts, newImage_width, 1, newImage,
3615 newwidth, 1, otherImage);
3616 /* Swap newImage and otherImage */
3617 imageTemp = otherImage;
3618 otherImage = newImage;
3619 newImage = imageTemp;
3621 newImage_width = newwidth;
3622 if (baseLevel <= level && level <= maxLevel) {
3623 glTexImage1D(target, level, internalFormat, newImage_width,
3624 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3627 if (newwidth > 1) newwidth /= 2;
3629 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3630 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3631 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3632 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3633 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3635 free((GLbyte *) newImage);
3637 free((GLbyte *) otherImage);
3643 gluBuild1DMipmapLevels(GLenum target, GLint internalFormat,
3645 GLenum format, GLenum type,
3646 GLint userLevel, GLint baseLevel, GLint maxLevel,
3651 int rc= checkMipmapArgs(internalFormat,format,type);
3652 if (rc != 0) return rc;
3655 return GLU_INVALID_VALUE;
3658 levels = computeLog(width);
3661 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
3662 return GLU_INVALID_VALUE;
3664 return gluBuild1DMipmapLevelsCore(target, internalFormat,
3667 userLevel, baseLevel, maxLevel,
3669 } /* gluBuild1DMipmapLevels() */
3672 gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
3673 GLenum format, GLenum type,
3676 GLint widthPowerOf2;
3680 int rc= checkMipmapArgs(internalFormat,format,type);
3681 if (rc != 0) return rc;
3684 return GLU_INVALID_VALUE;
3687 closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
3688 levels = computeLog(widthPowerOf2);
3690 return gluBuild1DMipmapLevelsCore(target,internalFormat,
3693 format,type,0,0,levels,data);
3696 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
3697 GLint width, GLint height, GLenum format,
3698 GLenum type, const void *data)
3700 GLint newwidth, newheight;
3701 GLint level, levels;
3703 GLint newImage_width;
3704 GLint newImage_height;
3705 GLushort *otherImage;
3706 GLushort *imageTemp;
3709 PixelStorageModes psm;
3711 retrieveStoreModes(&psm);
3714 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3715 newwidth = nearestPower(width);
3716 if (newwidth > maxsize) newwidth = maxsize;
3717 newheight = nearestPower(height);
3718 if (newheight > maxsize) newheight = maxsize;
3720 closestFit(target,width,height,internalFormat,format,type,
3721 &newwidth,&newheight);
3723 levels = computeLog(newwidth);
3724 level = computeLog(newheight);
3725 if (level > levels) levels=level;
3728 newImage = (GLushort *)
3729 malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
3730 newImage_width = width;
3731 newImage_height = height;
3732 if (newImage == NULL) {
3733 return GLU_OUT_OF_MEMORY;
3736 fill_image(&psm,width, height, format, type, is_index(format),
3739 cmpts = elements_per_group(format,type);
3740 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3741 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3742 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3743 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3745 ** If swap_bytes was set, swapping occurred in fill_image.
3747 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3749 for (level = 0; level <= levels; level++) {
3750 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
3751 glTexImage2D(target, level, internalFormat, newImage_width,
3752 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3755 if (otherImage == NULL) {
3757 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
3758 otherImage = (GLushort *) malloc(memreq);
3759 if (otherImage == NULL) {
3760 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3761 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3762 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3763 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3764 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3766 return GLU_OUT_OF_MEMORY;
3769 scale_internal(cmpts, newImage_width, newImage_height, newImage,
3770 newwidth, newheight, otherImage);
3771 /* Swap newImage and otherImage */
3772 imageTemp = otherImage;
3773 otherImage = newImage;
3774 newImage = imageTemp;
3776 newImage_width = newwidth;
3777 newImage_height = newheight;
3778 glTexImage2D(target, level, internalFormat, newImage_width,
3779 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3782 if (newwidth > 1) newwidth /= 2;
3783 if (newheight > 1) newheight /= 2;
3785 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3786 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3787 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3788 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3789 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3791 free((GLbyte *) newImage);
3793 free((GLbyte *) otherImage);
3798 /* To make swapping images less error prone */
3799 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3800 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3802 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3803 GLsizei width, GLsizei height,
3804 GLsizei widthPowerOf2,
3805 GLsizei heightPowerOf2,
3806 GLenum format, GLenum type,
3808 GLint baseLevel,GLint maxLevel,
3811 GLint newwidth, newheight;
3812 GLint level, levels;
3813 const void *usersImage; /* passed from user. Don't touch! */
3814 void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3815 __GLU_INIT_SWAP_IMAGE;
3819 GLint myswap_bytes, groups_per_line, element_size, group_size;
3820 GLint rowsize, padding;
3821 PixelStorageModes psm;
3823 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3824 assert(width >= 1 && height >= 1);
3826 if(type == GL_BITMAP) {
3827 return bitmapBuild2DMipmaps(target, internalFormat, width, height,
3828 format, type, data);
3831 srcImage = dstImage = NULL;
3833 newwidth= widthPowerOf2;
3834 newheight= heightPowerOf2;
3835 levels = computeLog(newwidth);
3836 level = computeLog(newheight);
3837 if (level > levels) levels=level;
3841 retrieveStoreModes(&psm);
3842 myswap_bytes = psm.unpack_swap_bytes;
3843 cmpts = elements_per_group(format,type);
3844 if (psm.unpack_row_length > 0) {
3845 groups_per_line = psm.unpack_row_length;
3847 groups_per_line = width;
3850 element_size = bytes_per_element(type);
3851 group_size = element_size * cmpts;
3852 if (element_size == 1) myswap_bytes = 0;
3854 rowsize = groups_per_line * group_size;
3855 padding = (rowsize % psm.unpack_alignment);
3857 rowsize += psm.unpack_alignment - padding;
3859 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3860 psm.unpack_skip_pixels * group_size;
3862 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3863 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3864 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3868 /* already power-of-two square */
3869 if (width == newwidth && height == newheight) {
3870 /* Use usersImage for level userLevel */
3871 if (baseLevel <= level && level <= maxLevel) {
3872 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3873 glTexImage2D(target, level, internalFormat, width,
3874 height, 0, format, type,
3877 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3878 if(levels == 0) { /* we're done. clean up and return */
3879 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3880 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3881 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3882 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3883 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3887 int nextWidth= newwidth/2;
3888 int nextHeight= newheight/2;
3891 if (nextWidth < 1) nextWidth= 1;
3892 if (nextHeight < 1) nextHeight= 1;
3893 memreq = image_size(nextWidth, nextHeight, format, type);
3897 case GL_UNSIGNED_BYTE:
3898 dstImage = (GLubyte *)malloc(memreq);
3901 dstImage = (GLbyte *)malloc(memreq);
3903 case GL_UNSIGNED_SHORT:
3904 dstImage = (GLushort *)malloc(memreq);
3907 dstImage = (GLshort *)malloc(memreq);
3909 case GL_UNSIGNED_INT:
3910 dstImage = (GLuint *)malloc(memreq);
3913 dstImage = (GLint *)malloc(memreq);
3916 dstImage = (GLfloat *)malloc(memreq);
3918 case GL_UNSIGNED_BYTE_3_3_2:
3919 case GL_UNSIGNED_BYTE_2_3_3_REV:
3920 dstImage = (GLubyte *)malloc(memreq);
3922 case GL_UNSIGNED_SHORT_5_6_5:
3923 case GL_UNSIGNED_SHORT_5_6_5_REV:
3924 case GL_UNSIGNED_SHORT_4_4_4_4:
3925 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3926 case GL_UNSIGNED_SHORT_5_5_5_1:
3927 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3928 dstImage = (GLushort *)malloc(memreq);
3930 case GL_UNSIGNED_INT_8_8_8_8:
3931 case GL_UNSIGNED_INT_8_8_8_8_REV:
3932 case GL_UNSIGNED_INT_10_10_10_2:
3933 case GL_UNSIGNED_INT_2_10_10_10_REV:
3934 dstImage = (GLuint *)malloc(memreq);
3937 return GLU_INVALID_ENUM;
3939 if (dstImage == NULL) {
3940 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3941 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3942 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3943 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3944 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3945 return GLU_OUT_OF_MEMORY;
3949 case GL_UNSIGNED_BYTE:
3950 halveImage_ubyte(cmpts, width, height,
3951 (const GLubyte *)usersImage, (GLubyte *)dstImage,
3952 element_size, rowsize, group_size);
3955 halveImage_byte(cmpts, width, height,
3956 (const GLbyte *)usersImage, (GLbyte *)dstImage,
3957 element_size, rowsize, group_size);
3959 case GL_UNSIGNED_SHORT:
3960 halveImage_ushort(cmpts, width, height,
3961 (const GLushort *)usersImage, (GLushort *)dstImage,
3962 element_size, rowsize, group_size, myswap_bytes);
3965 halveImage_short(cmpts, width, height,
3966 (const GLshort *)usersImage, (GLshort *)dstImage,
3967 element_size, rowsize, group_size, myswap_bytes);
3969 case GL_UNSIGNED_INT:
3970 halveImage_uint(cmpts, width, height,
3971 (const GLuint *)usersImage, (GLuint *)dstImage,
3972 element_size, rowsize, group_size, myswap_bytes);
3975 halveImage_int(cmpts, width, height,
3976 (const GLint *)usersImage, (GLint *)dstImage,
3977 element_size, rowsize, group_size, myswap_bytes);
3980 halveImage_float(cmpts, width, height,
3981 (const GLfloat *)usersImage, (GLfloat *)dstImage,
3982 element_size, rowsize, group_size, myswap_bytes);
3984 case GL_UNSIGNED_BYTE_3_3_2:
3985 assert(format == GL_RGB);
3986 halveImagePackedPixel(3,extract332,shove332,
3987 width,height,usersImage,dstImage,
3988 element_size,rowsize,myswap_bytes);
3990 case GL_UNSIGNED_BYTE_2_3_3_REV:
3991 assert(format == GL_RGB);
3992 halveImagePackedPixel(3,extract233rev,shove233rev,
3993 width,height,usersImage,dstImage,
3994 element_size,rowsize,myswap_bytes);
3996 case GL_UNSIGNED_SHORT_5_6_5:
3997 halveImagePackedPixel(3,extract565,shove565,
3998 width,height,usersImage,dstImage,
3999 element_size,rowsize,myswap_bytes);
4001 case GL_UNSIGNED_SHORT_5_6_5_REV:
4002 halveImagePackedPixel(3,extract565rev,shove565rev,
4003 width,height,usersImage,dstImage,
4004 element_size,rowsize,myswap_bytes);
4006 case GL_UNSIGNED_SHORT_4_4_4_4:
4007 halveImagePackedPixel(4,extract4444,shove4444,
4008 width,height,usersImage,dstImage,
4009 element_size,rowsize,myswap_bytes);
4011 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4012 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4013 width,height,usersImage,dstImage,
4014 element_size,rowsize,myswap_bytes);
4016 case GL_UNSIGNED_SHORT_5_5_5_1:
4017 halveImagePackedPixel(4,extract5551,shove5551,
4018 width,height,usersImage,dstImage,
4019 element_size,rowsize,myswap_bytes);
4021 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4022 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4023 width,height,usersImage,dstImage,
4024 element_size,rowsize,myswap_bytes);
4026 case GL_UNSIGNED_INT_8_8_8_8:
4027 halveImagePackedPixel(4,extract8888,shove8888,
4028 width,height,usersImage,dstImage,
4029 element_size,rowsize,myswap_bytes);
4031 case GL_UNSIGNED_INT_8_8_8_8_REV:
4032 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4033 width,height,usersImage,dstImage,
4034 element_size,rowsize,myswap_bytes);
4036 case GL_UNSIGNED_INT_10_10_10_2:
4037 halveImagePackedPixel(4,extract1010102,shove1010102,
4038 width,height,usersImage,dstImage,
4039 element_size,rowsize,myswap_bytes);
4041 case GL_UNSIGNED_INT_2_10_10_10_REV:
4042 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4043 width,height,usersImage,dstImage,
4044 element_size,rowsize,myswap_bytes);
4051 newheight = height/2;
4053 if (newwidth < 1) newwidth= 1;
4054 if (newheight < 1) newheight= 1;
4057 rowsize = newwidth * group_size;
4058 memreq = image_size(newwidth, newheight, format, type);
4059 /* Swap srcImage and dstImage */
4060 __GLU_SWAP_IMAGE(srcImage,dstImage);
4062 case GL_UNSIGNED_BYTE:
4063 dstImage = (GLubyte *)malloc(memreq);
4066 dstImage = (GLbyte *)malloc(memreq);
4068 case GL_UNSIGNED_SHORT:
4069 dstImage = (GLushort *)malloc(memreq);
4072 dstImage = (GLshort *)malloc(memreq);
4074 case GL_UNSIGNED_INT:
4075 dstImage = (GLuint *)malloc(memreq);
4078 dstImage = (GLint *)malloc(memreq);
4081 dstImage = (GLfloat *)malloc(memreq);
4083 case GL_UNSIGNED_BYTE_3_3_2:
4084 case GL_UNSIGNED_BYTE_2_3_3_REV:
4085 dstImage = (GLubyte *)malloc(memreq);
4087 case GL_UNSIGNED_SHORT_5_6_5:
4088 case GL_UNSIGNED_SHORT_5_6_5_REV:
4089 case GL_UNSIGNED_SHORT_4_4_4_4:
4090 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4091 case GL_UNSIGNED_SHORT_5_5_5_1:
4092 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4093 dstImage = (GLushort *)malloc(memreq);
4095 case GL_UNSIGNED_INT_8_8_8_8:
4096 case GL_UNSIGNED_INT_8_8_8_8_REV:
4097 case GL_UNSIGNED_INT_10_10_10_2:
4098 case GL_UNSIGNED_INT_2_10_10_10_REV:
4099 dstImage = (GLuint *)malloc(memreq);
4102 return GLU_INVALID_ENUM;
4104 if (dstImage == NULL) {
4105 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4106 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4107 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4108 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4109 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4111 return GLU_OUT_OF_MEMORY;
4113 /* level userLevel+1 is in srcImage; level userLevel already saved */
4114 level = userLevel+1;
4115 } else { /* user's image is *not* nice power-of-2 sized square */
4116 memreq = image_size(newwidth, newheight, format, type);
4118 case GL_UNSIGNED_BYTE:
4119 dstImage = (GLubyte *)malloc(memreq);
4122 dstImage = (GLbyte *)malloc(memreq);
4124 case GL_UNSIGNED_SHORT:
4125 dstImage = (GLushort *)malloc(memreq);
4128 dstImage = (GLshort *)malloc(memreq);
4130 case GL_UNSIGNED_INT:
4131 dstImage = (GLuint *)malloc(memreq);
4134 dstImage = (GLint *)malloc(memreq);
4137 dstImage = (GLfloat *)malloc(memreq);
4139 case GL_UNSIGNED_BYTE_3_3_2:
4140 case GL_UNSIGNED_BYTE_2_3_3_REV:
4141 dstImage = (GLubyte *)malloc(memreq);
4143 case GL_UNSIGNED_SHORT_5_6_5:
4144 case GL_UNSIGNED_SHORT_5_6_5_REV:
4145 case GL_UNSIGNED_SHORT_4_4_4_4:
4146 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4147 case GL_UNSIGNED_SHORT_5_5_5_1:
4148 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4149 dstImage = (GLushort *)malloc(memreq);
4151 case GL_UNSIGNED_INT_8_8_8_8:
4152 case GL_UNSIGNED_INT_8_8_8_8_REV:
4153 case GL_UNSIGNED_INT_10_10_10_2:
4154 case GL_UNSIGNED_INT_2_10_10_10_REV:
4155 dstImage = (GLuint *)malloc(memreq);
4158 return GLU_INVALID_ENUM;
4161 if (dstImage == NULL) {
4162 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4163 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4164 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4165 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4166 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4167 return GLU_OUT_OF_MEMORY;
4171 case GL_UNSIGNED_BYTE:
4172 scale_internal_ubyte(cmpts, width, height,
4173 (const GLubyte *)usersImage, newwidth, newheight,
4174 (GLubyte *)dstImage, element_size,
4175 rowsize, group_size);
4178 scale_internal_byte(cmpts, width, height,
4179 (const GLbyte *)usersImage, newwidth, newheight,
4180 (GLbyte *)dstImage, element_size,
4181 rowsize, group_size);
4183 case GL_UNSIGNED_SHORT:
4184 scale_internal_ushort(cmpts, width, height,
4185 (const GLushort *)usersImage, newwidth, newheight,
4186 (GLushort *)dstImage, element_size,
4187 rowsize, group_size, myswap_bytes);
4190 scale_internal_short(cmpts, width, height,
4191 (const GLshort *)usersImage, newwidth, newheight,
4192 (GLshort *)dstImage, element_size,
4193 rowsize, group_size, myswap_bytes);
4195 case GL_UNSIGNED_INT:
4196 scale_internal_uint(cmpts, width, height,
4197 (const GLuint *)usersImage, newwidth, newheight,
4198 (GLuint *)dstImage, element_size,
4199 rowsize, group_size, myswap_bytes);
4202 scale_internal_int(cmpts, width, height,
4203 (const GLint *)usersImage, newwidth, newheight,
4204 (GLint *)dstImage, element_size,
4205 rowsize, group_size, myswap_bytes);
4208 scale_internal_float(cmpts, width, height,
4209 (const GLfloat *)usersImage, newwidth, newheight,
4210 (GLfloat *)dstImage, element_size,
4211 rowsize, group_size, myswap_bytes);
4213 case GL_UNSIGNED_BYTE_3_3_2:
4214 scaleInternalPackedPixel(3,extract332,shove332,
4215 width, height,usersImage,
4216 newwidth,newheight,(void *)dstImage,
4217 element_size,rowsize,myswap_bytes);
4219 case GL_UNSIGNED_BYTE_2_3_3_REV:
4220 scaleInternalPackedPixel(3,extract233rev,shove233rev,
4221 width, height,usersImage,
4222 newwidth,newheight,(void *)dstImage,
4223 element_size,rowsize,myswap_bytes);
4225 case GL_UNSIGNED_SHORT_5_6_5:
4226 scaleInternalPackedPixel(3,extract565,shove565,
4227 width, height,usersImage,
4228 newwidth,newheight,(void *)dstImage,
4229 element_size,rowsize,myswap_bytes);
4231 case GL_UNSIGNED_SHORT_5_6_5_REV:
4232 scaleInternalPackedPixel(3,extract565rev,shove565rev,
4233 width, height,usersImage,
4234 newwidth,newheight,(void *)dstImage,
4235 element_size,rowsize,myswap_bytes);
4237 case GL_UNSIGNED_SHORT_4_4_4_4:
4238 scaleInternalPackedPixel(4,extract4444,shove4444,
4239 width, height,usersImage,
4240 newwidth,newheight,(void *)dstImage,
4241 element_size,rowsize,myswap_bytes);
4243 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4244 scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4245 width, height,usersImage,
4246 newwidth,newheight,(void *)dstImage,
4247 element_size,rowsize,myswap_bytes);
4249 case GL_UNSIGNED_SHORT_5_5_5_1:
4250 scaleInternalPackedPixel(4,extract5551,shove5551,
4251 width, height,usersImage,
4252 newwidth,newheight,(void *)dstImage,
4253 element_size,rowsize,myswap_bytes);
4255 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4256 scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4257 width, height,usersImage,
4258 newwidth,newheight,(void *)dstImage,
4259 element_size,rowsize,myswap_bytes);
4261 case GL_UNSIGNED_INT_8_8_8_8:
4262 scaleInternalPackedPixel(4,extract8888,shove8888,
4263 width, height,usersImage,
4264 newwidth,newheight,(void *)dstImage,
4265 element_size,rowsize,myswap_bytes);
4267 case GL_UNSIGNED_INT_8_8_8_8_REV:
4268 scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4269 width, height,usersImage,
4270 newwidth,newheight,(void *)dstImage,
4271 element_size,rowsize,myswap_bytes);
4273 case GL_UNSIGNED_INT_10_10_10_2:
4274 scaleInternalPackedPixel(4,extract1010102,shove1010102,
4275 width, height,usersImage,
4276 newwidth,newheight,(void *)dstImage,
4277 element_size,rowsize,myswap_bytes);
4279 case GL_UNSIGNED_INT_2_10_10_10_REV:
4280 scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
4281 width, height,usersImage,
4282 newwidth,newheight,(void *)dstImage,
4283 element_size,rowsize,myswap_bytes);
4290 rowsize = newwidth * group_size;
4291 /* Swap dstImage and srcImage */
4292 __GLU_SWAP_IMAGE(srcImage,dstImage);
4294 if(levels != 0) { /* use as little memory as possible */
4296 int nextWidth= newwidth/2;
4297 int nextHeight= newheight/2;
4298 if (nextWidth < 1) nextWidth= 1;
4299 if (nextHeight < 1) nextHeight= 1;
4301 memreq = image_size(nextWidth, nextHeight, format, type);
4305 case GL_UNSIGNED_BYTE:
4306 dstImage = (GLubyte *)malloc(memreq);
4309 dstImage = (GLbyte *)malloc(memreq);
4311 case GL_UNSIGNED_SHORT:
4312 dstImage = (GLushort *)malloc(memreq);
4315 dstImage = (GLshort *)malloc(memreq);
4317 case GL_UNSIGNED_INT:
4318 dstImage = (GLuint *)malloc(memreq);
4321 dstImage = (GLint *)malloc(memreq);
4324 dstImage = (GLfloat *)malloc(memreq);
4326 case GL_UNSIGNED_BYTE_3_3_2:
4327 case GL_UNSIGNED_BYTE_2_3_3_REV:
4328 dstImage = (GLubyte *)malloc(memreq);
4330 case GL_UNSIGNED_SHORT_5_6_5:
4331 case GL_UNSIGNED_SHORT_5_6_5_REV:
4332 case GL_UNSIGNED_SHORT_4_4_4_4:
4333 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4334 case GL_UNSIGNED_SHORT_5_5_5_1:
4335 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4336 dstImage = (GLushort *)malloc(memreq);
4338 case GL_UNSIGNED_INT_8_8_8_8:
4339 case GL_UNSIGNED_INT_8_8_8_8_REV:
4340 case GL_UNSIGNED_INT_10_10_10_2:
4341 case GL_UNSIGNED_INT_2_10_10_10_REV:
4342 dstImage = (GLuint *)malloc(memreq);
4345 return GLU_INVALID_ENUM;
4347 if (dstImage == NULL) {
4348 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4349 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4350 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4351 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4352 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4354 return GLU_OUT_OF_MEMORY;
4357 /* level userLevel is in srcImage; nothing saved yet */
4361 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4362 if (baseLevel <= level && level <= maxLevel) {
4363 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4364 format, type, (void *)srcImage);
4367 level++; /* update current level for the loop */
4368 for (; level <= levels; level++) {
4370 case GL_UNSIGNED_BYTE:
4371 halveImage_ubyte(cmpts, newwidth, newheight,
4372 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4373 rowsize, group_size);
4376 halveImage_byte(cmpts, newwidth, newheight,
4377 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4378 rowsize, group_size);
4380 case GL_UNSIGNED_SHORT:
4381 halveImage_ushort(cmpts, newwidth, newheight,
4382 (GLushort *)srcImage, (GLushort *)dstImage, element_size,
4383 rowsize, group_size, myswap_bytes);
4386 halveImage_short(cmpts, newwidth, newheight,
4387 (GLshort *)srcImage, (GLshort *)dstImage, element_size,
4388 rowsize, group_size, myswap_bytes);
4390 case GL_UNSIGNED_INT:
4391 halveImage_uint(cmpts, newwidth, newheight,
4392 (GLuint *)srcImage, (GLuint *)dstImage, element_size,
4393 rowsize, group_size, myswap_bytes);
4396 halveImage_int(cmpts, newwidth, newheight,
4397 (GLint *)srcImage, (GLint *)dstImage, element_size,
4398 rowsize, group_size, myswap_bytes);
4401 halveImage_float(cmpts, newwidth, newheight,
4402 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4403 rowsize, group_size, myswap_bytes);
4405 case GL_UNSIGNED_BYTE_3_3_2:
4406 halveImagePackedPixel(3,extract332,shove332,
4408 srcImage,dstImage,element_size,rowsize,
4411 case GL_UNSIGNED_BYTE_2_3_3_REV:
4412 halveImagePackedPixel(3,extract233rev,shove233rev,
4414 srcImage,dstImage,element_size,rowsize,
4417 case GL_UNSIGNED_SHORT_5_6_5:
4418 halveImagePackedPixel(3,extract565,shove565,
4420 srcImage,dstImage,element_size,rowsize,
4423 case GL_UNSIGNED_SHORT_5_6_5_REV:
4424 halveImagePackedPixel(3,extract565rev,shove565rev,
4426 srcImage,dstImage,element_size,rowsize,
4429 case GL_UNSIGNED_SHORT_4_4_4_4:
4430 halveImagePackedPixel(4,extract4444,shove4444,
4432 srcImage,dstImage,element_size,rowsize,
4435 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4436 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4438 srcImage,dstImage,element_size,rowsize,
4441 case GL_UNSIGNED_SHORT_5_5_5_1:
4442 halveImagePackedPixel(4,extract5551,shove5551,
4444 srcImage,dstImage,element_size,rowsize,
4447 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4448 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4450 srcImage,dstImage,element_size,rowsize,
4453 case GL_UNSIGNED_INT_8_8_8_8:
4454 halveImagePackedPixel(4,extract8888,shove8888,
4456 srcImage,dstImage,element_size,rowsize,
4459 case GL_UNSIGNED_INT_8_8_8_8_REV:
4460 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4462 srcImage,dstImage,element_size,rowsize,
4465 case GL_UNSIGNED_INT_10_10_10_2:
4466 halveImagePackedPixel(4,extract1010102,shove1010102,
4468 srcImage,dstImage,element_size,rowsize,
4471 case GL_UNSIGNED_INT_2_10_10_10_REV:
4472 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4474 srcImage,dstImage,element_size,rowsize,
4482 __GLU_SWAP_IMAGE(srcImage,dstImage);
4484 if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4485 if (newheight > 1) newheight /= 2;
4487 /* compute amount to pad per row, if any */
4488 int rowPad= rowsize % psm.unpack_alignment;
4490 /* should row be padded? */
4491 if (rowPad == 0) { /* nope, row should not be padded */
4492 /* call tex image with srcImage untouched since it's not padded */
4493 if (baseLevel <= level && level <= maxLevel) {
4494 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4495 format, type, (void *) srcImage);
4498 else { /* yes, row should be padded */
4499 /* compute length of new row in bytes, including padding */
4500 int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4501 int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4503 /* allocate new image for mipmap of size newRowLength x newheight */
4504 void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
4505 if (newMipmapImage == NULL) {
4506 /* out of memory so return */
4507 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4508 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4509 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4510 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4511 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4512 return GLU_OUT_OF_MEMORY;
4515 /* copy image from srcImage into newMipmapImage by rows */
4517 dstTrav= (unsigned char *) newMipmapImage,
4518 srcTrav= (unsigned char *) srcImage;
4521 dstTrav+= newRowLength, /* make sure the correct distance... */
4522 srcTrav+= rowsize) { /* ...is skipped */
4523 memcpy(dstTrav,srcTrav,rowsize);
4524 /* note that the pad bytes are not visited and will contain
4525 * garbage, which is ok.
4529 /* ...and use this new image for mipmapping instead */
4530 if (baseLevel <= level && level <= maxLevel) {
4531 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4532 format, type, newMipmapImage);
4534 free(newMipmapImage); /* don't forget to free it! */
4538 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4539 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4540 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4541 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4542 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4544 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4545 if (dstImage) { /* if it's non-rectangular and only 1 level */
4549 } /* gluBuild2DMipmapLevelsCore() */
4552 gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
4553 GLsizei width, GLsizei height,
4554 GLenum format, GLenum type,
4555 GLint userLevel, GLint baseLevel, GLint maxLevel,
4560 int rc= checkMipmapArgs(internalFormat,format,type);
4561 if (rc != 0) return rc;
4563 if (width < 1 || height < 1) {
4564 return GLU_INVALID_VALUE;
4567 levels = computeLog(width);
4568 level = computeLog(height);
4569 if (level > levels) levels=level;
4572 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
4573 return GLU_INVALID_VALUE;
4575 return gluBuild2DMipmapLevelsCore(target, internalFormat,
4579 userLevel, baseLevel, maxLevel,
4581 } /* gluBuild2DMipmapLevels() */
4584 gluBuild2DMipmaps(GLenum target, GLint internalFormat,
4585 GLsizei width, GLsizei height,
4586 GLenum format, GLenum type,
4589 GLint widthPowerOf2, heightPowerOf2;
4592 int rc= checkMipmapArgs(internalFormat,format,type);
4593 if (rc != 0) return rc;
4595 if (width < 1 || height < 1) {
4596 return GLU_INVALID_VALUE;
4599 closestFit(target,width,height,internalFormat,format,type,
4600 &widthPowerOf2,&heightPowerOf2);
4602 levels = computeLog(widthPowerOf2);
4603 level = computeLog(heightPowerOf2);
4604 if (level > levels) levels=level;
4606 return gluBuild2DMipmapLevelsCore(target,internalFormat,
4608 widthPowerOf2,heightPowerOf2,
4611 } /* gluBuild2DMipmaps() */
4615 ** This routine is for the limited case in which
4616 ** type == GL_UNSIGNED_BYTE && format != index &&
4617 ** unpack_alignment = 1 && unpack_swap_bytes == false
4619 ** so all of the work data can be kept as ubytes instead of shorts.
4621 static int fastBuild2DMipmaps(const PixelStorageModes *psm,
4622 GLenum target, GLint components, GLint width,
4623 GLint height, GLenum format,
4624 GLenum type, void *data)
4626 GLint newwidth, newheight;
4627 GLint level, levels;
4629 GLint newImage_width;
4630 GLint newImage_height;
4631 GLubyte *otherImage;
4638 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
4639 newwidth = nearestPower(width);
4640 if (newwidth > maxsize) newwidth = maxsize;
4641 newheight = nearestPower(height);
4642 if (newheight > maxsize) newheight = maxsize;
4644 closestFit(target,width,height,components,format,type,
4645 &newwidth,&newheight);
4647 levels = computeLog(newwidth);
4648 level = computeLog(newheight);
4649 if (level > levels) levels=level;
4651 cmpts = elements_per_group(format,type);
4655 ** No need to copy the user data if its in the packed correctly.
4656 ** Make sure that later routines don't change that data.
4658 if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
4659 newImage = (GLubyte *)data;
4660 newImage_width = width;
4661 newImage_height = height;
4664 GLint groups_per_line;
4665 GLint elements_per_line;
4666 const GLubyte *start;
4667 const GLubyte *iter;
4671 newImage = (GLubyte *)
4672 malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
4673 newImage_width = width;
4674 newImage_height = height;
4675 if (newImage == NULL) {
4676 return GLU_OUT_OF_MEMORY;
4680 ** Abbreviated version of fill_image for this restricted case.
4682 if (psm->unpack_row_length > 0) {
4683 groups_per_line = psm->unpack_row_length;
4685 groups_per_line = width;
4687 rowsize = groups_per_line * cmpts;
4688 elements_per_line = width * cmpts;
4689 start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
4690 psm->unpack_skip_pixels * cmpts;
4693 for (i = 0; i < height; i++) {
4695 for (j = 0; j < elements_per_line; j++) {
4705 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4706 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
4707 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
4708 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
4709 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4711 for (level = 0; level <= levels; level++) {
4712 if (newImage_width == newwidth && newImage_height == newheight) {
4713 /* Use newImage for this level */
4714 glTexImage2D(target, level, components, newImage_width,
4715 newImage_height, 0, format, GL_UNSIGNED_BYTE,
4718 if (otherImage == NULL) {
4720 image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
4721 otherImage = (GLubyte *) malloc(memreq);
4722 if (otherImage == NULL) {
4723 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4724 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4725 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4726 glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
4727 glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
4728 return GLU_OUT_OF_MEMORY;
4732 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4733 newImage, newwidth, newheight, otherImage);
4735 /* Swap newImage and otherImage */
4736 imageTemp = otherImage;
4737 otherImage = newImage;
4738 newImage = imageTemp;
4740 newImage_width = newwidth;
4741 newImage_height = newheight;
4742 glTexImage2D(target, level, components, newImage_width,
4743 newImage_height, 0, format, GL_UNSIGNED_BYTE,
4746 if (newwidth > 1) newwidth /= 2;
4747 if (newheight > 1) newheight /= 2;
4749 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4750 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4751 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4752 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
4753 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
4755 if (newImage != (const GLubyte *)data) {
4756 free((GLbyte *) newImage);
4758 if (otherImage && otherImage != (const GLubyte *)data) {
4759 free((GLbyte *) otherImage);
4768 static GLint elements_per_group(GLenum format, GLenum type)
4771 * Return the number of elements per group of a specified format
4774 /* If the type is packedpixels then answer is 1 (ignore format) */
4775 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4776 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4777 type == GL_UNSIGNED_SHORT_5_6_5 ||
4778 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4779 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4780 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4781 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
4782 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
4783 type == GL_UNSIGNED_INT_8_8_8_8 ||
4784 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4785 type == GL_UNSIGNED_INT_10_10_10_2 ||
4786 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
4790 /* Types are not packed pixels, so get elements per group */
4795 case GL_LUMINANCE_ALPHA:
4805 static GLfloat bytes_per_element(GLenum type)
4808 * Return the number of bytes per element, based on the element type
4813 case GL_UNSIGNED_SHORT:
4814 return(sizeof(GLushort));
4816 return(sizeof(GLshort));
4817 case GL_UNSIGNED_BYTE:
4818 return(sizeof(GLubyte));
4820 return(sizeof(GLbyte));
4822 return(sizeof(GLint));
4823 case GL_UNSIGNED_INT:
4824 return(sizeof(GLuint));
4826 return(sizeof(GLfloat));
4827 case GL_UNSIGNED_BYTE_3_3_2:
4828 case GL_UNSIGNED_BYTE_2_3_3_REV:
4829 return(sizeof(GLubyte));
4830 case GL_UNSIGNED_SHORT_5_6_5:
4831 case GL_UNSIGNED_SHORT_5_6_5_REV:
4832 case GL_UNSIGNED_SHORT_4_4_4_4:
4833 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4834 case GL_UNSIGNED_SHORT_5_5_5_1:
4835 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4836 return(sizeof(GLushort));
4837 case GL_UNSIGNED_INT_8_8_8_8:
4838 case GL_UNSIGNED_INT_8_8_8_8_REV:
4839 case GL_UNSIGNED_INT_10_10_10_2:
4840 case GL_UNSIGNED_INT_2_10_10_10_REV:
4841 return(sizeof(GLuint));
4847 static GLint is_index(GLenum format)
4849 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4853 ** Compute memory required for internal packed array of data of given type
4856 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4863 components = elements_per_group(format,type);
4864 if (type == GL_BITMAP) {
4865 bytes_per_row = (width + 7) / 8;
4867 bytes_per_row = bytes_per_element(type) * width;
4869 return bytes_per_row * height * components;
4873 ** Extract array from user's data applying all pixel store modes.
4874 ** The internal format used is an array of unsigned shorts.
4876 static void fill_image(const PixelStorageModes *psm,
4877 GLint width, GLint height, GLenum format,
4878 GLenum type, GLboolean index_format,
4879 const void *userdata, GLushort *newimage)
4885 GLint groups_per_line;
4887 GLint elements_per_line;
4888 const GLubyte *start;
4889 const GLubyte *iter;
4894 myswap_bytes = psm->unpack_swap_bytes;
4895 components = elements_per_group(format,type);
4896 if (psm->unpack_row_length > 0) {
4897 groups_per_line = psm->unpack_row_length;
4899 groups_per_line = width;
4902 /* All formats except GL_BITMAP fall out trivially */
4903 if (type == GL_BITMAP) {
4907 rowsize = (groups_per_line * components + 7) / 8;
4908 padding = (rowsize % psm->unpack_alignment);
4910 rowsize += psm->unpack_alignment - padding;
4912 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4913 (psm->unpack_skip_pixels * components / 8);
4914 elements_per_line = width * components;
4916 for (i = 0; i < height; i++) {
4918 bit_offset = (psm->unpack_skip_pixels * components) % 8;
4919 for (j = 0; j < elements_per_line; j++) {
4921 if (psm->unpack_lsb_first) {
4922 current_bit = iter[0] & (1 << bit_offset);
4924 current_bit = iter[0] & (1 << (7 - bit_offset));
4936 if (bit_offset == 8) {
4945 element_size = bytes_per_element(type);
4946 group_size = element_size * components;
4947 if (element_size == 1) myswap_bytes = 0;
4949 rowsize = groups_per_line * group_size;
4950 padding = (rowsize % psm->unpack_alignment);
4952 rowsize += psm->unpack_alignment - padding;
4954 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4955 psm->unpack_skip_pixels * group_size;
4956 elements_per_line = width * components;
4959 for (i = 0; i < height; i++) {
4961 for (j = 0; j < elements_per_line; j++) {
4963 float extractComponents[4];
4966 case GL_UNSIGNED_BYTE_3_3_2:
4967 extract332(0,iter,extractComponents);
4968 for (k = 0; k < 3; k++) {
4969 *iter2++ = (GLushort)(extractComponents[k]*65535);
4972 case GL_UNSIGNED_BYTE_2_3_3_REV:
4973 extract233rev(0,iter,extractComponents);
4974 for (k = 0; k < 3; k++) {
4975 *iter2++ = (GLushort)(extractComponents[k]*65535);
4978 case GL_UNSIGNED_BYTE:
4982 *iter2++ = (*iter) * 257;
4987 *iter2++ = *((const GLbyte *) iter);
4990 *iter2++ = (*((const GLbyte *) iter)) * 516;
4993 case GL_UNSIGNED_SHORT_5_6_5:
4994 extract565(myswap_bytes,iter,extractComponents);
4995 for (k = 0; k < 3; k++) {
4996 *iter2++ = (GLushort)(extractComponents[k]*65535);
4999 case GL_UNSIGNED_SHORT_5_6_5_REV:
5000 extract565rev(myswap_bytes,iter,extractComponents);
5001 for (k = 0; k < 3; k++) {
5002 *iter2++ = (GLushort)(extractComponents[k]*65535);
5005 case GL_UNSIGNED_SHORT_4_4_4_4:
5006 extract4444(myswap_bytes,iter,extractComponents);
5007 for (k = 0; k < 4; k++) {
5008 *iter2++ = (GLushort)(extractComponents[k]*65535);
5011 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5012 extract4444rev(myswap_bytes,iter,extractComponents);
5013 for (k = 0; k < 4; k++) {
5014 *iter2++ = (GLushort)(extractComponents[k]*65535);
5017 case GL_UNSIGNED_SHORT_5_5_5_1:
5018 extract5551(myswap_bytes,iter,extractComponents);
5019 for (k = 0; k < 4; k++) {
5020 *iter2++ = (GLushort)(extractComponents[k]*65535);
5023 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5024 extract1555rev(myswap_bytes,iter,extractComponents);
5025 for (k = 0; k < 4; k++) {
5026 *iter2++ = (GLushort)(extractComponents[k]*65535);
5029 case GL_UNSIGNED_SHORT:
5032 widget.ub[0] = iter[1];
5033 widget.ub[1] = iter[0];
5035 widget.ub[0] = iter[0];
5036 widget.ub[1] = iter[1];
5038 if (type == GL_SHORT) {
5040 *iter2++ = widget.s[0];
5043 *iter2++ = widget.s[0]*2;
5046 *iter2++ = widget.us[0];
5049 case GL_UNSIGNED_INT_8_8_8_8:
5050 extract8888(myswap_bytes,iter,extractComponents);
5051 for (k = 0; k < 4; k++) {
5052 *iter2++ = (GLushort)(extractComponents[k]*65535);
5055 case GL_UNSIGNED_INT_8_8_8_8_REV:
5056 extract8888rev(myswap_bytes,iter,extractComponents);
5057 for (k = 0; k < 4; k++) {
5058 *iter2++ = (GLushort)(extractComponents[k]*65535);
5061 case GL_UNSIGNED_INT_10_10_10_2:
5062 extract1010102(myswap_bytes,iter,extractComponents);
5063 for (k = 0; k < 4; k++) {
5064 *iter2++ = (GLushort)(extractComponents[k]*65535);
5067 case GL_UNSIGNED_INT_2_10_10_10_REV:
5068 extract2101010rev(myswap_bytes,iter,extractComponents);
5069 for (k = 0; k < 4; k++) {
5070 *iter2++ = (GLushort)(extractComponents[k]*65535);
5074 case GL_UNSIGNED_INT:
5077 widget.ub[0] = iter[3];
5078 widget.ub[1] = iter[2];
5079 widget.ub[2] = iter[1];
5080 widget.ub[3] = iter[0];
5082 widget.ub[0] = iter[0];
5083 widget.ub[1] = iter[1];
5084 widget.ub[2] = iter[2];
5085 widget.ub[3] = iter[3];
5087 if (type == GL_FLOAT) {
5089 *iter2++ = widget.f;
5091 *iter2++ = 65535 * widget.f;
5093 } else if (type == GL_UNSIGNED_INT) {
5095 *iter2++ = widget.ui;
5097 *iter2++ = widget.ui >> 16;
5101 *iter2++ = widget.i;
5103 *iter2++ = widget.i >> 15;
5108 iter += element_size;
5112 /* want 'iter' pointing at start, not within, row for assertion
5119 /* iterators should be one byte past end */
5120 if (!isTypePackedPixel(type)) {
5121 assert(iter2 == &newimage[width*height*components]);
5124 assert(iter2 == &newimage[width*height*
5125 elements_per_group(format,0)]);
5127 assert( iter == &((const GLubyte *)userdata)[rowsize*height +
5128 psm->unpack_skip_rows * rowsize +
5129 psm->unpack_skip_pixels * group_size] );
5132 } /* fill_image() */
5135 ** Insert array into user's data applying all pixel store modes.
5136 ** The internal format is an array of unsigned shorts.
5137 ** empty_image() because it is the opposite of fill_image().
5139 static void empty_image(const PixelStorageModes *psm,
5140 GLint width, GLint height, GLenum format,
5141 GLenum type, GLboolean index_format,
5142 const GLushort *oldimage, void *userdata)
5148 GLint groups_per_line;
5150 GLint elements_per_line;
5153 const GLushort *iter2;
5157 myswap_bytes = psm->pack_swap_bytes;
5158 components = elements_per_group(format,type);
5159 if (psm->pack_row_length > 0) {
5160 groups_per_line = psm->pack_row_length;
5162 groups_per_line = width;
5165 /* All formats except GL_BITMAP fall out trivially */
5166 if (type == GL_BITMAP) {
5170 rowsize = (groups_per_line * components + 7) / 8;
5171 padding = (rowsize % psm->pack_alignment);
5173 rowsize += psm->pack_alignment - padding;
5175 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5176 (psm->pack_skip_pixels * components / 8);
5177 elements_per_line = width * components;
5179 for (i = 0; i < height; i++) {
5181 bit_offset = (psm->pack_skip_pixels * components) % 8;
5182 for (j = 0; j < elements_per_line; j++) {
5184 current_bit = iter2[0] & 1;
5186 if (iter2[0] > 32767) {
5194 if (psm->pack_lsb_first) {
5195 *iter |= (1 << bit_offset);
5197 *iter |= (1 << (7 - bit_offset));
5200 if (psm->pack_lsb_first) {
5201 *iter &= ~(1 << bit_offset);
5203 *iter &= ~(1 << (7 - bit_offset));
5208 if (bit_offset == 8) {
5217 float shoveComponents[4];
5219 element_size = bytes_per_element(type);
5220 group_size = element_size * components;
5221 if (element_size == 1) myswap_bytes = 0;
5223 rowsize = groups_per_line * group_size;
5224 padding = (rowsize % psm->pack_alignment);
5226 rowsize += psm->pack_alignment - padding;
5228 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5229 psm->pack_skip_pixels * group_size;
5230 elements_per_line = width * components;
5233 for (i = 0; i < height; i++) {
5235 for (j = 0; j < elements_per_line; j++) {
5239 case GL_UNSIGNED_BYTE_3_3_2:
5240 for (k = 0; k < 3; k++) {
5241 shoveComponents[k]= *iter2++ / 65535.0;
5243 shove332(shoveComponents,0,(void *)iter);
5245 case GL_UNSIGNED_BYTE_2_3_3_REV:
5246 for (k = 0; k < 3; k++) {
5247 shoveComponents[k]= *iter2++ / 65535.0;
5249 shove233rev(shoveComponents,0,(void *)iter);
5251 case GL_UNSIGNED_BYTE:
5255 *iter = *iter2++ >> 8;
5260 *((GLbyte *) iter) = *iter2++;
5262 *((GLbyte *) iter) = *iter2++ >> 9;
5265 case GL_UNSIGNED_SHORT_5_6_5:
5266 for (k = 0; k < 3; k++) {
5267 shoveComponents[k]= *iter2++ / 65535.0;
5269 shove565(shoveComponents,0,(void *)&widget.us[0]);
5271 iter[0] = widget.ub[1];
5272 iter[1] = widget.ub[0];
5275 *(GLushort *)iter = widget.us[0];
5278 case GL_UNSIGNED_SHORT_5_6_5_REV:
5279 for (k = 0; k < 3; k++) {
5280 shoveComponents[k]= *iter2++ / 65535.0;
5282 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
5284 iter[0] = widget.ub[1];
5285 iter[1] = widget.ub[0];
5288 *(GLushort *)iter = widget.us[0];
5291 case GL_UNSIGNED_SHORT_4_4_4_4:
5292 for (k = 0; k < 4; k++) {
5293 shoveComponents[k]= *iter2++ / 65535.0;
5295 shove4444(shoveComponents,0,(void *)&widget.us[0]);
5297 iter[0] = widget.ub[1];
5298 iter[1] = widget.ub[0];
5300 *(GLushort *)iter = widget.us[0];
5303 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5304 for (k = 0; k < 4; k++) {
5305 shoveComponents[k]= *iter2++ / 65535.0;
5307 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
5309 iter[0] = widget.ub[1];
5310 iter[1] = widget.ub[0];
5312 *(GLushort *)iter = widget.us[0];
5315 case GL_UNSIGNED_SHORT_5_5_5_1:
5316 for (k = 0; k < 4; k++) {
5317 shoveComponents[k]= *iter2++ / 65535.0;
5319 shove5551(shoveComponents,0,(void *)&widget.us[0]);
5321 iter[0] = widget.ub[1];
5322 iter[1] = widget.ub[0];
5324 *(GLushort *)iter = widget.us[0];
5327 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5328 for (k = 0; k < 4; k++) {
5329 shoveComponents[k]= *iter2++ / 65535.0;
5331 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
5333 iter[0] = widget.ub[1];
5334 iter[1] = widget.ub[0];
5336 *(GLushort *)iter = widget.us[0];
5339 case GL_UNSIGNED_SHORT:
5341 if (type == GL_SHORT) {
5343 widget.s[0] = *iter2++;
5345 widget.s[0] = *iter2++ >> 1;
5348 widget.us[0] = *iter2++;
5351 iter[0] = widget.ub[1];
5352 iter[1] = widget.ub[0];
5354 iter[0] = widget.ub[0];
5355 iter[1] = widget.ub[1];
5358 case GL_UNSIGNED_INT_8_8_8_8:
5359 for (k = 0; k < 4; k++) {
5360 shoveComponents[k]= *iter2++ / 65535.0;
5362 shove8888(shoveComponents,0,(void *)&widget.ui);
5364 iter[3] = widget.ub[0];
5365 iter[2] = widget.ub[1];
5366 iter[1] = widget.ub[2];
5367 iter[0] = widget.ub[3];
5369 *(GLuint *)iter= widget.ui;
5373 case GL_UNSIGNED_INT_8_8_8_8_REV:
5374 for (k = 0; k < 4; k++) {
5375 shoveComponents[k]= *iter2++ / 65535.0;
5377 shove8888rev(shoveComponents,0,(void *)&widget.ui);
5379 iter[3] = widget.ub[0];
5380 iter[2] = widget.ub[1];
5381 iter[1] = widget.ub[2];
5382 iter[0] = widget.ub[3];
5384 *(GLuint *)iter= widget.ui;
5387 case GL_UNSIGNED_INT_10_10_10_2:
5388 for (k = 0; k < 4; k++) {
5389 shoveComponents[k]= *iter2++ / 65535.0;
5391 shove1010102(shoveComponents,0,(void *)&widget.ui);
5393 iter[3] = widget.ub[0];
5394 iter[2] = widget.ub[1];
5395 iter[1] = widget.ub[2];
5396 iter[0] = widget.ub[3];
5398 *(GLuint *)iter= widget.ui;
5401 case GL_UNSIGNED_INT_2_10_10_10_REV:
5402 for (k = 0; k < 4; k++) {
5403 shoveComponents[k]= *iter2++ / 65535.0;
5405 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5407 iter[3] = widget.ub[0];
5408 iter[2] = widget.ub[1];
5409 iter[1] = widget.ub[2];
5410 iter[0] = widget.ub[3];
5412 *(GLuint *)iter= widget.ui;
5416 case GL_UNSIGNED_INT:
5418 if (type == GL_FLOAT) {
5420 widget.f = *iter2++;
5422 widget.f = *iter2++ / (float) 65535.0;
5424 } else if (type == GL_UNSIGNED_INT) {
5426 widget.ui = *iter2++;
5428 widget.ui = (unsigned int) *iter2++ * 65537;
5432 widget.i = *iter2++;
5434 widget.i = ((unsigned int) *iter2++ * 65537)/2;
5438 iter[3] = widget.ub[0];
5439 iter[2] = widget.ub[1];
5440 iter[1] = widget.ub[2];
5441 iter[0] = widget.ub[3];
5443 iter[0] = widget.ub[0];
5444 iter[1] = widget.ub[1];
5445 iter[2] = widget.ub[2];
5446 iter[3] = widget.ub[3];
5450 iter += element_size;
5454 /* want 'iter' pointing at start, not within, row for assertion
5461 /* iterators should be one byte past end */
5462 if (!isTypePackedPixel(type)) {
5463 assert(iter2 == &oldimage[width*height*components]);
5466 assert(iter2 == &oldimage[width*height*
5467 elements_per_group(format,0)]);
5469 assert( iter == &((GLubyte *)userdata)[rowsize*height +
5470 psm->pack_skip_rows * rowsize +
5471 psm->pack_skip_pixels * group_size] );
5474 } /* empty_image() */
5476 /*--------------------------------------------------------------------------
5477 * Decimation of packed pixel types
5478 *--------------------------------------------------------------------------
5480 static void extract332(int isSwap,
5481 const void *packedPixel, GLfloat extractComponents[])
5483 GLubyte ubyte= *(const GLubyte *)packedPixel;
5485 isSwap= isSwap; /* turn off warnings */
5487 /* 11100000 == 0xe0 */
5488 /* 00011100 == 0x1c */
5489 /* 00000011 == 0x03 */
5491 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0;
5492 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5493 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */
5494 } /* extract332() */
5496 static void shove332(const GLfloat shoveComponents[],
5497 int index, void *packedPixel)
5499 /* 11100000 == 0xe0 */
5500 /* 00011100 == 0x1c */
5501 /* 00000011 == 0x03 */
5503 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5504 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5505 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5507 /* due to limited precision, need to round before shoving */
5508 ((GLubyte *)packedPixel)[index] =
5509 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0;
5510 ((GLubyte *)packedPixel)[index] |=
5511 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c;
5512 ((GLubyte *)packedPixel)[index] |=
5513 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03;
5516 static void extract233rev(int isSwap,
5517 const void *packedPixel, GLfloat extractComponents[])
5519 GLubyte ubyte= *(const GLubyte *)packedPixel;
5521 isSwap= isSwap; /* turn off warnings */
5523 /* 0000,0111 == 0x07 */
5524 /* 0011,1000 == 0x38 */
5525 /* 1100,0000 == 0xC0 */
5527 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0;
5528 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5529 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5530 } /* extract233rev() */
5532 static void shove233rev(const GLfloat shoveComponents[],
5533 int index, void *packedPixel)
5535 /* 0000,0111 == 0x07 */
5536 /* 0011,1000 == 0x38 */
5537 /* 1100,0000 == 0xC0 */
5539 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5540 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5541 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5543 /* due to limited precision, need to round before shoving */
5544 ((GLubyte *)packedPixel)[index] =
5545 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07;
5546 ((GLubyte *)packedPixel)[index]|=
5547 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5548 ((GLubyte *)packedPixel)[index]|=
5549 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5550 } /* shove233rev() */
5552 static void extract565(int isSwap,
5553 const void *packedPixel, GLfloat extractComponents[])
5558 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5561 ushort= *(const GLushort *)packedPixel;
5564 /* 11111000,00000000 == 0xf800 */
5565 /* 00000111,11100000 == 0x07e0 */
5566 /* 00000000,00011111 == 0x001f */
5568 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5569 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5570 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0;
5571 } /* extract565() */
5573 static void shove565(const GLfloat shoveComponents[],
5574 int index,void *packedPixel)
5576 /* 11111000,00000000 == 0xf800 */
5577 /* 00000111,11100000 == 0x07e0 */
5578 /* 00000000,00011111 == 0x001f */
5580 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5581 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5582 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5584 /* due to limited precision, need to round before shoving */
5585 ((GLushort *)packedPixel)[index] =
5586 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5587 ((GLushort *)packedPixel)[index]|=
5588 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0;
5589 ((GLushort *)packedPixel)[index]|=
5590 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f;
5593 static void extract565rev(int isSwap,
5594 const void *packedPixel, GLfloat extractComponents[])
5599 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5602 ushort= *(const GLushort *)packedPixel;
5605 /* 00000000,00011111 == 0x001f */
5606 /* 00000111,11100000 == 0x07e0 */
5607 /* 11111000,00000000 == 0xf800 */
5609 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5610 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0;
5611 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5612 } /* extract565rev() */
5614 static void shove565rev(const GLfloat shoveComponents[],
5615 int index,void *packedPixel)
5617 /* 00000000,00011111 == 0x001f */
5618 /* 00000111,11100000 == 0x07e0 */
5619 /* 11111000,00000000 == 0xf800 */
5621 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5622 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5623 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5625 /* due to limited precision, need to round before shoving */
5626 ((GLushort *)packedPixel)[index] =
5627 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F;
5628 ((GLushort *)packedPixel)[index]|=
5629 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0;
5630 ((GLushort *)packedPixel)[index]|=
5631 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5632 } /* shove565rev() */
5634 static void extract4444(int isSwap,const void *packedPixel,
5635 GLfloat extractComponents[])
5640 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5643 ushort= *(const GLushort *)packedPixel;
5646 /* 11110000,00000000 == 0xf000 */
5647 /* 00001111,00000000 == 0x0f00 */
5648 /* 00000000,11110000 == 0x00f0 */
5649 /* 00000000,00001111 == 0x000f */
5651 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5652 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0;
5653 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0;
5654 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0;
5655 } /* extract4444() */
5657 static void shove4444(const GLfloat shoveComponents[],
5658 int index,void *packedPixel)
5660 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5661 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5662 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5663 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5665 /* due to limited precision, need to round before shoving */
5666 ((GLushort *)packedPixel)[index] =
5667 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5668 ((GLushort *)packedPixel)[index]|=
5669 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00;
5670 ((GLushort *)packedPixel)[index]|=
5671 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0;
5672 ((GLushort *)packedPixel)[index]|=
5673 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f;
5676 static void extract4444rev(int isSwap,const void *packedPixel,
5677 GLfloat extractComponents[])
5682 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5685 ushort= *(const GLushort *)packedPixel;
5688 /* 00000000,00001111 == 0x000f */
5689 /* 00000000,11110000 == 0x00f0 */
5690 /* 00001111,00000000 == 0x0f00 */
5691 /* 11110000,00000000 == 0xf000 */
5694 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0;
5695 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0;
5696 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0;
5697 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5698 } /* extract4444rev() */
5700 static void shove4444rev(const GLfloat shoveComponents[],
5701 int index,void *packedPixel)
5703 /* 00000000,00001111 == 0x000f */
5704 /* 00000000,11110000 == 0x00f0 */
5705 /* 00001111,00000000 == 0x0f00 */
5706 /* 11110000,00000000 == 0xf000 */
5708 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5709 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5710 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5711 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5713 /* due to limited precision, need to round before shoving */
5714 ((GLushort *)packedPixel)[index] =
5715 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F;
5716 ((GLushort *)packedPixel)[index]|=
5717 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0;
5718 ((GLushort *)packedPixel)[index]|=
5719 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00;
5720 ((GLushort *)packedPixel)[index]|=
5721 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5722 } /* shove4444rev() */
5724 static void extract5551(int isSwap,const void *packedPixel,
5725 GLfloat extractComponents[])
5730 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5733 ushort= *(const GLushort *)packedPixel;
5736 /* 11111000,00000000 == 0xf800 */
5737 /* 00000111,11000000 == 0x07c0 */
5738 /* 00000000,00111110 == 0x003e */
5739 /* 00000000,00000001 == 0x0001 */
5741 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5742 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0;
5743 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0;
5744 extractComponents[3]=(float)((ushort & 0x0001) );
5745 } /* extract5551() */
5747 static void shove5551(const GLfloat shoveComponents[],
5748 int index,void *packedPixel)
5750 /* 11111000,00000000 == 0xf800 */
5751 /* 00000111,11000000 == 0x07c0 */
5752 /* 00000000,00111110 == 0x003e */
5753 /* 00000000,00000001 == 0x0001 */
5755 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5756 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5757 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5758 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5760 /* due to limited precision, need to round before shoving */
5761 ((GLushort *)packedPixel)[index] =
5762 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5763 ((GLushort *)packedPixel)[index]|=
5764 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0;
5765 ((GLushort *)packedPixel)[index]|=
5766 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e;
5767 ((GLushort *)packedPixel)[index]|=
5768 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001;
5771 static void extract1555rev(int isSwap,const void *packedPixel,
5772 GLfloat extractComponents[])
5777 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5780 ushort= *(const GLushort *)packedPixel;
5783 /* 00000000,00011111 == 0x001F */
5784 /* 00000011,11100000 == 0x03E0 */
5785 /* 01111100,00000000 == 0x7C00 */
5786 /* 10000000,00000000 == 0x8000 */
5789 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5790 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0;
5791 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5792 extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5793 } /* extract1555rev() */
5795 static void shove1555rev(const GLfloat shoveComponents[],
5796 int index,void *packedPixel)
5798 /* 00000000,00011111 == 0x001F */
5799 /* 00000011,11100000 == 0x03E0 */
5800 /* 01111100,00000000 == 0x7C00 */
5801 /* 10000000,00000000 == 0x8000 */
5803 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5804 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5805 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5806 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5808 /* due to limited precision, need to round before shoving */
5809 ((GLushort *)packedPixel)[index] =
5810 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F;
5811 ((GLushort *)packedPixel)[index]|=
5812 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0;
5813 ((GLushort *)packedPixel)[index]|=
5814 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5815 ((GLushort *)packedPixel)[index]|=
5816 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000;
5817 } /* shove1555rev() */
5819 static void extract8888(int isSwap,
5820 const void *packedPixel, GLfloat extractComponents[])
5825 uint= __GLU_SWAP_4_BYTES(packedPixel);
5828 uint= *(const GLuint *)packedPixel;
5831 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5832 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5833 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5834 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5837 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5838 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5839 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0;
5840 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0;
5841 } /* extract8888() */
5843 static void shove8888(const GLfloat shoveComponents[],
5844 int index,void *packedPixel)
5846 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5847 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5848 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5849 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5851 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5852 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5853 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5854 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5856 /* due to limited precision, need to round before shoving */
5857 ((GLuint *)packedPixel)[index] =
5858 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5859 ((GLuint *)packedPixel)[index]|=
5860 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5861 ((GLuint *)packedPixel)[index]|=
5862 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00;
5863 ((GLuint *)packedPixel)[index]|=
5864 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff;
5867 static void extract8888rev(int isSwap,
5868 const void *packedPixel,GLfloat extractComponents[])
5873 uint= __GLU_SWAP_4_BYTES(packedPixel);
5876 uint= *(const GLuint *)packedPixel;
5879 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5880 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5881 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5882 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5885 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0;
5886 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0;
5887 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5888 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5889 } /* extract8888rev() */
5891 static void shove8888rev(const GLfloat shoveComponents[],
5892 int index,void *packedPixel)
5894 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5895 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5896 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5897 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5899 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5900 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5901 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5902 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5904 /* due to limited precision, need to round before shoving */
5905 ((GLuint *)packedPixel)[index] =
5906 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF;
5907 ((GLuint *)packedPixel)[index]|=
5908 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00;
5909 ((GLuint *)packedPixel)[index]|=
5910 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5911 ((GLuint *)packedPixel)[index]|=
5912 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5913 } /* shove8888rev() */
5915 static void extract1010102(int isSwap,
5916 const void *packedPixel,GLfloat extractComponents[])
5921 uint= __GLU_SWAP_4_BYTES(packedPixel);
5924 uint= *(const GLuint *)packedPixel;
5927 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5928 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5929 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5930 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5933 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5934 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5935 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0;
5936 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0;
5937 } /* extract1010102() */
5939 static void shove1010102(const GLfloat shoveComponents[],
5940 int index,void *packedPixel)
5942 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5943 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5944 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5945 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5947 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5948 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5949 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5950 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5952 /* due to limited precision, need to round before shoving */
5953 ((GLuint *)packedPixel)[index] =
5954 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5955 ((GLuint *)packedPixel)[index]|=
5956 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5957 ((GLuint *)packedPixel)[index]|=
5958 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc;
5959 ((GLuint *)packedPixel)[index]|=
5960 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003;
5961 } /* shove1010102() */
5963 static void extract2101010rev(int isSwap,
5964 const void *packedPixel,
5965 GLfloat extractComponents[])
5970 uint= __GLU_SWAP_4_BYTES(packedPixel);
5973 uint= *(const GLuint *)packedPixel;
5976 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5977 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5978 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5979 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5982 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0;
5983 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5984 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5985 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5987 } /* extract2101010rev() */
5989 static void shove2101010rev(const GLfloat shoveComponents[],
5990 int index,void *packedPixel)
5992 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5993 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5994 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5995 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5997 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5998 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5999 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
6000 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
6002 /* due to limited precision, need to round before shoving */
6003 ((GLuint *)packedPixel)[index] =
6004 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF;
6005 ((GLuint *)packedPixel)[index]|=
6006 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
6007 ((GLuint *)packedPixel)[index]|=
6008 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
6009 ((GLuint *)packedPixel)[index]|=
6010 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000;
6011 } /* shove2101010rev() */
6013 static void scaleInternalPackedPixel(int components,
6014 void (*extractPackedPixel)
6015 (int, const void *,GLfloat []),
6016 void (*shovePackedPixel)
6017 (const GLfloat [], int, void *),
6018 GLint widthIn,GLint heightIn,
6020 GLint widthOut,GLint heightOut,
6022 GLint pixelSizeInBytes,
6023 GLint rowSizeInBytes,GLint isSwap)
6029 /* Max components in a format is 4, so... */
6031 float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
6036 const char *temp, *temp0;
6039 int lowx_int, highx_int, lowy_int, highy_int;
6040 float x_percent, y_percent;
6041 float lowx_float, highx_float, lowy_float, highy_float;
6042 float convy_float, convx_float;
6043 int convy_int, convx_int;
6045 const char *left, *right;
6047 if (widthIn == widthOut*2 && heightIn == heightOut*2) {
6048 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6049 widthIn, heightIn, dataIn, dataOut,
6050 pixelSizeInBytes,rowSizeInBytes,isSwap);
6053 convy = (float) heightIn/heightOut;
6054 convx = (float) widthIn/widthOut;
6055 convy_int = floor(convy);
6056 convy_float = convy - convy_int;
6057 convx_int = floor(convx);
6058 convx_float = convx - convx_int;
6060 area = convx * convy;
6064 highy_int = convy_int;
6065 highy_float = convy_float;
6067 for (i = 0; i < heightOut; i++) {
6070 highx_int = convx_int;
6071 highx_float = convx_float;
6073 for (j = 0; j < widthOut; j++) {
6075 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6076 ** to (highx, highy) on input data into this pixel on output
6079 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6081 /* calculate the value for pixels in the 1st row */
6082 xindex = lowx_int*pixelSizeInBytes;
6083 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
6085 y_percent = 1-lowy_float;
6086 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6087 percent = y_percent * (1-lowx_float);
6089 for (k = 0, temp_index = temp; k < components;
6090 k++, temp_index += element_size) {
6092 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6094 totals[k] += *(const GLushort*)temp_index * percent;
6098 (*extractPackedPixel)(isSwap,temp,extractTotals);
6099 for (k = 0; k < components; k++) {
6100 totals[k]+= extractTotals[k] * percent;
6104 for(l = lowx_int+1; l < highx_int; l++) {
6105 temp += pixelSizeInBytes;
6107 for (k = 0, temp_index = temp; k < components;
6108 k++, temp_index += element_size) {
6111 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6113 totals[k] += *(const GLushort*)temp_index * y_percent;
6117 (*extractPackedPixel)(isSwap,temp,extractTotals);
6118 for (k = 0; k < components; k++) {
6119 totals[k]+= extractTotals[k] * y_percent;
6123 temp += pixelSizeInBytes;
6125 percent = y_percent * highx_float;
6127 for (k = 0, temp_index = temp; k < components;
6128 k++, temp_index += element_size) {
6130 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6132 totals[k] += *(const GLushort*)temp_index * percent;
6136 (*extractPackedPixel)(isSwap,temp,extractTotals);
6137 for (k = 0; k < components; k++) {
6138 totals[k]+= extractTotals[k] * percent;
6142 /* calculate the value for pixels in the last row */
6144 y_percent = highy_float;
6145 percent = y_percent * (1-lowx_float);
6146 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
6148 for (k = 0, temp_index = temp; k < components;
6149 k++, temp_index += element_size) {
6151 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6153 totals[k] += *(const GLushort*)temp_index * percent;
6157 (*extractPackedPixel)(isSwap,temp,extractTotals);
6158 for (k = 0; k < components; k++) {
6159 totals[k]+= extractTotals[k] * percent;
6162 for(l = lowx_int+1; l < highx_int; l++) {
6163 temp += pixelSizeInBytes;
6165 for (k = 0, temp_index = temp; k < components;
6166 k++, temp_index += element_size) {
6169 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6171 totals[k] += *(const GLushort*)temp_index * y_percent;
6175 (*extractPackedPixel)(isSwap,temp,extractTotals);
6176 for (k = 0; k < components; k++) {
6177 totals[k]+= extractTotals[k] * y_percent;
6182 temp += pixelSizeInBytes;
6183 percent = y_percent * highx_float;
6185 for (k = 0, temp_index = temp; k < components;
6186 k++, temp_index += element_size) {
6188 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6190 totals[k] += *(const GLushort*)temp_index * percent;
6194 (*extractPackedPixel)(isSwap,temp,extractTotals);
6195 for (k = 0; k < components; k++) {
6196 totals[k]+= extractTotals[k] * percent;
6200 /* calculate the value for pixels in the 1st and last column */
6201 for(m = lowy_int+1; m < highy_int; m++) {
6202 left += rowSizeInBytes;
6203 right += rowSizeInBytes;
6205 for (k = 0; k < components;
6206 k++, left += element_size, right += element_size) {
6209 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
6210 __GLU_SWAP_2_BYTES(right) * highx_float;
6212 totals[k] += *(const GLushort*)left * (1-lowx_float)
6213 + *(const GLushort*)right * highx_float;
6217 (*extractPackedPixel)(isSwap,left,extractTotals);
6218 (*extractPackedPixel)(isSwap,right,extractMoreTotals);
6219 for (k = 0; k < components; k++) {
6220 totals[k]+= (extractTotals[k]*(1-lowx_float) +
6221 extractMoreTotals[k]*highx_float);
6225 } else if (highy_int > lowy_int) {
6226 x_percent = highx_float - lowx_float;
6227 percent = (1-lowy_float)*x_percent;
6228 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6230 for (k = 0, temp_index = temp; k < components;
6231 k++, temp_index += element_size) {
6233 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6235 totals[k] += *(const GLushort*)temp_index * percent;
6239 (*extractPackedPixel)(isSwap,temp,extractTotals);
6240 for (k = 0; k < components; k++) {
6241 totals[k]+= extractTotals[k] * percent;
6244 for(m = lowy_int+1; m < highy_int; m++) {
6245 temp += rowSizeInBytes;
6247 for (k = 0, temp_index = temp; k < components;
6248 k++, temp_index += element_size) {
6251 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
6253 totals[k] += *(const GLushort*)temp_index * x_percent;
6257 (*extractPackedPixel)(isSwap,temp,extractTotals);
6258 for (k = 0; k < components; k++) {
6259 totals[k]+= extractTotals[k] * x_percent;
6263 percent = x_percent * highy_float;
6264 temp += rowSizeInBytes;
6266 for (k = 0, temp_index = temp; k < components;
6267 k++, temp_index += element_size) {
6269 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6271 totals[k] += *(const GLushort*)temp_index * percent;
6275 (*extractPackedPixel)(isSwap,temp,extractTotals);
6276 for (k = 0; k < components; k++) {
6277 totals[k]+= extractTotals[k] * percent;
6280 } else if (highx_int > lowx_int) {
6281 y_percent = highy_float - lowy_float;
6282 percent = (1-lowx_float)*y_percent;
6283 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6285 for (k = 0, temp_index = temp; k < components;
6286 k++, temp_index += element_size) {
6288 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6290 totals[k] += *(const GLushort*)temp_index * percent;
6294 (*extractPackedPixel)(isSwap,temp,extractTotals);
6295 for (k = 0; k < components; k++) {
6296 totals[k]+= extractTotals[k] * percent;
6299 for (l = lowx_int+1; l < highx_int; l++) {
6300 temp += pixelSizeInBytes;
6302 for (k = 0, temp_index = temp; k < components;
6303 k++, temp_index += element_size) {
6306 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6308 totals[k] += *(const GLushort*)temp_index * y_percent;
6312 (*extractPackedPixel)(isSwap,temp,extractTotals);
6313 for (k = 0; k < components; k++) {
6314 totals[k]+= extractTotals[k] * y_percent;
6318 temp += pixelSizeInBytes;
6319 percent = y_percent * highx_float;
6321 for (k = 0, temp_index = temp; k < components;
6322 k++, temp_index += element_size) {
6324 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6326 totals[k] += *(const GLushort*)temp_index * percent;
6330 (*extractPackedPixel)(isSwap,temp,extractTotals);
6331 for (k = 0; k < components; k++) {
6332 totals[k]+= extractTotals[k] * percent;
6336 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
6337 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6339 for (k = 0, temp_index = temp; k < components;
6340 k++, temp_index += element_size) {
6342 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6344 totals[k] += *(const GLushort*)temp_index * percent;
6348 (*extractPackedPixel)(isSwap,temp,extractTotals);
6349 for (k = 0; k < components; k++) {
6350 totals[k]+= extractTotals[k] * percent;
6355 /* this is for the pixels in the body */
6356 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
6357 for (m = lowy_int+1; m < highy_int; m++) {
6359 for(l = lowx_int+1; l < highx_int; l++) {
6361 for (k = 0, temp_index = temp; k < components;
6362 k++, temp_index += element_size) {
6364 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6366 totals[k] += *(const GLushort*)temp_index;
6370 (*extractPackedPixel)(isSwap,temp,extractTotals);
6371 for (k = 0; k < components; k++) {
6372 totals[k]+= extractTotals[k];
6375 temp += pixelSizeInBytes;
6377 temp0 += rowSizeInBytes;
6380 outindex = (j + (i * widthOut)); /* * (components == 1) */
6382 for (k = 0; k < components; k++) {
6383 dataout[outindex + k] = totals[k]/area;
6384 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6387 for (k = 0; k < components; k++) {
6388 shoveTotals[k]= totals[k]/area;
6390 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6392 lowx_int = highx_int;
6393 lowx_float = highx_float;
6394 highx_int += convx_int;
6395 highx_float += convx_float;
6396 if(highx_float > 1) {
6401 lowy_int = highy_int;
6402 lowy_float = highy_float;
6403 highy_int += convy_int;
6404 highy_float += convy_float;
6405 if(highy_float > 1) {
6411 assert(outindex == (widthOut*heightOut - 1));
6412 } /* scaleInternalPackedPixel() */
6414 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6415 * inputs; not always equal. Output NEVER has row padding.
6417 static void halveImagePackedPixel(int components,
6418 void (*extractPackedPixel)
6419 (int, const void *,GLfloat []),
6420 void (*shovePackedPixel)
6421 (const GLfloat [],int, void *),
6422 GLint width, GLint height,
6423 const void *dataIn, void *dataOut,
6424 GLint pixelSizeInBytes,
6425 GLint rowSizeInBytes, GLint isSwap)
6427 /* handle case where there is only 1 column/row */
6428 if (width == 1 || height == 1) {
6429 assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6430 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6431 width,height,dataIn,dataOut,pixelSizeInBytes,
6432 rowSizeInBytes,isSwap);
6439 int halfWidth= width / 2;
6440 int halfHeight= height / 2;
6441 const char *src= (const char *) dataIn;
6442 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6445 for (ii= 0; ii< halfHeight; ii++) {
6446 for (jj= 0; jj< halfWidth; jj++) {
6448 float totals[4]; /* 4 is maximum components */
6449 float extractTotals[BOX4][4]; /* 4 is maximum components */
6452 (*extractPackedPixel)(isSwap,src,
6453 &extractTotals[0][0]);
6454 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6455 &extractTotals[1][0]);
6456 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6457 &extractTotals[2][0]);
6458 (*extractPackedPixel)(isSwap,
6459 (src+rowSizeInBytes+pixelSizeInBytes),
6460 &extractTotals[3][0]);
6461 for (cc = 0; cc < components; cc++) {
6464 /* grab 4 pixels to average */
6466 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6467 * extractTotals[2][RED]+extractTotals[3][RED];
6468 * totals[RED]/= 4.0;
6470 for (kk = 0; kk < BOX4; kk++) {
6471 totals[cc]+= extractTotals[kk][cc];
6473 totals[cc]/= (float)BOX4;
6475 (*shovePackedPixel)(totals,outIndex,dataOut);
6478 /* skip over to next square of 4 */
6479 src+= pixelSizeInBytes + pixelSizeInBytes;
6481 /* skip past pad bytes, if any, to get to next row */
6484 /* src is at beginning of a row here, but it's the second row of
6485 * the square block of 4 pixels that we just worked on so we
6486 * need to go one more row.
6494 src+= rowSizeInBytes;
6497 /* both pointers must reach one byte after the end */
6498 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6499 assert(outIndex == halfWidth * halfHeight);
6501 } /* halveImagePackedPixel() */
6503 static void halve1DimagePackedPixel(int components,
6504 void (*extractPackedPixel)
6505 (int, const void *,GLfloat []),
6506 void (*shovePackedPixel)
6507 (const GLfloat [],int, void *),
6508 GLint width, GLint height,
6509 const void *dataIn, void *dataOut,
6510 GLint pixelSizeInBytes,
6511 GLint rowSizeInBytes, GLint isSwap)
6513 int halfWidth= width / 2;
6514 int halfHeight= height / 2;
6515 const char *src= (const char *) dataIn;
6518 assert(width == 1 || height == 1); /* must be 1D */
6519 assert(width != height); /* can't be square */
6521 if (height == 1) { /* 1 row */
6524 assert(width != 1); /* widthxheight can't be 1x1 */
6527 /* one horizontal row with possible pad bytes */
6529 for (jj= 0; jj< halfWidth; jj++) {
6531 float totals[4]; /* 4 is maximum components */
6532 float extractTotals[BOX2][4]; /* 4 is maximum components */
6535 /* average two at a time, instead of four */
6536 (*extractPackedPixel)(isSwap,src,
6537 &extractTotals[0][0]);
6538 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6539 &extractTotals[1][0]);
6540 for (cc = 0; cc < components; cc++) {
6543 /* grab 2 pixels to average */
6545 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6546 * totals[RED]/= 2.0;
6548 for (kk = 0; kk < BOX2; kk++) {
6549 totals[cc]+= extractTotals[kk][cc];
6551 totals[cc]/= (float)BOX2;
6553 (*shovePackedPixel)(totals,outIndex,dataOut);
6556 /* skip over to next group of 2 */
6557 src+= pixelSizeInBytes + pixelSizeInBytes;
6561 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6562 src+= padBytes; /* for assertion only */
6564 assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6565 assert(outIndex == halfWidth * halfHeight);
6567 else if (width == 1) { /* 1 column */
6570 assert(height != 1); /* widthxheight can't be 1x1 */
6572 /* one vertical column with possible pad bytes per row */
6573 /* average two at a time */
6575 for (jj= 0; jj< halfHeight; jj++) {
6577 float totals[4]; /* 4 is maximum components */
6578 float extractTotals[BOX2][4]; /* 4 is maximum components */
6581 /* average two at a time, instead of four */
6582 (*extractPackedPixel)(isSwap,src,
6583 &extractTotals[0][0]);
6584 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6585 &extractTotals[1][0]);
6586 for (cc = 0; cc < components; cc++) {
6589 /* grab 2 pixels to average */
6591 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6592 * totals[RED]/= 2.0;
6594 for (kk = 0; kk < BOX2; kk++) {
6595 totals[cc]+= extractTotals[kk][cc];
6597 totals[cc]/= (float)BOX2;
6599 (*shovePackedPixel)(totals,outIndex,dataOut);
6602 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6605 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6606 assert(outIndex == halfWidth * halfHeight);
6608 } /* halve1DimagePackedPixel() */
6610 /*===========================================================================*/
6612 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6614 * This section ensures that GLU 1.3 will load and run on
6615 * a GL 1.1 implementation. It dynamically resolves the
6616 * call to glTexImage3D() which might not be available.
6617 * Or is it might be supported as an extension.
6618 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6621 typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
6622 GLenum internalFormat,
6623 GLsizei width, GLsizei height,
6624 GLsizei depth, GLint border,
6625 GLenum format, GLenum type,
6626 const GLvoid *pixels );
6628 static TexImage3Dproc pTexImage3D = 0;
6630 #if !defined(_WIN32) && !defined(__WIN32__)
6632 # include <sys/types.h>
6634 WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR);
6637 static void gluTexImage3D( GLenum target, GLint level,
6638 GLenum internalFormat,
6639 GLsizei width, GLsizei height,
6640 GLsizei depth, GLint border,
6641 GLenum format, GLenum type,
6642 const GLvoid *pixels )
6645 #if defined(_WIN32) || defined(__WIN32__)
6646 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
6648 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
6650 void *libHandle = dlopen("libgl.so", RTLD_LAZY);
6651 pTexImage3D = (TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
6653 pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
6658 /* Now call glTexImage3D */
6660 pTexImage3D(target, level, internalFormat, width, height,
6661 depth, border, format, type, pixels);
6666 /* Only bind to a GL 1.2 implementation: */
6667 #define gluTexImage3D glTexImage3D
6671 static GLint imageSize3D(GLint width, GLint height, GLint depth,
6672 GLenum format, GLenum type)
6674 int components= elements_per_group(format,type);
6675 int bytes_per_row= bytes_per_element(type) * width;
6677 assert(width > 0 && height > 0 && depth > 0);
6678 assert(type != GL_BITMAP);
6680 return bytes_per_row * height * depth * components;
6681 } /* imageSize3D() */
6683 static void fillImage3D(const PixelStorageModes *psm,
6684 GLint width, GLint height, GLint depth, GLenum format,
6685 GLenum type, GLboolean indexFormat,
6686 const void *userImage, GLushort *newImage)
6695 int elementsPerLine;
6698 const GLubyte *start, *rowStart, *iter;
6702 myswapBytes= psm->unpack_swap_bytes;
6703 components= elements_per_group(format,type);
6704 if (psm->unpack_row_length > 0) {
6705 groupsPerLine= psm->unpack_row_length;
6708 groupsPerLine= width;
6710 elementSize= bytes_per_element(type);
6711 groupSize= elementSize * components;
6712 if (elementSize == 1) myswapBytes= 0;
6715 if (psm->unpack_image_height > 0) {
6716 rowsPerImage= psm->unpack_image_height;
6719 rowsPerImage= height;
6723 rowSize= groupsPerLine * groupSize;
6724 padding= rowSize % psm->unpack_alignment;
6726 rowSize+= psm->unpack_alignment - padding;
6729 imageSize= rowsPerImage * rowSize; /* 3dstuff */
6731 start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
6732 psm->unpack_skip_pixels * groupSize +
6734 psm->unpack_skip_images * imageSize;
6735 elementsPerLine = width * components;
6738 for (dd= 0; dd < depth; dd++) {
6741 for (hh= 0; hh < height; hh++) {
6744 for (ww= 0; ww < elementsPerLine; ww++) {
6746 float extractComponents[4];
6749 case GL_UNSIGNED_BYTE:
6753 *iter2++ = (*iter) * 257;
6758 *iter2++ = *((const GLbyte *) iter);
6761 *iter2++ = (*((const GLbyte *) iter)) * 516;
6764 case GL_UNSIGNED_BYTE_3_3_2:
6765 extract332(0,iter,extractComponents);
6766 for (k = 0; k < 3; k++) {
6767 *iter2++ = (GLushort)(extractComponents[k]*65535);
6770 case GL_UNSIGNED_BYTE_2_3_3_REV:
6771 extract233rev(0,iter,extractComponents);
6772 for (k = 0; k < 3; k++) {
6773 *iter2++ = (GLushort)(extractComponents[k]*65535);
6776 case GL_UNSIGNED_SHORT_5_6_5:
6777 extract565(myswapBytes,iter,extractComponents);
6778 for (k = 0; k < 3; k++) {
6779 *iter2++ = (GLushort)(extractComponents[k]*65535);
6782 case GL_UNSIGNED_SHORT_5_6_5_REV:
6783 extract565rev(myswapBytes,iter,extractComponents);
6784 for (k = 0; k < 3; k++) {
6785 *iter2++ = (GLushort)(extractComponents[k]*65535);
6788 case GL_UNSIGNED_SHORT_4_4_4_4:
6789 extract4444(myswapBytes,iter,extractComponents);
6790 for (k = 0; k < 4; k++) {
6791 *iter2++ = (GLushort)(extractComponents[k]*65535);
6794 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
6795 extract4444rev(myswapBytes,iter,extractComponents);
6796 for (k = 0; k < 4; k++) {
6797 *iter2++ = (GLushort)(extractComponents[k]*65535);
6800 case GL_UNSIGNED_SHORT_5_5_5_1:
6801 extract5551(myswapBytes,iter,extractComponents);
6802 for (k = 0; k < 4; k++) {
6803 *iter2++ = (GLushort)(extractComponents[k]*65535);
6806 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
6807 extract1555rev(myswapBytes,iter,extractComponents);
6808 for (k = 0; k < 4; k++) {
6809 *iter2++ = (GLushort)(extractComponents[k]*65535);
6812 case GL_UNSIGNED_SHORT:
6815 widget.ub[0] = iter[1];
6816 widget.ub[1] = iter[0];
6818 widget.ub[0] = iter[0];
6819 widget.ub[1] = iter[1];
6821 if (type == GL_SHORT) {
6823 *iter2++ = widget.s[0];
6826 *iter2++ = widget.s[0]*2;
6829 *iter2++ = widget.us[0];
6832 case GL_UNSIGNED_INT_8_8_8_8:
6833 extract8888(myswapBytes,iter,extractComponents);
6834 for (k = 0; k < 4; k++) {
6835 *iter2++ = (GLushort)(extractComponents[k]*65535);
6838 case GL_UNSIGNED_INT_8_8_8_8_REV:
6839 extract8888rev(myswapBytes,iter,extractComponents);
6840 for (k = 0; k < 4; k++) {
6841 *iter2++ = (GLushort)(extractComponents[k]*65535);
6844 case GL_UNSIGNED_INT_10_10_10_2:
6845 extract1010102(myswapBytes,iter,extractComponents);
6846 for (k = 0; k < 4; k++) {
6847 *iter2++ = (GLushort)(extractComponents[k]*65535);
6850 case GL_UNSIGNED_INT_2_10_10_10_REV:
6851 extract2101010rev(myswapBytes,iter,extractComponents);
6852 for (k = 0; k < 4; k++) {
6853 *iter2++ = (GLushort)(extractComponents[k]*65535);
6857 case GL_UNSIGNED_INT:
6860 widget.ub[0] = iter[3];
6861 widget.ub[1] = iter[2];
6862 widget.ub[2] = iter[1];
6863 widget.ub[3] = iter[0];
6865 widget.ub[0] = iter[0];
6866 widget.ub[1] = iter[1];
6867 widget.ub[2] = iter[2];
6868 widget.ub[3] = iter[3];
6870 if (type == GL_FLOAT) {
6872 *iter2++ = widget.f;
6874 *iter2++ = 65535 * widget.f;
6876 } else if (type == GL_UNSIGNED_INT) {
6878 *iter2++ = widget.ui;
6880 *iter2++ = widget.ui >> 16;
6884 *iter2++ = widget.i;
6886 *iter2++ = widget.i >> 15;
6898 iter= rowStart; /* for assertion purposes */
6904 /* iterators should be one byte past end */
6905 if (!isTypePackedPixel(type)) {
6906 assert(iter2 == &newImage[width*height*depth*components]);
6909 assert(iter2 == &newImage[width*height*depth*
6910 elements_per_group(format,0)]);
6912 assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
6913 psm->unpack_skip_rows * rowSize +
6914 psm->unpack_skip_pixels * groupSize +
6916 psm->unpack_skip_images * imageSize] );
6917 } /* fillImage3D () */
6919 static void scaleInternal3D(GLint components,
6920 GLint widthIn, GLint heightIn, GLint depthIn,
6921 const GLushort *dataIn,
6922 GLint widthOut, GLint heightOut, GLint depthOut,
6925 float x, lowx, highx, convx, halfconvx;
6926 float y, lowy, highy, convy, halfconvy;
6927 float z, lowz, highz, convz, halfconvz;
6928 float xpercent,ypercent,zpercent;
6930 /* Max components in a format is 4, so... */
6933 int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
6936 convz = (float) depthIn/depthOut;
6937 convy = (float) heightIn/heightOut;
6938 convx = (float) widthIn/widthOut;
6939 halfconvx = convx/2;
6940 halfconvy = convy/2;
6941 halfconvz = convz/2;
6942 for (d = 0; d < depthOut; d++) {
6943 z = convz * (d+0.5);
6944 if (depthIn > depthOut) {
6945 highz = z + halfconvz;
6946 lowz = z - halfconvz;
6951 for (i = 0; i < heightOut; i++) {
6952 y = convy * (i+0.5);
6953 if (heightIn > heightOut) {
6954 highy = y + halfconvy;
6955 lowy = y - halfconvy;
6960 for (j = 0; j < widthOut; j++) {
6961 x = convx * (j+0.5);
6962 if (widthIn > widthOut) {
6963 highx = x + halfconvx;
6964 lowx = x - halfconvx;
6971 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6972 ** lowz) to (highx, highy, highz) on input data into this pixel
6975 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6981 zindex = (zint + depthIn) % depthIn;
6982 if (highz < zint+1) {
6983 zpercent = highz - z;
6985 zpercent = zint+1 - z;
6991 yindex = (yint + heightIn) % heightIn;
6992 if (highy < yint+1) {
6993 ypercent = highy - y;
6995 ypercent = yint+1 - y;
7002 xindex = (xint + widthIn) % widthIn;
7003 if (highx < xint+1) {
7004 xpercent = highx - x;
7006 xpercent = xint+1 - x;
7009 percent = xpercent * ypercent * zpercent;
7012 temp = (xindex + (yindex*widthIn) +
7013 (zindex*widthIn*heightIn)) * components;
7014 for (k = 0; k < components; k++) {
7015 assert(0 <= (temp+k) &&
7017 (widthIn*heightIn*depthIn*components));
7018 totals[k] += dataIn[temp + k] * percent;
7033 temp = (j + (i * widthOut) +
7034 (d*widthOut*heightOut)) * components;
7035 for (k = 0; k < components; k++) {
7036 /* totals[] should be rounded in the case of enlarging an
7037 * RGB ramp when the type is 332 or 4444
7039 assert(0 <= (temp+k) &&
7040 (temp+k) < (widthOut*heightOut*depthOut*components));
7041 dataOut[temp + k] = (totals[k]+0.5)/volume;
7046 } /* scaleInternal3D() */
7048 static void emptyImage3D(const PixelStorageModes *psm,
7049 GLint width, GLint height, GLint depth,
7050 GLenum format, GLenum type, GLboolean indexFormat,
7051 const GLushort *oldImage, void *userImage)
7060 GLubyte *start, *rowStart, *iter;
7061 int elementsPerLine;
7062 const GLushort *iter2;
7067 myswapBytes= psm->pack_swap_bytes;
7068 components = elements_per_group(format,type);
7069 if (psm->pack_row_length > 0) {
7070 groupsPerLine = psm->pack_row_length;
7073 groupsPerLine = width;
7076 elementSize= bytes_per_element(type);
7077 groupSize= elementSize * components;
7078 if (elementSize == 1) myswapBytes= 0;
7081 if (psm->pack_image_height > 0) {
7082 rowsPerImage= psm->pack_image_height;
7085 rowsPerImage= height;
7090 rowSize = groupsPerLine * groupSize;
7091 padding = rowSize % psm->pack_alignment;
7093 rowSize+= psm->pack_alignment - padding;
7096 imageSize= rowsPerImage * rowSize; /* 3dstuff */
7098 start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
7099 psm->pack_skip_pixels * groupSize +
7101 psm->pack_skip_images * imageSize;
7102 elementsPerLine= width * components;
7105 for (dd= 0; dd < depth; dd++) {
7108 for (ii= 0; ii< height; ii++) {
7111 for (jj = 0; jj < elementsPerLine; jj++) {
7113 float shoveComponents[4];
7116 case GL_UNSIGNED_BYTE:
7120 *iter = *iter2++ >> 8;
7125 *((GLbyte *) iter) = *iter2++;
7127 *((GLbyte *) iter) = *iter2++ >> 9;
7130 case GL_UNSIGNED_BYTE_3_3_2:
7131 for (k = 0; k < 3; k++) {
7132 shoveComponents[k]= *iter2++ / 65535.0;
7134 shove332(shoveComponents,0,(void *)iter);
7136 case GL_UNSIGNED_BYTE_2_3_3_REV:
7137 for (k = 0; k < 3; k++) {
7138 shoveComponents[k]= *iter2++ / 65535.0;
7140 shove233rev(shoveComponents,0,(void *)iter);
7142 case GL_UNSIGNED_SHORT_5_6_5:
7143 for (k = 0; k < 3; k++) {
7144 shoveComponents[k]= *iter2++ / 65535.0;
7146 shove565(shoveComponents,0,(void *)&widget.us[0]);
7148 iter[0] = widget.ub[1];
7149 iter[1] = widget.ub[0];
7152 *(GLushort *)iter = widget.us[0];
7155 case GL_UNSIGNED_SHORT_5_6_5_REV:
7156 for (k = 0; k < 3; k++) {
7157 shoveComponents[k]= *iter2++ / 65535.0;
7159 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
7161 iter[0] = widget.ub[1];
7162 iter[1] = widget.ub[0];
7165 *(GLushort *)iter = widget.us[0];
7168 case GL_UNSIGNED_SHORT_4_4_4_4:
7169 for (k = 0; k < 4; k++) {
7170 shoveComponents[k]= *iter2++ / 65535.0;
7172 shove4444(shoveComponents,0,(void *)&widget.us[0]);
7174 iter[0] = widget.ub[1];
7175 iter[1] = widget.ub[0];
7177 *(GLushort *)iter = widget.us[0];
7180 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7181 for (k = 0; k < 4; k++) {
7182 shoveComponents[k]= *iter2++ / 65535.0;
7184 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
7186 iter[0] = widget.ub[1];
7187 iter[1] = widget.ub[0];
7189 *(GLushort *)iter = widget.us[0];
7192 case GL_UNSIGNED_SHORT_5_5_5_1:
7193 for (k = 0; k < 4; k++) {
7194 shoveComponents[k]= *iter2++ / 65535.0;
7196 shove5551(shoveComponents,0,(void *)&widget.us[0]);
7198 iter[0] = widget.ub[1];
7199 iter[1] = widget.ub[0];
7201 *(GLushort *)iter = widget.us[0];
7204 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7205 for (k = 0; k < 4; k++) {
7206 shoveComponents[k]= *iter2++ / 65535.0;
7208 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
7210 iter[0] = widget.ub[1];
7211 iter[1] = widget.ub[0];
7213 *(GLushort *)iter = widget.us[0];
7216 case GL_UNSIGNED_SHORT:
7218 if (type == GL_SHORT) {
7220 widget.s[0] = *iter2++;
7222 widget.s[0] = *iter2++ >> 1;
7225 widget.us[0] = *iter2++;
7228 iter[0] = widget.ub[1];
7229 iter[1] = widget.ub[0];
7231 iter[0] = widget.ub[0];
7232 iter[1] = widget.ub[1];
7235 case GL_UNSIGNED_INT_8_8_8_8:
7236 for (k = 0; k < 4; k++) {
7237 shoveComponents[k]= *iter2++ / 65535.0;
7239 shove8888(shoveComponents,0,(void *)&widget.ui);
7241 iter[3] = widget.ub[0];
7242 iter[2] = widget.ub[1];
7243 iter[1] = widget.ub[2];
7244 iter[0] = widget.ub[3];
7246 *(GLuint *)iter= widget.ui;
7249 case GL_UNSIGNED_INT_8_8_8_8_REV:
7250 for (k = 0; k < 4; k++) {
7251 shoveComponents[k]= *iter2++ / 65535.0;
7253 shove8888rev(shoveComponents,0,(void *)&widget.ui);
7255 iter[3] = widget.ub[0];
7256 iter[2] = widget.ub[1];
7257 iter[1] = widget.ub[2];
7258 iter[0] = widget.ub[3];
7260 *(GLuint *)iter= widget.ui;
7263 case GL_UNSIGNED_INT_10_10_10_2:
7264 for (k = 0; k < 4; k++) {
7265 shoveComponents[k]= *iter2++ / 65535.0;
7267 shove1010102(shoveComponents,0,(void *)&widget.ui);
7269 iter[3] = widget.ub[0];
7270 iter[2] = widget.ub[1];
7271 iter[1] = widget.ub[2];
7272 iter[0] = widget.ub[3];
7274 *(GLuint *)iter= widget.ui;
7277 case GL_UNSIGNED_INT_2_10_10_10_REV:
7278 for (k = 0; k < 4; k++) {
7279 shoveComponents[k]= *iter2++ / 65535.0;
7281 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
7283 iter[3] = widget.ub[0];
7284 iter[2] = widget.ub[1];
7285 iter[1] = widget.ub[2];
7286 iter[0] = widget.ub[3];
7288 *(GLuint *)iter= widget.ui;
7292 case GL_UNSIGNED_INT:
7294 if (type == GL_FLOAT) {
7296 widget.f = *iter2++;
7298 widget.f = *iter2++ / (float) 65535.0;
7300 } else if (type == GL_UNSIGNED_INT) {
7302 widget.ui = *iter2++;
7304 widget.ui = (unsigned int) *iter2++ * 65537;
7308 widget.i = *iter2++;
7310 widget.i = ((unsigned int) *iter2++ * 65537)/2;
7314 iter[3] = widget.ub[0];
7315 iter[2] = widget.ub[1];
7316 iter[1] = widget.ub[2];
7317 iter[0] = widget.ub[3];
7319 iter[0] = widget.ub[0];
7320 iter[1] = widget.ub[1];
7321 iter[2] = widget.ub[2];
7322 iter[3] = widget.ub[3];
7338 /* iterators should be one byte past end */
7339 if (!isTypePackedPixel(type)) {
7340 assert(iter2 == &oldImage[width*height*depth*components]);
7343 assert(iter2 == &oldImage[width*height*depth*
7344 elements_per_group(format,0)]);
7346 assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
7347 psm->unpack_skip_rows * rowSize +
7348 psm->unpack_skip_pixels * groupSize +
7350 psm->unpack_skip_images * imageSize] );
7351 } /* emptyImage3D() */
7354 int gluScaleImage3D(GLenum format,
7355 GLint widthIn, GLint heightIn, GLint depthIn,
7356 GLenum typeIn, const void *dataIn,
7357 GLint widthOut, GLint heightOut, GLint depthOut,
7358 GLenum typeOut, void *dataOut)
7361 GLushort *beforeImage, *afterImage;
7362 PixelStorageModes psm;
7364 if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
7365 widthOut == 0 || heightOut == 0 || depthOut == 0) {
7369 if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
7370 widthOut < 0 || heightOut < 0 || depthOut < 0) {
7371 return GLU_INVALID_VALUE;
7374 if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
7375 typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
7376 return GLU_INVALID_ENUM;
7378 if (!isLegalFormatForPackedPixelType(format, typeIn)) {
7379 return GLU_INVALID_OPERATION;
7381 if (!isLegalFormatForPackedPixelType(format, typeOut)) {
7382 return GLU_INVALID_OPERATION;
7385 beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
7386 GL_UNSIGNED_SHORT));
7387 afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
7388 GL_UNSIGNED_SHORT));
7389 if (beforeImage == NULL || afterImage == NULL) {
7392 return GLU_OUT_OF_MEMORY;
7394 retrieveStoreModes3D(&psm);
7396 fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
7397 dataIn, beforeImage);
7398 components = elements_per_group(format,0);
7399 scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
7400 widthOut,heightOut,depthOut,afterImage);
7401 emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
7402 is_index(format),afterImage, dataOut);
7403 free((void *) beforeImage);
7404 free((void *) afterImage);
7407 } /* gluScaleImage3D() */
7410 static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
7411 GLint internalFormat, GLenum format, GLenum type,
7412 GLint *newWidth, GLint *newHeight, GLint *newDepth)
7414 GLint widthPowerOf2= nearestPower(width);
7415 GLint heightPowerOf2= nearestPower(height);
7416 GLint depthPowerOf2= nearestPower(depth);
7420 /* compute level 1 width & height & depth, clamping each at 1 */
7421 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
7422 widthPowerOf2 >> 1 :
7424 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
7425 heightPowerOf2 >> 1 :
7427 GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
7428 depthPowerOf2 >> 1 :
7430 GLenum proxyTarget = GL_PROXY_TEXTURE_3D;
7431 assert(widthAtLevelOne > 0);
7432 assert(heightAtLevelOne > 0);
7433 assert(depthAtLevelOne > 0);
7435 /* does width x height x depth at level 1 & all their mipmaps fit? */
7436 assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D);
7437 gluTexImage3D(proxyTarget, 1, /* must be non-zero */
7439 widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
7440 0,format,type,NULL);
7441 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
7442 /* does it fit??? */
7443 if (proxyWidth == 0) { /* nope, so try again with these sizes */
7444 if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
7445 depthPowerOf2 == 1) {
7446 *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
7449 widthPowerOf2= widthAtLevelOne;
7450 heightPowerOf2= heightAtLevelOne;
7451 depthPowerOf2= depthAtLevelOne;
7453 /* else it does fit */
7454 } while (proxyWidth == 0);
7455 /* loop must terminate! */
7457 /* return the width & height at level 0 that fits */
7458 *newWidth= widthPowerOf2;
7459 *newHeight= heightPowerOf2;
7460 *newDepth= depthPowerOf2;
7461 /*printf("Proxy Textures\n");*/
7462 } /* closestFit3D() */
7464 static void halveImagePackedPixelSlice(int components,
7465 void (*extractPackedPixel)
7466 (int, const void *,GLfloat []),
7467 void (*shovePackedPixel)
7468 (const GLfloat [],int, void *),
7469 GLint width, GLint height, GLint depth,
7470 const void *dataIn, void *dataOut,
7471 GLint pixelSizeInBytes,
7472 GLint rowSizeInBytes,
7473 GLint imageSizeInBytes,
7477 int halfWidth= width / 2;
7478 int halfHeight= height / 2;
7479 int halfDepth= depth / 2;
7480 const char *src= (const char *)dataIn;
7483 assert((width == 1 || height == 1) && depth >= 2);
7485 if (width == height) { /* a 1-pixel column viewed from top */
7486 assert(width == 1 && height == 1);
7489 for (ii= 0; ii< halfDepth; ii++) {
7491 float extractTotals[BOX2][4];
7494 (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
7495 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7496 &extractTotals[1][0]);
7497 for (cc = 0; cc < components; cc++) {
7500 /* average 2 pixels since only a column */
7502 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7503 * totals[RED]/= 2.0;
7505 for (kk = 0; kk < BOX2; kk++) {
7506 totals[cc]+= extractTotals[kk][cc];
7508 totals[cc]/= (float)BOX2;
7511 (*shovePackedPixel)(totals,outIndex,dataOut);
7513 /* skip over to next group of 2 */
7514 src+= imageSizeInBytes + imageSizeInBytes;
7517 else if (height == 1) { /* horizontal slice viewed from top */
7520 for (ii= 0; ii< halfDepth; ii++) {
7521 for (jj= 0; jj< halfWidth; jj++) {
7523 float extractTotals[BOX4][4];
7526 (*extractPackedPixel)(isSwap,src,
7527 &extractTotals[0][0]);
7528 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7529 &extractTotals[1][0]);
7530 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7531 &extractTotals[2][0]);
7532 (*extractPackedPixel)(isSwap,
7533 (src+imageSizeInBytes+pixelSizeInBytes),
7534 &extractTotals[3][0]);
7535 for (cc = 0; cc < components; cc++) {
7538 /* grab 4 pixels to average */
7540 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7541 * extractTotals[2][RED]+extractTotals[3][RED];
7542 * totals[RED]/= 4.0;
7544 for (kk = 0; kk < BOX4; kk++) {
7545 totals[cc]+= extractTotals[kk][cc];
7547 totals[cc]/= (float)BOX4;
7549 (*shovePackedPixel)(totals,outIndex,dataOut);
7552 /* skip over to next horizontal square of 4 */
7553 src+= imageSizeInBytes + imageSizeInBytes;
7559 else if (width == 1) { /* vertical slice viewed from top */
7560 assert(height != 1);
7562 for (ii= 0; ii< halfDepth; ii++) {
7563 for (jj= 0; jj< halfHeight; jj++) {
7565 float extractTotals[BOX4][4];
7568 (*extractPackedPixel)(isSwap,src,
7569 &extractTotals[0][0]);
7570 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7571 &extractTotals[1][0]);
7572 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7573 &extractTotals[2][0]);
7574 (*extractPackedPixel)(isSwap,
7575 (src+imageSizeInBytes+rowSizeInBytes),
7576 &extractTotals[3][0]);
7577 for (cc = 0; cc < components; cc++) {
7580 /* grab 4 pixels to average */
7582 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7583 * extractTotals[2][RED]+extractTotals[3][RED];
7584 * totals[RED]/= 4.0;
7586 for (kk = 0; kk < BOX4; kk++) {
7587 totals[cc]+= extractTotals[kk][cc];
7589 totals[cc]/= (float)BOX4;
7591 (*shovePackedPixel)(totals,outIndex,dataOut);
7595 /* skip over to next vertical square of 4 */
7596 src+= imageSizeInBytes + imageSizeInBytes;
7602 } /* halveImagePackedPixelSlice() */
7604 static void halveImagePackedPixel3D(int components,
7605 void (*extractPackedPixel)
7606 (int, const void *,GLfloat []),
7607 void (*shovePackedPixel)
7608 (const GLfloat [],int, void *),
7609 GLint width, GLint height, GLint depth,
7610 const void *dataIn, void *dataOut,
7611 GLint pixelSizeInBytes,
7612 GLint rowSizeInBytes,
7613 GLint imageSizeInBytes,
7617 assert(1 <= width && 1 <= height);
7619 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
7620 width,height,dataIn,dataOut,pixelSizeInBytes,
7621 rowSizeInBytes,isSwap);
7624 /* a horizontal or vertical slice viewed from top */
7625 else if (width == 1 || height == 1) {
7628 halveImagePackedPixelSlice(components,
7629 extractPackedPixel,shovePackedPixel,
7630 width, height, depth, dataIn, dataOut,
7631 pixelSizeInBytes, rowSizeInBytes,
7632 imageSizeInBytes, isSwap);
7638 int halfWidth= width / 2;
7639 int halfHeight= height / 2;
7640 int halfDepth= depth / 2;
7641 const char *src= (const char *) dataIn;
7642 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
7645 for (dd= 0; dd < halfDepth; dd++) {
7646 for (ii= 0; ii< halfHeight; ii++) {
7647 for (jj= 0; jj< halfWidth; jj++) {
7649 float totals[4]; /* 4 is maximum components */
7650 float extractTotals[BOX8][4]; /* 4 is maximum components */
7653 (*extractPackedPixel)(isSwap,src,
7654 &extractTotals[0][0]);
7655 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7656 &extractTotals[1][0]);
7657 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7658 &extractTotals[2][0]);
7659 (*extractPackedPixel)(isSwap,
7660 (src+rowSizeInBytes+pixelSizeInBytes),
7661 &extractTotals[3][0]);
7663 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7664 &extractTotals[4][0]);
7665 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
7666 &extractTotals[5][0]);
7667 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
7668 &extractTotals[6][0]);
7669 (*extractPackedPixel)(isSwap,
7670 (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
7671 &extractTotals[7][0]);
7672 for (cc = 0; cc < components; cc++) {
7675 /* grab 8 pixels to average */
7677 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7678 * extractTotals[2][RED]+extractTotals[3][RED]+
7679 * extractTotals[4][RED]+extractTotals[5][RED]+
7680 * extractTotals[6][RED]+extractTotals[7][RED];
7681 * totals[RED]/= 8.0;
7683 for (kk = 0; kk < BOX8; kk++) {
7684 totals[cc]+= extractTotals[kk][cc];
7686 totals[cc]/= (float)BOX8;
7688 (*shovePackedPixel)(totals,outIndex,dataOut);
7691 /* skip over to next square of 4 */
7692 src+= pixelSizeInBytes + pixelSizeInBytes;
7694 /* skip past pad bytes, if any, to get to next row */
7697 /* src is at beginning of a row here, but it's the second row of
7698 * the square block of 4 pixels that we just worked on so we
7699 * need to go one more row.
7707 src+= rowSizeInBytes;
7710 src+= imageSizeInBytes;
7713 /* both pointers must reach one byte after the end */
7714 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
7715 assert(outIndex == halfWidth * halfHeight * halfDepth);
7718 } /* halveImagePackedPixel3D() */
7720 static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
7724 GLsizei widthPowerOf2,
7725 GLsizei heightPowerOf2,
7726 GLsizei depthPowerOf2,
7727 GLenum format, GLenum type,
7729 GLint baseLevel,GLint maxLevel,
7732 GLint newWidth, newHeight, newDepth;
7733 GLint level, levels;
7734 const void *usersImage;
7735 void *srcImage, *dstImage;
7736 __GLU_INIT_SWAP_IMAGE;
7740 GLint myswapBytes, groupsPerLine, elementSize, groupSize;
7741 GLint rowsPerImage, imageSize;
7742 GLint rowSize, padding;
7743 PixelStorageModes psm;
7745 assert(checkMipmapArgs(internalFormat,format,type) == 0);
7746 assert(width >= 1 && height >= 1 && depth >= 1);
7747 assert(type != GL_BITMAP);
7749 srcImage = dstImage = NULL;
7751 newWidth= widthPowerOf2;
7752 newHeight= heightPowerOf2;
7753 newDepth= depthPowerOf2;
7754 levels = computeLog(newWidth);
7755 level = computeLog(newHeight);
7756 if (level > levels) levels=level;
7757 level = computeLog(newDepth);
7758 if (level > levels) levels=level;
7762 retrieveStoreModes3D(&psm);
7763 myswapBytes = psm.unpack_swap_bytes;
7764 cmpts = elements_per_group(format,type);
7765 if (psm.unpack_row_length > 0) {
7766 groupsPerLine = psm.unpack_row_length;
7768 groupsPerLine = width;
7771 elementSize = bytes_per_element(type);
7772 groupSize = elementSize * cmpts;
7773 if (elementSize == 1) myswapBytes = 0;
7776 if (psm.unpack_image_height > 0) {
7777 rowsPerImage= psm.unpack_image_height;
7780 rowsPerImage= height;
7784 rowSize = groupsPerLine * groupSize;
7785 padding = (rowSize % psm.unpack_alignment);
7787 rowSize += psm.unpack_alignment - padding;
7790 imageSize= rowsPerImage * rowSize; /* 3dstuff */
7792 usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
7793 psm.unpack_skip_pixels * groupSize +
7795 psm.unpack_skip_images * imageSize;
7797 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
7798 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
7799 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
7800 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
7801 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
7805 if (width == newWidth && height == newHeight && depth == newDepth) {
7806 /* Use usersImage for level userLevel */
7807 if (baseLevel <= level && level <= maxLevel) {
7808 gluTexImage3D(target, level, internalFormat, width,
7809 height, depth, 0, format, type,
7812 if(levels == 0) { /* we're done. clean up and return */
7813 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7814 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7815 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7816 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7817 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7818 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7819 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7823 int nextWidth= newWidth/2;
7824 int nextHeight= newHeight/2;
7825 int nextDepth= newDepth/2;
7828 if (nextWidth < 1) nextWidth= 1;
7829 if (nextHeight < 1) nextHeight= 1;
7830 if (nextDepth < 1) nextDepth= 1;
7831 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
7834 case GL_UNSIGNED_BYTE:
7835 dstImage = (GLubyte *)malloc(memReq);
7838 dstImage = (GLbyte *)malloc(memReq);
7840 case GL_UNSIGNED_SHORT:
7841 dstImage = (GLushort *)malloc(memReq);
7844 dstImage = (GLshort *)malloc(memReq);
7846 case GL_UNSIGNED_INT:
7847 dstImage = (GLuint *)malloc(memReq);
7850 dstImage = (GLint *)malloc(memReq);
7853 dstImage = (GLfloat *)malloc(memReq);
7855 case GL_UNSIGNED_BYTE_3_3_2:
7856 case GL_UNSIGNED_BYTE_2_3_3_REV:
7857 dstImage = (GLubyte *)malloc(memReq);
7859 case GL_UNSIGNED_SHORT_5_6_5:
7860 case GL_UNSIGNED_SHORT_5_6_5_REV:
7861 case GL_UNSIGNED_SHORT_4_4_4_4:
7862 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7863 case GL_UNSIGNED_SHORT_5_5_5_1:
7864 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7865 dstImage = (GLushort *)malloc(memReq);
7867 case GL_UNSIGNED_INT_8_8_8_8:
7868 case GL_UNSIGNED_INT_8_8_8_8_REV:
7869 case GL_UNSIGNED_INT_10_10_10_2:
7870 case GL_UNSIGNED_INT_2_10_10_10_REV:
7871 dstImage = (GLuint *)malloc(memReq);
7874 return GLU_INVALID_ENUM; /* assertion */
7876 if (dstImage == NULL) {
7877 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7878 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7879 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7880 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7881 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7882 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7883 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7884 return GLU_OUT_OF_MEMORY;
7888 case GL_UNSIGNED_BYTE:
7890 halveImage3D(cmpts,extractUbyte,shoveUbyte,
7892 usersImage,dstImage,elementSize,groupSize,rowSize,
7893 imageSize,myswapBytes);
7896 halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
7897 elementSize,rowSize,groupSize);
7902 halveImage3D(cmpts,extractSbyte,shoveSbyte,
7904 usersImage,dstImage,elementSize,groupSize,rowSize,
7905 imageSize,myswapBytes);
7908 halveImage_byte(cmpts,width,height,usersImage,dstImage,
7909 elementSize,rowSize,groupSize);
7912 case GL_UNSIGNED_SHORT:
7914 halveImage3D(cmpts,extractUshort,shoveUshort,
7916 usersImage,dstImage,elementSize,groupSize,rowSize,
7917 imageSize,myswapBytes);
7920 halveImage_ushort(cmpts,width,height,usersImage,dstImage,
7921 elementSize,rowSize,groupSize,myswapBytes);
7926 halveImage3D(cmpts,extractSshort,shoveSshort,
7928 usersImage,dstImage,elementSize,groupSize,rowSize,
7929 imageSize,myswapBytes);
7932 halveImage_short(cmpts,width,height,usersImage,dstImage,
7933 elementSize,rowSize,groupSize,myswapBytes);
7936 case GL_UNSIGNED_INT:
7938 halveImage3D(cmpts,extractUint,shoveUint,
7940 usersImage,dstImage,elementSize,groupSize,rowSize,
7941 imageSize,myswapBytes);
7944 halveImage_uint(cmpts,width,height,usersImage,dstImage,
7945 elementSize,rowSize,groupSize,myswapBytes);
7950 halveImage3D(cmpts,extractSint,shoveSint,
7952 usersImage,dstImage,elementSize,groupSize,rowSize,
7953 imageSize,myswapBytes);
7956 halveImage_int(cmpts,width,height,usersImage,dstImage,
7957 elementSize,rowSize,groupSize,myswapBytes);
7962 halveImage3D(cmpts,extractFloat,shoveFloat,
7964 usersImage,dstImage,elementSize,groupSize,rowSize,
7965 imageSize,myswapBytes);
7968 halveImage_float(cmpts,width,height,usersImage,dstImage,
7969 elementSize,rowSize,groupSize,myswapBytes);
7972 case GL_UNSIGNED_BYTE_3_3_2:
7973 assert(format == GL_RGB);
7974 halveImagePackedPixel3D(3,extract332,shove332,
7975 width,height,depth,usersImage,dstImage,
7976 elementSize,rowSize,imageSize,myswapBytes);
7978 case GL_UNSIGNED_BYTE_2_3_3_REV:
7979 assert(format == GL_RGB);
7980 halveImagePackedPixel3D(3,extract233rev,shove233rev,
7981 width,height,depth,usersImage,dstImage,
7982 elementSize,rowSize,imageSize,myswapBytes);
7984 case GL_UNSIGNED_SHORT_5_6_5:
7985 halveImagePackedPixel3D(3,extract565,shove565,
7986 width,height,depth,usersImage,dstImage,
7987 elementSize,rowSize,imageSize,myswapBytes);
7989 case GL_UNSIGNED_SHORT_5_6_5_REV:
7990 halveImagePackedPixel3D(3,extract565rev,shove565rev,
7991 width,height,depth,usersImage,dstImage,
7992 elementSize,rowSize,imageSize,myswapBytes);
7994 case GL_UNSIGNED_SHORT_4_4_4_4:
7995 halveImagePackedPixel3D(4,extract4444,shove4444,
7996 width,height,depth,usersImage,dstImage,
7997 elementSize,rowSize,imageSize,myswapBytes);
7999 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8000 halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8001 width,height,depth,usersImage,dstImage,
8002 elementSize,rowSize,imageSize,myswapBytes);
8004 case GL_UNSIGNED_SHORT_5_5_5_1:
8005 halveImagePackedPixel3D(4,extract5551,shove5551,
8006 width,height,depth,usersImage,dstImage,
8007 elementSize,rowSize,imageSize,myswapBytes);
8009 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8010 halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8011 width,height,depth,usersImage,dstImage,
8012 elementSize,rowSize,imageSize,myswapBytes);
8014 case GL_UNSIGNED_INT_8_8_8_8:
8015 halveImagePackedPixel3D(4,extract8888,shove8888,
8016 width,height,depth,usersImage,dstImage,
8017 elementSize,rowSize,imageSize,myswapBytes);
8019 case GL_UNSIGNED_INT_8_8_8_8_REV:
8020 halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8021 width,height,depth,usersImage,dstImage,
8022 elementSize,rowSize,imageSize,myswapBytes);
8024 case GL_UNSIGNED_INT_10_10_10_2:
8025 halveImagePackedPixel3D(4,extract1010102,shove1010102,
8026 width,height,depth,usersImage,dstImage,
8027 elementSize,rowSize,imageSize,myswapBytes);
8029 case GL_UNSIGNED_INT_2_10_10_10_REV:
8030 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8031 width,height,depth,usersImage,dstImage,
8032 elementSize,rowSize,imageSize,myswapBytes);
8039 newHeight = height/2;
8042 if (newWidth < 1) newWidth= 1;
8043 if (newHeight < 1) newHeight= 1;
8044 if (newDepth < 1) newDepth= 1;
8047 rowSize = newWidth * groupSize;
8048 imageSize= rowSize * newHeight; /* 3dstuff */
8049 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8050 /* Swap srcImage and dstImage */
8051 __GLU_SWAP_IMAGE(srcImage,dstImage);
8053 case GL_UNSIGNED_BYTE:
8054 dstImage = (GLubyte *)malloc(memReq);
8057 dstImage = (GLbyte *)malloc(memReq);
8059 case GL_UNSIGNED_SHORT:
8060 dstImage = (GLushort *)malloc(memReq);
8063 dstImage = (GLshort *)malloc(memReq);
8065 case GL_UNSIGNED_INT:
8066 dstImage = (GLuint *)malloc(memReq);
8069 dstImage = (GLint *)malloc(memReq);
8072 dstImage = (GLfloat *)malloc(memReq);
8074 case GL_UNSIGNED_BYTE_3_3_2:
8075 case GL_UNSIGNED_BYTE_2_3_3_REV:
8076 dstImage = (GLubyte *)malloc(memReq);
8078 case GL_UNSIGNED_SHORT_5_6_5:
8079 case GL_UNSIGNED_SHORT_5_6_5_REV:
8080 case GL_UNSIGNED_SHORT_4_4_4_4:
8081 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8082 case GL_UNSIGNED_SHORT_5_5_5_1:
8083 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8084 dstImage = (GLushort *)malloc(memReq);
8086 case GL_UNSIGNED_INT_8_8_8_8:
8087 case GL_UNSIGNED_INT_8_8_8_8_REV:
8088 case GL_UNSIGNED_INT_10_10_10_2:
8089 case GL_UNSIGNED_INT_2_10_10_10_REV:
8090 dstImage = (GLuint *)malloc(memReq);
8093 return GLU_INVALID_ENUM; /* assertion */
8095 if (dstImage == NULL) {
8096 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8097 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8098 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8099 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8100 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8101 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8102 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8104 return GLU_OUT_OF_MEMORY;
8106 /* level userLevel+1 is in srcImage; level userLevel already saved */
8107 level = userLevel+1;
8108 } else {/* user's image is *not* nice power-of-2 sized square */
8109 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8111 case GL_UNSIGNED_BYTE:
8112 dstImage = (GLubyte *)malloc(memReq);
8115 dstImage = (GLbyte *)malloc(memReq);
8117 case GL_UNSIGNED_SHORT:
8118 dstImage = (GLushort *)malloc(memReq);
8121 dstImage = (GLshort *)malloc(memReq);
8123 case GL_UNSIGNED_INT:
8124 dstImage = (GLuint *)malloc(memReq);
8127 dstImage = (GLint *)malloc(memReq);
8130 dstImage = (GLfloat *)malloc(memReq);
8132 case GL_UNSIGNED_BYTE_3_3_2:
8133 case GL_UNSIGNED_BYTE_2_3_3_REV:
8134 dstImage = (GLubyte *)malloc(memReq);
8136 case GL_UNSIGNED_SHORT_5_6_5:
8137 case GL_UNSIGNED_SHORT_5_6_5_REV:
8138 case GL_UNSIGNED_SHORT_4_4_4_4:
8139 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8140 case GL_UNSIGNED_SHORT_5_5_5_1:
8141 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8142 dstImage = (GLushort *)malloc(memReq);
8144 case GL_UNSIGNED_INT_8_8_8_8:
8145 case GL_UNSIGNED_INT_8_8_8_8_REV:
8146 case GL_UNSIGNED_INT_10_10_10_2:
8147 case GL_UNSIGNED_INT_2_10_10_10_REV:
8148 dstImage = (GLuint *)malloc(memReq);
8151 return GLU_INVALID_ENUM; /* assertion */
8154 if (dstImage == NULL) {
8155 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8156 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8157 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8158 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8159 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8160 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8161 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8162 return GLU_OUT_OF_MEMORY;
8164 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8165 width,height,depth,newWidth,newHeight,newDepth);*/
8167 gluScaleImage3D(format, width, height, depth, type, usersImage,
8168 newWidth, newHeight, newDepth, type, dstImage);
8171 rowSize = newWidth * groupSize;
8172 imageSize = rowSize * newHeight; /* 3dstuff */
8173 /* Swap dstImage and srcImage */
8174 __GLU_SWAP_IMAGE(srcImage,dstImage);
8176 if(levels != 0) { /* use as little memory as possible */
8178 int nextWidth= newWidth/2;
8179 int nextHeight= newHeight/2;
8180 int nextDepth= newDepth/2;
8181 if (nextWidth < 1) nextWidth= 1;
8182 if (nextHeight < 1) nextHeight= 1;
8183 if (nextDepth < 1) nextDepth= 1;
8185 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
8188 case GL_UNSIGNED_BYTE:
8189 dstImage = (GLubyte *)malloc(memReq);
8192 dstImage = (GLbyte *)malloc(memReq);
8194 case GL_UNSIGNED_SHORT:
8195 dstImage = (GLushort *)malloc(memReq);
8198 dstImage = (GLshort *)malloc(memReq);
8200 case GL_UNSIGNED_INT:
8201 dstImage = (GLuint *)malloc(memReq);
8204 dstImage = (GLint *)malloc(memReq);
8207 dstImage = (GLfloat *)malloc(memReq);
8209 case GL_UNSIGNED_BYTE_3_3_2:
8210 case GL_UNSIGNED_BYTE_2_3_3_REV:
8211 dstImage = (GLubyte *)malloc(memReq);
8213 case GL_UNSIGNED_SHORT_5_6_5:
8214 case GL_UNSIGNED_SHORT_5_6_5_REV:
8215 case GL_UNSIGNED_SHORT_4_4_4_4:
8216 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8217 case GL_UNSIGNED_SHORT_5_5_5_1:
8218 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8219 dstImage = (GLushort *)malloc(memReq);
8221 case GL_UNSIGNED_INT_8_8_8_8:
8222 case GL_UNSIGNED_INT_8_8_8_8_REV:
8223 case GL_UNSIGNED_INT_10_10_10_2:
8224 case GL_UNSIGNED_INT_2_10_10_10_REV:
8225 dstImage = (GLuint *)malloc(memReq);
8228 return GLU_INVALID_ENUM; /* assertion */
8230 if (dstImage == NULL) {
8231 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8232 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8233 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8234 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8235 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8236 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8237 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8239 return GLU_OUT_OF_MEMORY;
8242 /* level userLevel is in srcImage; nothing saved yet */
8246 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
8247 if (baseLevel <= level && level <= maxLevel) {
8248 gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
8249 0,format, type, (void *)srcImage);
8251 level++; /* update current level for the loop */
8252 for (; level <= levels; level++) {
8254 case GL_UNSIGNED_BYTE:
8256 halveImage3D(cmpts,extractUbyte,shoveUbyte,
8257 newWidth,newHeight,newDepth,
8258 srcImage,dstImage,elementSize,groupSize,rowSize,
8259 imageSize,myswapBytes);
8262 halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
8263 elementSize,rowSize,groupSize);
8268 halveImage3D(cmpts,extractSbyte,shoveSbyte,
8269 newWidth,newHeight,newDepth,
8270 srcImage,dstImage,elementSize,groupSize,rowSize,
8271 imageSize,myswapBytes);
8274 halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
8275 elementSize,rowSize,groupSize);
8278 case GL_UNSIGNED_SHORT:
8280 halveImage3D(cmpts,extractUshort,shoveUshort,
8281 newWidth,newHeight,newDepth,
8282 srcImage,dstImage,elementSize,groupSize,rowSize,
8283 imageSize,myswapBytes);
8286 halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
8287 elementSize,rowSize,groupSize,myswapBytes);
8292 halveImage3D(cmpts,extractSshort,shoveSshort,
8293 newWidth,newHeight,newDepth,
8294 srcImage,dstImage,elementSize,groupSize,rowSize,
8295 imageSize,myswapBytes);
8298 halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
8299 elementSize,rowSize,groupSize,myswapBytes);
8302 case GL_UNSIGNED_INT:
8304 halveImage3D(cmpts,extractUint,shoveUint,
8305 newWidth,newHeight,newDepth,
8306 srcImage,dstImage,elementSize,groupSize,rowSize,
8307 imageSize,myswapBytes);
8310 halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
8311 elementSize,rowSize,groupSize,myswapBytes);
8316 halveImage3D(cmpts,extractSint,shoveSint,
8317 newWidth,newHeight,newDepth,
8318 srcImage,dstImage,elementSize,groupSize,rowSize,
8319 imageSize,myswapBytes);
8322 halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
8323 elementSize,rowSize,groupSize,myswapBytes);
8328 halveImage3D(cmpts,extractFloat,shoveFloat,
8329 newWidth,newHeight,newDepth,
8330 srcImage,dstImage,elementSize,groupSize,rowSize,
8331 imageSize,myswapBytes);
8334 halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
8335 elementSize,rowSize,groupSize,myswapBytes);
8338 case GL_UNSIGNED_BYTE_3_3_2:
8339 halveImagePackedPixel3D(3,extract332,shove332,
8340 newWidth,newHeight,newDepth,
8341 srcImage,dstImage,elementSize,rowSize,
8342 imageSize,myswapBytes);
8344 case GL_UNSIGNED_BYTE_2_3_3_REV:
8345 halveImagePackedPixel3D(3,extract233rev,shove233rev,
8346 newWidth,newHeight,newDepth,
8347 srcImage,dstImage,elementSize,rowSize,
8348 imageSize,myswapBytes);
8350 case GL_UNSIGNED_SHORT_5_6_5:
8351 halveImagePackedPixel3D(3,extract565,shove565,
8352 newWidth,newHeight,newDepth,
8353 srcImage,dstImage,elementSize,rowSize,
8354 imageSize,myswapBytes);
8356 case GL_UNSIGNED_SHORT_5_6_5_REV:
8357 halveImagePackedPixel3D(3,extract565rev,shove565rev,
8358 newWidth,newHeight,newDepth,
8359 srcImage,dstImage,elementSize,rowSize,
8360 imageSize,myswapBytes);
8362 case GL_UNSIGNED_SHORT_4_4_4_4:
8363 halveImagePackedPixel3D(4,extract4444,shove4444,
8364 newWidth,newHeight,newDepth,
8365 srcImage,dstImage,elementSize,rowSize,
8366 imageSize,myswapBytes);
8368 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8369 halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8370 newWidth,newHeight,newDepth,
8371 srcImage,dstImage,elementSize,rowSize,
8372 imageSize,myswapBytes);
8374 case GL_UNSIGNED_SHORT_5_5_5_1:
8375 halveImagePackedPixel3D(4,extract5551,shove5551,
8376 newWidth,newHeight,newDepth,
8377 srcImage,dstImage,elementSize,rowSize,
8378 imageSize,myswapBytes);
8380 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8381 halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8382 newWidth,newHeight,newDepth,
8383 srcImage,dstImage,elementSize,rowSize,
8384 imageSize,myswapBytes);
8386 case GL_UNSIGNED_INT_8_8_8_8:
8387 halveImagePackedPixel3D(4,extract8888,shove8888,
8388 newWidth,newHeight,newDepth,
8389 srcImage,dstImage,elementSize,rowSize,
8390 imageSize,myswapBytes);
8392 case GL_UNSIGNED_INT_8_8_8_8_REV:
8393 halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8394 newWidth,newHeight,newDepth,
8395 srcImage,dstImage,elementSize,rowSize,
8396 imageSize,myswapBytes);
8398 case GL_UNSIGNED_INT_10_10_10_2:
8399 halveImagePackedPixel3D(4,extract1010102,shove1010102,
8400 newWidth,newHeight,newDepth,
8401 srcImage,dstImage,elementSize,rowSize,
8402 imageSize,myswapBytes);
8404 case GL_UNSIGNED_INT_2_10_10_10_REV:
8405 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8406 newWidth,newHeight,newDepth,
8407 srcImage,dstImage,elementSize,rowSize,
8408 imageSize,myswapBytes);
8415 __GLU_SWAP_IMAGE(srcImage,dstImage);
8417 if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
8418 if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
8419 if (newDepth > 1) newDepth /= 2;
8421 /* call tex image with srcImage untouched since it's not padded */
8422 if (baseLevel <= level && level <= maxLevel) {
8423 gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
8424 newDepth,0, format, type, (void *) srcImage);
8428 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8429 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8430 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8431 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8432 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8433 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8434 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8436 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
8437 if (dstImage) { /* if it's non-rectangular and only 1 level */
8441 } /* gluBuild3DMipmapLevelsCore() */
8444 gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
8445 GLsizei width, GLsizei height, GLsizei depth,
8446 GLenum format, GLenum type,
8447 GLint userLevel, GLint baseLevel, GLint maxLevel,
8452 int rc= checkMipmapArgs(internalFormat,format,type);
8453 if (rc != 0) return rc;
8455 if (width < 1 || height < 1 || depth < 1) {
8456 return GLU_INVALID_VALUE;
8459 if(type == GL_BITMAP) {
8460 return GLU_INVALID_ENUM;
8463 levels = computeLog(width);
8464 level = computeLog(height);
8465 if (level > levels) levels=level;
8466 level = computeLog(depth);
8467 if (level > levels) levels=level;
8470 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
8471 return GLU_INVALID_VALUE;
8473 return gluBuild3DMipmapLevelsCore(target, internalFormat,
8474 width, height, depth,
8475 width, height, depth,
8477 userLevel, baseLevel, maxLevel,
8479 } /* gluBuild3DMipmapLevels() */
8482 gluBuild3DMipmaps(GLenum target, GLint internalFormat,
8483 GLsizei width, GLsizei height, GLsizei depth,
8484 GLenum format, GLenum type, const void *data)
8486 GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
8489 int rc= checkMipmapArgs(internalFormat,format,type);
8490 if (rc != 0) return rc;
8492 if (width < 1 || height < 1 || depth < 1) {
8493 return GLU_INVALID_VALUE;
8496 if(type == GL_BITMAP) {
8497 return GLU_INVALID_ENUM;
8500 closestFit3D(target,width,height,depth,internalFormat,format,type,
8501 &widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
8503 levels = computeLog(widthPowerOf2);
8504 level = computeLog(heightPowerOf2);
8505 if (level > levels) levels=level;
8506 level = computeLog(depthPowerOf2);
8507 if (level > levels) levels=level;
8509 return gluBuild3DMipmapLevelsCore(target, internalFormat,
8510 width, height, depth,
8511 widthPowerOf2, heightPowerOf2,
8513 format, type, 0, 0, levels,
8515 } /* gluBuild3DMipmaps() */
8517 static GLdouble extractUbyte(int isSwap, const void *ubyte)
8519 isSwap= isSwap; /* turn off warnings */
8521 assert(*((const GLubyte *)ubyte) <= 255);
8523 return (GLdouble)(*((const GLubyte *)ubyte));
8524 } /* extractUbyte() */
8526 static void shoveUbyte(GLdouble value, int index, void *data)
8528 assert(0.0 <= value && value < 256.0);
8530 ((GLubyte *)data)[index]= (GLubyte)value;
8531 } /* shoveUbyte() */
8533 static GLdouble extractSbyte(int isSwap, const void *sbyte)
8535 isSwap= isSwap; /* turn off warnings */
8537 assert(*((const GLbyte *)sbyte) <= 127);
8539 return (GLdouble)(*((const GLbyte *)sbyte));
8540 } /* extractSbyte() */
8542 static void shoveSbyte(GLdouble value, int index, void *data)
8544 ((GLbyte *)data)[index]= (GLbyte)value;
8545 } /* shoveSbyte() */
8547 static GLdouble extractUshort(int isSwap, const void *uitem)
8552 ushort= __GLU_SWAP_2_BYTES(uitem);
8555 ushort= *(const GLushort *)uitem;
8558 assert(ushort <= 65535);
8560 return (GLdouble)ushort;
8561 } /* extractUshort() */
8563 static void shoveUshort(GLdouble value, int index, void *data)
8565 assert(0.0 <= value && value < 65536.0);
8567 ((GLushort *)data)[index]= (GLushort)value;
8568 } /* shoveUshort() */
8570 static GLdouble extractSshort(int isSwap, const void *sitem)
8575 sshort= __GLU_SWAP_2_BYTES(sitem);
8578 sshort= *(const GLshort *)sitem;
8581 assert(sshort <= 32767);
8583 return (GLdouble)sshort;
8584 } /* extractSshort() */
8586 static void shoveSshort(GLdouble value, int index, void *data)
8588 assert(0.0 <= value && value < 32768.0);
8590 ((GLshort *)data)[index]= (GLshort)value;
8591 } /* shoveSshort() */
8593 static GLdouble extractUint(int isSwap, const void *uitem)
8598 uint= __GLU_SWAP_4_BYTES(uitem);
8601 uint= *(const GLuint *)uitem;
8604 assert(uint <= 0xffffffff);
8606 return (GLdouble)uint;
8607 } /* extractUint() */
8609 static void shoveUint(GLdouble value, int index, void *data)
8611 assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
8613 ((GLuint *)data)[index]= (GLuint)value;
8616 static GLdouble extractSint(int isSwap, const void *sitem)
8621 sint= __GLU_SWAP_4_BYTES(sitem);
8624 sint= *(const GLint *)sitem;
8627 assert(sint <= 0x7fffffff);
8629 return (GLdouble)sint;
8630 } /* extractSint() */
8632 static void shoveSint(GLdouble value, int index, void *data)
8634 assert(0.0 <= value && value <= (GLdouble) INT_MAX);
8636 ((GLint *)data)[index]= (GLint)value;
8639 static GLdouble extractFloat(int isSwap, const void *item)
8644 ffloat= __GLU_SWAP_4_BYTES(item);
8647 ffloat= *(const GLfloat *)item;
8650 assert(ffloat <= 1.0);
8652 return (GLdouble)ffloat;
8653 } /* extractFloat() */
8655 static void shoveFloat(GLdouble value, int index, void *data)
8657 assert(0.0 <= value && value <= 1.0);
8659 ((GLfloat *)data)[index]= value;
8660 } /* shoveFloat() */
8662 static void halveImageSlice(int components,
8663 GLdouble (*extract)(int, const void *),
8664 void (*shove)(GLdouble, int, void *),
8665 GLint width, GLint height, GLint depth,
8666 const void *dataIn, void *dataOut,
8667 GLint elementSizeInBytes,
8668 GLint groupSizeInBytes,
8669 GLint rowSizeInBytes,
8670 GLint imageSizeInBytes,
8674 int halfWidth= width / 2;
8675 int halfHeight= height / 2;
8676 int halfDepth= depth / 2;
8677 const char *src= (const char *)dataIn;
8678 int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes);
8679 int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8682 assert((width == 1 || height == 1) && depth >= 2);
8684 if (width == height) { /* a 1-pixel column viewed from top */
8685 /* printf("1-column\n");*/
8686 assert(width == 1 && height == 1);
8689 for (ii= 0; ii< halfDepth; ii++) {
8692 for (cc = 0; cc < components; cc++) {
8694 double extractTotals[BOX2][4];
8697 extractTotals[0][cc]= (*extract)(isSwap,src);
8698 extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
8700 /* average 2 pixels since only a column */
8702 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8703 * totals[RED]/= 2.0;
8705 for (kk = 0; kk < BOX2; kk++) {
8706 totals[cc]+= extractTotals[kk][cc];
8708 totals[cc]/= (double)BOX2;
8710 (*shove)(totals[cc],outIndex,dataOut);
8712 src+= elementSizeInBytes;
8715 /* skip over to next group of 2 */
8716 src+= rowSizeInBytes;
8719 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8720 assert(outIndex == halfDepth * components);
8722 else if (height == 1) { /* horizontal slice viewed from top */
8723 /* printf("horizontal slice\n"); */
8726 for (ii= 0; ii< halfDepth; ii++) {
8727 for (jj= 0; jj< halfWidth; jj++) {
8730 for (cc = 0; cc < components; cc++) {
8733 double extractTotals[BOX4][4];
8735 extractTotals[0][cc]=(*extract)(isSwap,src);
8736 extractTotals[1][cc]=(*extract)(isSwap,
8737 (src+groupSizeInBytes));
8738 extractTotals[2][cc]=(*extract)(isSwap,
8739 (src+imageSizeInBytes));
8740 extractTotals[3][cc]=(*extract)(isSwap,
8741 (src+imageSizeInBytes+groupSizeInBytes));
8743 /* grab 4 pixels to average */
8745 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8746 * extractTotals[2][RED]+extractTotals[3][RED];
8747 * totals[RED]/= 4.0;
8749 for (kk = 0; kk < BOX4; kk++) {
8750 totals[cc]+= extractTotals[kk][cc];
8752 totals[cc]/= (double)BOX4;
8754 (*shove)(totals[cc],outIndex,dataOut);
8757 src+= elementSizeInBytes;
8760 /* skip over to next horizontal square of 4 */
8761 src+= groupSizeInBytes;
8765 src+= rowSizeInBytes;
8768 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8769 assert(outIndex == halfWidth * halfDepth * components);
8771 else if (width == 1) { /* vertical slice viewed from top */
8772 /* printf("vertical slice\n"); */
8773 assert(height != 1);
8775 for (ii= 0; ii< halfDepth; ii++) {
8776 for (jj= 0; jj< halfHeight; jj++) {
8779 for (cc = 0; cc < components; cc++) {
8782 double extractTotals[BOX4][4];
8784 extractTotals[0][cc]=(*extract)(isSwap,src);
8785 extractTotals[1][cc]=(*extract)(isSwap,
8786 (src+rowSizeInBytes));
8787 extractTotals[2][cc]=(*extract)(isSwap,
8788 (src+imageSizeInBytes));
8789 extractTotals[3][cc]=(*extract)(isSwap,
8790 (src+imageSizeInBytes+rowSizeInBytes));
8792 /* grab 4 pixels to average */
8794 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8795 * extractTotals[2][RED]+extractTotals[3][RED];
8796 * totals[RED]/= 4.0;
8798 for (kk = 0; kk < BOX4; kk++) {
8799 totals[cc]+= extractTotals[kk][cc];
8801 totals[cc]/= (double)BOX4;
8803 (*shove)(totals[cc],outIndex,dataOut);
8806 src+= elementSizeInBytes;
8810 /* skip over to next vertical square of 4 */
8811 src+= rowSizeInBytes;
8813 src+= imagePadBytes;
8815 src+= imageSizeInBytes;
8818 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8819 assert(outIndex == halfHeight * halfDepth * components);
8822 } /* halveImageSlice() */
8824 static void halveImage3D(int components,
8825 GLdouble (*extract)(int, const void *),
8826 void (*shove)(GLdouble, int, void *),
8827 GLint width, GLint height, GLint depth,
8828 const void *dataIn, void *dataOut,
8829 GLint elementSizeInBytes,
8830 GLint groupSizeInBytes,
8831 GLint rowSizeInBytes,
8832 GLint imageSizeInBytes,
8837 /* a horizontal/vertical/one-column slice viewed from top */
8838 if (width == 1 || height == 1) {
8841 halveImageSlice(components,extract,shove, width, height, depth,
8842 dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
8843 rowSizeInBytes, imageSizeInBytes, isSwap);
8849 int halfWidth= width / 2;
8850 int halfHeight= height / 2;
8851 int halfDepth= depth / 2;
8852 const char *src= (const char *) dataIn;
8853 int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes);
8854 int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8857 for (dd= 0; dd < halfDepth; dd++) {
8858 for (ii= 0; ii< halfHeight; ii++) {
8859 for (jj= 0; jj< halfWidth; jj++) {
8862 for (cc= 0; cc < components; cc++) {
8865 double totals[4]; /* 4 is maximum components */
8866 double extractTotals[BOX8][4]; /* 4 is maximum components */
8868 extractTotals[0][cc]= (*extract)(isSwap,src);
8869 extractTotals[1][cc]= (*extract)(isSwap,
8870 (src+groupSizeInBytes));
8871 extractTotals[2][cc]= (*extract)(isSwap,
8872 (src+rowSizeInBytes));
8873 extractTotals[3][cc]= (*extract)(isSwap,
8874 (src+rowSizeInBytes+groupSizeInBytes));
8876 extractTotals[4][cc]= (*extract)(isSwap,
8877 (src+imageSizeInBytes));
8879 extractTotals[5][cc]= (*extract)(isSwap,
8880 (src+groupSizeInBytes+imageSizeInBytes));
8881 extractTotals[6][cc]= (*extract)(isSwap,
8882 (src+rowSizeInBytes+imageSizeInBytes));
8883 extractTotals[7][cc]= (*extract)(isSwap,
8884 (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
8888 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8889 * extractTotals[2][RED]+extractTotals[3][RED]+
8890 * extractTotals[4][RED]+extractTotals[5][RED]+
8891 * extractTotals[6][RED]+extractTotals[7][RED];
8892 * totals[RED]/= 8.0;
8894 for (kk = 0; kk < BOX8; kk++) {
8895 totals[cc]+= extractTotals[kk][cc];
8897 totals[cc]/= (double)BOX8;
8899 (*shove)(totals[cc],outIndex,dataOut);
8903 src+= elementSizeInBytes; /* go to next component */
8906 /* skip over to next square of 4 */
8907 src+= groupSizeInBytes;
8909 /* skip past pad bytes, if any, to get to next row */
8912 /* src is at beginning of a row here, but it's the second row of
8913 * the square block of 4 pixels that we just worked on so we
8914 * need to go one more row.
8922 src+= rowSizeInBytes;
8925 /* skip past pad bytes, if any, to get to next image */
8926 src+= imagePadBytes;
8928 src+= imageSizeInBytes;
8931 /* both pointers must reach one byte after the end */
8932 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8933 assert(outIndex == halfWidth * halfHeight * halfDepth * components);
8935 } /* halveImage3D() */