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) {
3528 return GLU_OUT_OF_MEMORY;
3531 retrieveStoreModes(&psm);
3532 fill_image(&psm,widthin, heightin, format, typein, is_index(format),
3533 datain, beforeImage);
3534 components = elements_per_group(format, 0);
3535 scale_internal(components, widthin, heightin, beforeImage,
3536 widthout, heightout, afterImage);
3537 empty_image(&psm,widthout, heightout, format, typeout,
3538 is_index(format), afterImage, dataout);
3539 free((GLbyte *) beforeImage);
3540 free((GLbyte *) afterImage);
3545 int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
3547 GLsizei widthPowerOf2,
3548 GLenum format, GLenum type,
3549 GLint userLevel, GLint baseLevel,GLint maxLevel,
3553 GLint level, levels;
3555 GLint newImage_width;
3556 GLushort *otherImage;
3557 GLushort *imageTemp;
3560 PixelStorageModes psm;
3562 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3567 newwidth= widthPowerOf2;
3568 levels = computeLog(newwidth);
3572 retrieveStoreModes(&psm);
3573 newImage = (GLushort *)
3574 malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
3575 newImage_width = width;
3576 if (newImage == NULL) {
3577 return GLU_OUT_OF_MEMORY;
3579 fill_image(&psm,width, 1, format, type, is_index(format),
3581 cmpts = elements_per_group(format,type);
3582 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3583 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3584 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3585 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3587 ** If swap_bytes was set, swapping occurred in fill_image.
3589 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3591 for (level = userLevel; level <= levels; level++) {
3592 if (newImage_width == newwidth) {
3593 /* Use newImage for this level */
3594 if (baseLevel <= level && level <= maxLevel) {
3595 glTexImage1D(target, level, internalFormat, newImage_width,
3596 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3599 if (otherImage == NULL) {
3600 memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
3601 otherImage = (GLushort *) malloc(memreq);
3602 if (otherImage == NULL) {
3603 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3604 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3605 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3606 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3607 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3608 return GLU_OUT_OF_MEMORY;
3611 scale_internal(cmpts, newImage_width, 1, newImage,
3612 newwidth, 1, otherImage);
3613 /* Swap newImage and otherImage */
3614 imageTemp = otherImage;
3615 otherImage = newImage;
3616 newImage = imageTemp;
3618 newImage_width = newwidth;
3619 if (baseLevel <= level && level <= maxLevel) {
3620 glTexImage1D(target, level, internalFormat, newImage_width,
3621 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
3624 if (newwidth > 1) newwidth /= 2;
3626 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3627 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3628 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3629 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3630 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3632 free((GLbyte *) newImage);
3634 free((GLbyte *) otherImage);
3640 gluBuild1DMipmapLevels(GLenum target, GLint internalFormat,
3642 GLenum format, GLenum type,
3643 GLint userLevel, GLint baseLevel, GLint maxLevel,
3648 int rc= checkMipmapArgs(internalFormat,format,type);
3649 if (rc != 0) return rc;
3652 return GLU_INVALID_VALUE;
3655 levels = computeLog(width);
3658 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
3659 return GLU_INVALID_VALUE;
3661 return gluBuild1DMipmapLevelsCore(target, internalFormat,
3664 userLevel, baseLevel, maxLevel,
3666 } /* gluBuild1DMipmapLevels() */
3669 gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
3670 GLenum format, GLenum type,
3673 GLint widthPowerOf2;
3677 int rc= checkMipmapArgs(internalFormat,format,type);
3678 if (rc != 0) return rc;
3681 return GLU_INVALID_VALUE;
3684 closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
3685 levels = computeLog(widthPowerOf2);
3687 return gluBuild1DMipmapLevelsCore(target,internalFormat,
3690 format,type,0,0,levels,data);
3693 static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
3694 GLint width, GLint height, GLenum format,
3695 GLenum type, const void *data)
3697 GLint newwidth, newheight;
3698 GLint level, levels;
3700 GLint newImage_width;
3701 GLint newImage_height;
3702 GLushort *otherImage;
3703 GLushort *imageTemp;
3706 PixelStorageModes psm;
3708 retrieveStoreModes(&psm);
3711 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
3712 newwidth = nearestPower(width);
3713 if (newwidth > maxsize) newwidth = maxsize;
3714 newheight = nearestPower(height);
3715 if (newheight > maxsize) newheight = maxsize;
3717 closestFit(target,width,height,internalFormat,format,type,
3718 &newwidth,&newheight);
3720 levels = computeLog(newwidth);
3721 level = computeLog(newheight);
3722 if (level > levels) levels=level;
3725 newImage = (GLushort *)
3726 malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
3727 newImage_width = width;
3728 newImage_height = height;
3729 if (newImage == NULL) {
3730 return GLU_OUT_OF_MEMORY;
3733 fill_image(&psm,width, height, format, type, is_index(format),
3736 cmpts = elements_per_group(format,type);
3737 glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
3738 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3739 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3740 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3742 ** If swap_bytes was set, swapping occurred in fill_image.
3744 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
3746 for (level = 0; level <= levels; level++) {
3747 if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
3748 glTexImage2D(target, level, internalFormat, newImage_width,
3749 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3752 if (otherImage == NULL) {
3754 image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
3755 otherImage = (GLushort *) malloc(memreq);
3756 if (otherImage == NULL) {
3757 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3758 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3759 glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
3760 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3761 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3762 return GLU_OUT_OF_MEMORY;
3765 scale_internal(cmpts, newImage_width, newImage_height, newImage,
3766 newwidth, newheight, otherImage);
3767 /* Swap newImage and otherImage */
3768 imageTemp = otherImage;
3769 otherImage = newImage;
3770 newImage = imageTemp;
3772 newImage_width = newwidth;
3773 newImage_height = newheight;
3774 glTexImage2D(target, level, internalFormat, newImage_width,
3775 newImage_height, 0, format, GL_UNSIGNED_SHORT,
3778 if (newwidth > 1) newwidth /= 2;
3779 if (newheight > 1) newheight /= 2;
3781 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3782 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3783 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3784 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3785 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3787 free((GLbyte *) newImage);
3789 free((GLbyte *) otherImage);
3794 /* To make swapping images less error prone */
3795 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3796 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3798 static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
3799 GLsizei width, GLsizei height,
3800 GLsizei widthPowerOf2,
3801 GLsizei heightPowerOf2,
3802 GLenum format, GLenum type,
3804 GLint baseLevel,GLint maxLevel,
3807 GLint newwidth, newheight;
3808 GLint level, levels;
3809 const void *usersImage; /* passed from user. Don't touch! */
3810 void *srcImage, *dstImage; /* scratch area to build mipmapped images */
3811 __GLU_INIT_SWAP_IMAGE;
3815 GLint myswap_bytes, groups_per_line, element_size, group_size;
3816 GLint rowsize, padding;
3817 PixelStorageModes psm;
3819 assert(checkMipmapArgs(internalFormat,format,type) == 0);
3820 assert(width >= 1 && height >= 1);
3822 if(type == GL_BITMAP) {
3823 return bitmapBuild2DMipmaps(target, internalFormat, width, height,
3824 format, type, data);
3827 srcImage = dstImage = NULL;
3829 newwidth= widthPowerOf2;
3830 newheight= heightPowerOf2;
3831 levels = computeLog(newwidth);
3832 level = computeLog(newheight);
3833 if (level > levels) levels=level;
3837 retrieveStoreModes(&psm);
3838 myswap_bytes = psm.unpack_swap_bytes;
3839 cmpts = elements_per_group(format,type);
3840 if (psm.unpack_row_length > 0) {
3841 groups_per_line = psm.unpack_row_length;
3843 groups_per_line = width;
3846 element_size = bytes_per_element(type);
3847 group_size = element_size * cmpts;
3848 if (element_size == 1) myswap_bytes = 0;
3850 rowsize = groups_per_line * group_size;
3851 padding = (rowsize % psm.unpack_alignment);
3853 rowsize += psm.unpack_alignment - padding;
3855 usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
3856 psm.unpack_skip_pixels * group_size;
3858 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
3859 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
3860 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3864 /* already power-of-two square */
3865 if (width == newwidth && height == newheight) {
3866 /* Use usersImage for level userLevel */
3867 if (baseLevel <= level && level <= maxLevel) {
3868 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3869 glTexImage2D(target, level, internalFormat, width,
3870 height, 0, format, type,
3873 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
3874 if(levels == 0) { /* we're done. clean up and return */
3875 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3876 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3877 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3878 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3879 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3883 int nextWidth= newwidth/2;
3884 int nextHeight= newheight/2;
3887 if (nextWidth < 1) nextWidth= 1;
3888 if (nextHeight < 1) nextHeight= 1;
3889 memreq = image_size(nextWidth, nextHeight, format, type);
3893 case GL_UNSIGNED_BYTE:
3894 dstImage = (GLubyte *)malloc(memreq);
3897 dstImage = (GLbyte *)malloc(memreq);
3899 case GL_UNSIGNED_SHORT:
3900 dstImage = (GLushort *)malloc(memreq);
3903 dstImage = (GLshort *)malloc(memreq);
3905 case GL_UNSIGNED_INT:
3906 dstImage = (GLuint *)malloc(memreq);
3909 dstImage = (GLint *)malloc(memreq);
3912 dstImage = (GLfloat *)malloc(memreq);
3914 case GL_UNSIGNED_BYTE_3_3_2:
3915 case GL_UNSIGNED_BYTE_2_3_3_REV:
3916 dstImage = (GLubyte *)malloc(memreq);
3918 case GL_UNSIGNED_SHORT_5_6_5:
3919 case GL_UNSIGNED_SHORT_5_6_5_REV:
3920 case GL_UNSIGNED_SHORT_4_4_4_4:
3921 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
3922 case GL_UNSIGNED_SHORT_5_5_5_1:
3923 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
3924 dstImage = (GLushort *)malloc(memreq);
3926 case GL_UNSIGNED_INT_8_8_8_8:
3927 case GL_UNSIGNED_INT_8_8_8_8_REV:
3928 case GL_UNSIGNED_INT_10_10_10_2:
3929 case GL_UNSIGNED_INT_2_10_10_10_REV:
3930 dstImage = (GLuint *)malloc(memreq);
3933 return GLU_INVALID_ENUM;
3935 if (dstImage == NULL) {
3936 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
3937 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
3938 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
3939 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
3940 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
3941 return GLU_OUT_OF_MEMORY;
3945 case GL_UNSIGNED_BYTE:
3946 halveImage_ubyte(cmpts, width, height,
3947 (const GLubyte *)usersImage, (GLubyte *)dstImage,
3948 element_size, rowsize, group_size);
3951 halveImage_byte(cmpts, width, height,
3952 (const GLbyte *)usersImage, (GLbyte *)dstImage,
3953 element_size, rowsize, group_size);
3955 case GL_UNSIGNED_SHORT:
3956 halveImage_ushort(cmpts, width, height,
3957 (const GLushort *)usersImage, (GLushort *)dstImage,
3958 element_size, rowsize, group_size, myswap_bytes);
3961 halveImage_short(cmpts, width, height,
3962 (const GLshort *)usersImage, (GLshort *)dstImage,
3963 element_size, rowsize, group_size, myswap_bytes);
3965 case GL_UNSIGNED_INT:
3966 halveImage_uint(cmpts, width, height,
3967 (const GLuint *)usersImage, (GLuint *)dstImage,
3968 element_size, rowsize, group_size, myswap_bytes);
3971 halveImage_int(cmpts, width, height,
3972 (const GLint *)usersImage, (GLint *)dstImage,
3973 element_size, rowsize, group_size, myswap_bytes);
3976 halveImage_float(cmpts, width, height,
3977 (const GLfloat *)usersImage, (GLfloat *)dstImage,
3978 element_size, rowsize, group_size, myswap_bytes);
3980 case GL_UNSIGNED_BYTE_3_3_2:
3981 assert(format == GL_RGB);
3982 halveImagePackedPixel(3,extract332,shove332,
3983 width,height,usersImage,dstImage,
3984 element_size,rowsize,myswap_bytes);
3986 case GL_UNSIGNED_BYTE_2_3_3_REV:
3987 assert(format == GL_RGB);
3988 halveImagePackedPixel(3,extract233rev,shove233rev,
3989 width,height,usersImage,dstImage,
3990 element_size,rowsize,myswap_bytes);
3992 case GL_UNSIGNED_SHORT_5_6_5:
3993 halveImagePackedPixel(3,extract565,shove565,
3994 width,height,usersImage,dstImage,
3995 element_size,rowsize,myswap_bytes);
3997 case GL_UNSIGNED_SHORT_5_6_5_REV:
3998 halveImagePackedPixel(3,extract565rev,shove565rev,
3999 width,height,usersImage,dstImage,
4000 element_size,rowsize,myswap_bytes);
4002 case GL_UNSIGNED_SHORT_4_4_4_4:
4003 halveImagePackedPixel(4,extract4444,shove4444,
4004 width,height,usersImage,dstImage,
4005 element_size,rowsize,myswap_bytes);
4007 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4008 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4009 width,height,usersImage,dstImage,
4010 element_size,rowsize,myswap_bytes);
4012 case GL_UNSIGNED_SHORT_5_5_5_1:
4013 halveImagePackedPixel(4,extract5551,shove5551,
4014 width,height,usersImage,dstImage,
4015 element_size,rowsize,myswap_bytes);
4017 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4018 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4019 width,height,usersImage,dstImage,
4020 element_size,rowsize,myswap_bytes);
4022 case GL_UNSIGNED_INT_8_8_8_8:
4023 halveImagePackedPixel(4,extract8888,shove8888,
4024 width,height,usersImage,dstImage,
4025 element_size,rowsize,myswap_bytes);
4027 case GL_UNSIGNED_INT_8_8_8_8_REV:
4028 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4029 width,height,usersImage,dstImage,
4030 element_size,rowsize,myswap_bytes);
4032 case GL_UNSIGNED_INT_10_10_10_2:
4033 halveImagePackedPixel(4,extract1010102,shove1010102,
4034 width,height,usersImage,dstImage,
4035 element_size,rowsize,myswap_bytes);
4037 case GL_UNSIGNED_INT_2_10_10_10_REV:
4038 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4039 width,height,usersImage,dstImage,
4040 element_size,rowsize,myswap_bytes);
4047 newheight = height/2;
4049 if (newwidth < 1) newwidth= 1;
4050 if (newheight < 1) newheight= 1;
4053 rowsize = newwidth * group_size;
4054 memreq = image_size(newwidth, newheight, format, type);
4055 /* Swap srcImage and dstImage */
4056 __GLU_SWAP_IMAGE(srcImage,dstImage);
4058 case GL_UNSIGNED_BYTE:
4059 dstImage = (GLubyte *)malloc(memreq);
4062 dstImage = (GLbyte *)malloc(memreq);
4064 case GL_UNSIGNED_SHORT:
4065 dstImage = (GLushort *)malloc(memreq);
4068 dstImage = (GLshort *)malloc(memreq);
4070 case GL_UNSIGNED_INT:
4071 dstImage = (GLuint *)malloc(memreq);
4074 dstImage = (GLint *)malloc(memreq);
4077 dstImage = (GLfloat *)malloc(memreq);
4079 case GL_UNSIGNED_BYTE_3_3_2:
4080 case GL_UNSIGNED_BYTE_2_3_3_REV:
4081 dstImage = (GLubyte *)malloc(memreq);
4083 case GL_UNSIGNED_SHORT_5_6_5:
4084 case GL_UNSIGNED_SHORT_5_6_5_REV:
4085 case GL_UNSIGNED_SHORT_4_4_4_4:
4086 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4087 case GL_UNSIGNED_SHORT_5_5_5_1:
4088 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4089 dstImage = (GLushort *)malloc(memreq);
4091 case GL_UNSIGNED_INT_8_8_8_8:
4092 case GL_UNSIGNED_INT_8_8_8_8_REV:
4093 case GL_UNSIGNED_INT_10_10_10_2:
4094 case GL_UNSIGNED_INT_2_10_10_10_REV:
4095 dstImage = (GLuint *)malloc(memreq);
4098 return GLU_INVALID_ENUM;
4100 if (dstImage == NULL) {
4101 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4102 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4103 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4104 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4105 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4106 return GLU_OUT_OF_MEMORY;
4108 /* level userLevel+1 is in srcImage; level userLevel already saved */
4109 level = userLevel+1;
4110 } else { /* user's image is *not* nice power-of-2 sized square */
4111 memreq = image_size(newwidth, newheight, format, type);
4113 case GL_UNSIGNED_BYTE:
4114 dstImage = (GLubyte *)malloc(memreq);
4117 dstImage = (GLbyte *)malloc(memreq);
4119 case GL_UNSIGNED_SHORT:
4120 dstImage = (GLushort *)malloc(memreq);
4123 dstImage = (GLshort *)malloc(memreq);
4125 case GL_UNSIGNED_INT:
4126 dstImage = (GLuint *)malloc(memreq);
4129 dstImage = (GLint *)malloc(memreq);
4132 dstImage = (GLfloat *)malloc(memreq);
4134 case GL_UNSIGNED_BYTE_3_3_2:
4135 case GL_UNSIGNED_BYTE_2_3_3_REV:
4136 dstImage = (GLubyte *)malloc(memreq);
4138 case GL_UNSIGNED_SHORT_5_6_5:
4139 case GL_UNSIGNED_SHORT_5_6_5_REV:
4140 case GL_UNSIGNED_SHORT_4_4_4_4:
4141 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4142 case GL_UNSIGNED_SHORT_5_5_5_1:
4143 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4144 dstImage = (GLushort *)malloc(memreq);
4146 case GL_UNSIGNED_INT_8_8_8_8:
4147 case GL_UNSIGNED_INT_8_8_8_8_REV:
4148 case GL_UNSIGNED_INT_10_10_10_2:
4149 case GL_UNSIGNED_INT_2_10_10_10_REV:
4150 dstImage = (GLuint *)malloc(memreq);
4153 return GLU_INVALID_ENUM;
4156 if (dstImage == NULL) {
4157 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4158 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4159 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4160 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4161 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4162 return GLU_OUT_OF_MEMORY;
4166 case GL_UNSIGNED_BYTE:
4167 scale_internal_ubyte(cmpts, width, height,
4168 (const GLubyte *)usersImage, newwidth, newheight,
4169 (GLubyte *)dstImage, element_size,
4170 rowsize, group_size);
4173 scale_internal_byte(cmpts, width, height,
4174 (const GLbyte *)usersImage, newwidth, newheight,
4175 (GLbyte *)dstImage, element_size,
4176 rowsize, group_size);
4178 case GL_UNSIGNED_SHORT:
4179 scale_internal_ushort(cmpts, width, height,
4180 (const GLushort *)usersImage, newwidth, newheight,
4181 (GLushort *)dstImage, element_size,
4182 rowsize, group_size, myswap_bytes);
4185 scale_internal_short(cmpts, width, height,
4186 (const GLshort *)usersImage, newwidth, newheight,
4187 (GLshort *)dstImage, element_size,
4188 rowsize, group_size, myswap_bytes);
4190 case GL_UNSIGNED_INT:
4191 scale_internal_uint(cmpts, width, height,
4192 (const GLuint *)usersImage, newwidth, newheight,
4193 (GLuint *)dstImage, element_size,
4194 rowsize, group_size, myswap_bytes);
4197 scale_internal_int(cmpts, width, height,
4198 (const GLint *)usersImage, newwidth, newheight,
4199 (GLint *)dstImage, element_size,
4200 rowsize, group_size, myswap_bytes);
4203 scale_internal_float(cmpts, width, height,
4204 (const GLfloat *)usersImage, newwidth, newheight,
4205 (GLfloat *)dstImage, element_size,
4206 rowsize, group_size, myswap_bytes);
4208 case GL_UNSIGNED_BYTE_3_3_2:
4209 scaleInternalPackedPixel(3,extract332,shove332,
4210 width, height,usersImage,
4211 newwidth,newheight,(void *)dstImage,
4212 element_size,rowsize,myswap_bytes);
4214 case GL_UNSIGNED_BYTE_2_3_3_REV:
4215 scaleInternalPackedPixel(3,extract233rev,shove233rev,
4216 width, height,usersImage,
4217 newwidth,newheight,(void *)dstImage,
4218 element_size,rowsize,myswap_bytes);
4220 case GL_UNSIGNED_SHORT_5_6_5:
4221 scaleInternalPackedPixel(3,extract565,shove565,
4222 width, height,usersImage,
4223 newwidth,newheight,(void *)dstImage,
4224 element_size,rowsize,myswap_bytes);
4226 case GL_UNSIGNED_SHORT_5_6_5_REV:
4227 scaleInternalPackedPixel(3,extract565rev,shove565rev,
4228 width, height,usersImage,
4229 newwidth,newheight,(void *)dstImage,
4230 element_size,rowsize,myswap_bytes);
4232 case GL_UNSIGNED_SHORT_4_4_4_4:
4233 scaleInternalPackedPixel(4,extract4444,shove4444,
4234 width, height,usersImage,
4235 newwidth,newheight,(void *)dstImage,
4236 element_size,rowsize,myswap_bytes);
4238 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4239 scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
4240 width, height,usersImage,
4241 newwidth,newheight,(void *)dstImage,
4242 element_size,rowsize,myswap_bytes);
4244 case GL_UNSIGNED_SHORT_5_5_5_1:
4245 scaleInternalPackedPixel(4,extract5551,shove5551,
4246 width, height,usersImage,
4247 newwidth,newheight,(void *)dstImage,
4248 element_size,rowsize,myswap_bytes);
4250 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4251 scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
4252 width, height,usersImage,
4253 newwidth,newheight,(void *)dstImage,
4254 element_size,rowsize,myswap_bytes);
4256 case GL_UNSIGNED_INT_8_8_8_8:
4257 scaleInternalPackedPixel(4,extract8888,shove8888,
4258 width, height,usersImage,
4259 newwidth,newheight,(void *)dstImage,
4260 element_size,rowsize,myswap_bytes);
4262 case GL_UNSIGNED_INT_8_8_8_8_REV:
4263 scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
4264 width, height,usersImage,
4265 newwidth,newheight,(void *)dstImage,
4266 element_size,rowsize,myswap_bytes);
4268 case GL_UNSIGNED_INT_10_10_10_2:
4269 scaleInternalPackedPixel(4,extract1010102,shove1010102,
4270 width, height,usersImage,
4271 newwidth,newheight,(void *)dstImage,
4272 element_size,rowsize,myswap_bytes);
4274 case GL_UNSIGNED_INT_2_10_10_10_REV:
4275 scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
4276 width, height,usersImage,
4277 newwidth,newheight,(void *)dstImage,
4278 element_size,rowsize,myswap_bytes);
4285 rowsize = newwidth * group_size;
4286 /* Swap dstImage and srcImage */
4287 __GLU_SWAP_IMAGE(srcImage,dstImage);
4289 if(levels != 0) { /* use as little memory as possible */
4291 int nextWidth= newwidth/2;
4292 int nextHeight= newheight/2;
4293 if (nextWidth < 1) nextWidth= 1;
4294 if (nextHeight < 1) nextHeight= 1;
4296 memreq = image_size(nextWidth, nextHeight, format, type);
4300 case GL_UNSIGNED_BYTE:
4301 dstImage = (GLubyte *)malloc(memreq);
4304 dstImage = (GLbyte *)malloc(memreq);
4306 case GL_UNSIGNED_SHORT:
4307 dstImage = (GLushort *)malloc(memreq);
4310 dstImage = (GLshort *)malloc(memreq);
4312 case GL_UNSIGNED_INT:
4313 dstImage = (GLuint *)malloc(memreq);
4316 dstImage = (GLint *)malloc(memreq);
4319 dstImage = (GLfloat *)malloc(memreq);
4321 case GL_UNSIGNED_BYTE_3_3_2:
4322 case GL_UNSIGNED_BYTE_2_3_3_REV:
4323 dstImage = (GLubyte *)malloc(memreq);
4325 case GL_UNSIGNED_SHORT_5_6_5:
4326 case GL_UNSIGNED_SHORT_5_6_5_REV:
4327 case GL_UNSIGNED_SHORT_4_4_4_4:
4328 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4329 case GL_UNSIGNED_SHORT_5_5_5_1:
4330 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4331 dstImage = (GLushort *)malloc(memreq);
4333 case GL_UNSIGNED_INT_8_8_8_8:
4334 case GL_UNSIGNED_INT_8_8_8_8_REV:
4335 case GL_UNSIGNED_INT_10_10_10_2:
4336 case GL_UNSIGNED_INT_2_10_10_10_REV:
4337 dstImage = (GLuint *)malloc(memreq);
4340 return GLU_INVALID_ENUM;
4342 if (dstImage == NULL) {
4343 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4344 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4345 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4346 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4347 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4348 return GLU_OUT_OF_MEMORY;
4351 /* level userLevel is in srcImage; nothing saved yet */
4355 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4356 if (baseLevel <= level && level <= maxLevel) {
4357 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4358 format, type, (void *)srcImage);
4361 level++; /* update current level for the loop */
4362 for (; level <= levels; level++) {
4364 case GL_UNSIGNED_BYTE:
4365 halveImage_ubyte(cmpts, newwidth, newheight,
4366 (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
4367 rowsize, group_size);
4370 halveImage_byte(cmpts, newwidth, newheight,
4371 (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
4372 rowsize, group_size);
4374 case GL_UNSIGNED_SHORT:
4375 halveImage_ushort(cmpts, newwidth, newheight,
4376 (GLushort *)srcImage, (GLushort *)dstImage, element_size,
4377 rowsize, group_size, myswap_bytes);
4380 halveImage_short(cmpts, newwidth, newheight,
4381 (GLshort *)srcImage, (GLshort *)dstImage, element_size,
4382 rowsize, group_size, myswap_bytes);
4384 case GL_UNSIGNED_INT:
4385 halveImage_uint(cmpts, newwidth, newheight,
4386 (GLuint *)srcImage, (GLuint *)dstImage, element_size,
4387 rowsize, group_size, myswap_bytes);
4390 halveImage_int(cmpts, newwidth, newheight,
4391 (GLint *)srcImage, (GLint *)dstImage, element_size,
4392 rowsize, group_size, myswap_bytes);
4395 halveImage_float(cmpts, newwidth, newheight,
4396 (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
4397 rowsize, group_size, myswap_bytes);
4399 case GL_UNSIGNED_BYTE_3_3_2:
4400 halveImagePackedPixel(3,extract332,shove332,
4402 srcImage,dstImage,element_size,rowsize,
4405 case GL_UNSIGNED_BYTE_2_3_3_REV:
4406 halveImagePackedPixel(3,extract233rev,shove233rev,
4408 srcImage,dstImage,element_size,rowsize,
4411 case GL_UNSIGNED_SHORT_5_6_5:
4412 halveImagePackedPixel(3,extract565,shove565,
4414 srcImage,dstImage,element_size,rowsize,
4417 case GL_UNSIGNED_SHORT_5_6_5_REV:
4418 halveImagePackedPixel(3,extract565rev,shove565rev,
4420 srcImage,dstImage,element_size,rowsize,
4423 case GL_UNSIGNED_SHORT_4_4_4_4:
4424 halveImagePackedPixel(4,extract4444,shove4444,
4426 srcImage,dstImage,element_size,rowsize,
4429 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4430 halveImagePackedPixel(4,extract4444rev,shove4444rev,
4432 srcImage,dstImage,element_size,rowsize,
4435 case GL_UNSIGNED_SHORT_5_5_5_1:
4436 halveImagePackedPixel(4,extract5551,shove5551,
4438 srcImage,dstImage,element_size,rowsize,
4441 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4442 halveImagePackedPixel(4,extract1555rev,shove1555rev,
4444 srcImage,dstImage,element_size,rowsize,
4447 case GL_UNSIGNED_INT_8_8_8_8:
4448 halveImagePackedPixel(4,extract8888,shove8888,
4450 srcImage,dstImage,element_size,rowsize,
4453 case GL_UNSIGNED_INT_8_8_8_8_REV:
4454 halveImagePackedPixel(4,extract8888rev,shove8888rev,
4456 srcImage,dstImage,element_size,rowsize,
4459 case GL_UNSIGNED_INT_10_10_10_2:
4460 halveImagePackedPixel(4,extract1010102,shove1010102,
4462 srcImage,dstImage,element_size,rowsize,
4465 case GL_UNSIGNED_INT_2_10_10_10_REV:
4466 halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
4468 srcImage,dstImage,element_size,rowsize,
4476 __GLU_SWAP_IMAGE(srcImage,dstImage);
4478 if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
4479 if (newheight > 1) newheight /= 2;
4481 /* compute amount to pad per row, if any */
4482 int rowPad= rowsize % psm.unpack_alignment;
4484 /* should row be padded? */
4485 if (rowPad == 0) { /* nope, row should not be padded */
4486 /* call tex image with srcImage untouched since it's not padded */
4487 if (baseLevel <= level && level <= maxLevel) {
4488 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4489 format, type, (void *) srcImage);
4492 else { /* yes, row should be padded */
4493 /* compute length of new row in bytes, including padding */
4494 int newRowLength= rowsize + psm.unpack_alignment - rowPad;
4495 int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
4497 /* allocate new image for mipmap of size newRowLength x newheight */
4498 void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
4499 if (newMipmapImage == NULL) {
4500 /* out of memory so return */
4501 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4502 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4503 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4504 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4505 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4506 return GLU_OUT_OF_MEMORY;
4509 /* copy image from srcImage into newMipmapImage by rows */
4511 dstTrav= (unsigned char *) newMipmapImage,
4512 srcTrav= (unsigned char *) srcImage;
4515 dstTrav+= newRowLength, /* make sure the correct distance... */
4516 srcTrav+= rowsize) { /* ...is skipped */
4517 memcpy(dstTrav,srcTrav,rowsize);
4518 /* note that the pad bytes are not visited and will contain
4519 * garbage, which is ok.
4523 /* ...and use this new image for mipmapping instead */
4524 if (baseLevel <= level && level <= maxLevel) {
4525 glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
4526 format, type, newMipmapImage);
4528 free(newMipmapImage); /* don't forget to free it! */
4532 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
4533 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
4534 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
4535 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
4536 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
4538 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
4539 if (dstImage) { /* if it's non-rectangular and only 1 level */
4543 } /* gluBuild2DMipmapLevelsCore() */
4546 gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
4547 GLsizei width, GLsizei height,
4548 GLenum format, GLenum type,
4549 GLint userLevel, GLint baseLevel, GLint maxLevel,
4554 int rc= checkMipmapArgs(internalFormat,format,type);
4555 if (rc != 0) return rc;
4557 if (width < 1 || height < 1) {
4558 return GLU_INVALID_VALUE;
4561 levels = computeLog(width);
4562 level = computeLog(height);
4563 if (level > levels) levels=level;
4566 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
4567 return GLU_INVALID_VALUE;
4569 return gluBuild2DMipmapLevelsCore(target, internalFormat,
4573 userLevel, baseLevel, maxLevel,
4575 } /* gluBuild2DMipmapLevels() */
4578 gluBuild2DMipmaps(GLenum target, GLint internalFormat,
4579 GLsizei width, GLsizei height,
4580 GLenum format, GLenum type,
4583 GLint widthPowerOf2, heightPowerOf2;
4586 int rc= checkMipmapArgs(internalFormat,format,type);
4587 if (rc != 0) return rc;
4589 if (width < 1 || height < 1) {
4590 return GLU_INVALID_VALUE;
4593 closestFit(target,width,height,internalFormat,format,type,
4594 &widthPowerOf2,&heightPowerOf2);
4596 levels = computeLog(widthPowerOf2);
4597 level = computeLog(heightPowerOf2);
4598 if (level > levels) levels=level;
4600 return gluBuild2DMipmapLevelsCore(target,internalFormat,
4602 widthPowerOf2,heightPowerOf2,
4605 } /* gluBuild2DMipmaps() */
4609 ** This routine is for the limited case in which
4610 ** type == GL_UNSIGNED_BYTE && format != index &&
4611 ** unpack_alignment = 1 && unpack_swap_bytes == false
4613 ** so all of the work data can be kept as ubytes instead of shorts.
4615 static int fastBuild2DMipmaps(const PixelStorageModes *psm,
4616 GLenum target, GLint components, GLint width,
4617 GLint height, GLenum format,
4618 GLenum type, void *data)
4620 GLint newwidth, newheight;
4621 GLint level, levels;
4623 GLint newImage_width;
4624 GLint newImage_height;
4625 GLubyte *otherImage;
4632 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
4633 newwidth = nearestPower(width);
4634 if (newwidth > maxsize) newwidth = maxsize;
4635 newheight = nearestPower(height);
4636 if (newheight > maxsize) newheight = maxsize;
4638 closestFit(target,width,height,components,format,type,
4639 &newwidth,&newheight);
4641 levels = computeLog(newwidth);
4642 level = computeLog(newheight);
4643 if (level > levels) levels=level;
4645 cmpts = elements_per_group(format,type);
4649 ** No need to copy the user data if its in the packed correctly.
4650 ** Make sure that later routines don't change that data.
4652 if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
4653 newImage = (GLubyte *)data;
4654 newImage_width = width;
4655 newImage_height = height;
4658 GLint groups_per_line;
4659 GLint elements_per_line;
4660 const GLubyte *start;
4661 const GLubyte *iter;
4665 newImage = (GLubyte *)
4666 malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
4667 newImage_width = width;
4668 newImage_height = height;
4669 if (newImage == NULL) {
4670 return GLU_OUT_OF_MEMORY;
4674 ** Abbreviated version of fill_image for this restricted case.
4676 if (psm->unpack_row_length > 0) {
4677 groups_per_line = psm->unpack_row_length;
4679 groups_per_line = width;
4681 rowsize = groups_per_line * cmpts;
4682 elements_per_line = width * cmpts;
4683 start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
4684 psm->unpack_skip_pixels * cmpts;
4687 for (i = 0; i < height; i++) {
4689 for (j = 0; j < elements_per_line; j++) {
4699 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4700 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
4701 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
4702 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
4703 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
4705 for (level = 0; level <= levels; level++) {
4706 if (newImage_width == newwidth && newImage_height == newheight) {
4707 /* Use newImage for this level */
4708 glTexImage2D(target, level, components, newImage_width,
4709 newImage_height, 0, format, GL_UNSIGNED_BYTE,
4712 if (otherImage == NULL) {
4714 image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
4715 otherImage = (GLubyte *) malloc(memreq);
4716 if (otherImage == NULL) {
4717 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4718 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4719 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4720 glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
4721 glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
4722 return GLU_OUT_OF_MEMORY;
4726 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4727 newImage, newwidth, newheight, otherImage);
4729 /* Swap newImage and otherImage */
4730 imageTemp = otherImage;
4731 otherImage = newImage;
4732 newImage = imageTemp;
4734 newImage_width = newwidth;
4735 newImage_height = newheight;
4736 glTexImage2D(target, level, components, newImage_width,
4737 newImage_height, 0, format, GL_UNSIGNED_BYTE,
4740 if (newwidth > 1) newwidth /= 2;
4741 if (newheight > 1) newheight /= 2;
4743 glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
4744 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
4745 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
4746 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
4747 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
4749 if (newImage != (const GLubyte *)data) {
4750 free((GLbyte *) newImage);
4752 if (otherImage && otherImage != (const GLubyte *)data) {
4753 free((GLbyte *) otherImage);
4762 static GLint elements_per_group(GLenum format, GLenum type)
4765 * Return the number of elements per group of a specified format
4768 /* If the type is packedpixels then answer is 1 (ignore format) */
4769 if (type == GL_UNSIGNED_BYTE_3_3_2 ||
4770 type == GL_UNSIGNED_BYTE_2_3_3_REV ||
4771 type == GL_UNSIGNED_SHORT_5_6_5 ||
4772 type == GL_UNSIGNED_SHORT_5_6_5_REV ||
4773 type == GL_UNSIGNED_SHORT_4_4_4_4 ||
4774 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
4775 type == GL_UNSIGNED_SHORT_5_5_5_1 ||
4776 type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
4777 type == GL_UNSIGNED_INT_8_8_8_8 ||
4778 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
4779 type == GL_UNSIGNED_INT_10_10_10_2 ||
4780 type == GL_UNSIGNED_INT_2_10_10_10_REV) {
4784 /* Types are not packed pixels, so get elements per group */
4789 case GL_LUMINANCE_ALPHA:
4799 static GLfloat bytes_per_element(GLenum type)
4802 * Return the number of bytes per element, based on the element type
4807 case GL_UNSIGNED_SHORT:
4808 return(sizeof(GLushort));
4810 return(sizeof(GLshort));
4811 case GL_UNSIGNED_BYTE:
4812 return(sizeof(GLubyte));
4814 return(sizeof(GLbyte));
4816 return(sizeof(GLint));
4817 case GL_UNSIGNED_INT:
4818 return(sizeof(GLuint));
4820 return(sizeof(GLfloat));
4821 case GL_UNSIGNED_BYTE_3_3_2:
4822 case GL_UNSIGNED_BYTE_2_3_3_REV:
4823 return(sizeof(GLubyte));
4824 case GL_UNSIGNED_SHORT_5_6_5:
4825 case GL_UNSIGNED_SHORT_5_6_5_REV:
4826 case GL_UNSIGNED_SHORT_4_4_4_4:
4827 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
4828 case GL_UNSIGNED_SHORT_5_5_5_1:
4829 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
4830 return(sizeof(GLushort));
4831 case GL_UNSIGNED_INT_8_8_8_8:
4832 case GL_UNSIGNED_INT_8_8_8_8_REV:
4833 case GL_UNSIGNED_INT_10_10_10_2:
4834 case GL_UNSIGNED_INT_2_10_10_10_REV:
4835 return(sizeof(GLuint));
4841 static GLint is_index(GLenum format)
4843 return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
4847 ** Compute memory required for internal packed array of data of given type
4850 static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
4857 components = elements_per_group(format,type);
4858 if (type == GL_BITMAP) {
4859 bytes_per_row = (width + 7) / 8;
4861 bytes_per_row = bytes_per_element(type) * width;
4863 return bytes_per_row * height * components;
4867 ** Extract array from user's data applying all pixel store modes.
4868 ** The internal format used is an array of unsigned shorts.
4870 static void fill_image(const PixelStorageModes *psm,
4871 GLint width, GLint height, GLenum format,
4872 GLenum type, GLboolean index_format,
4873 const void *userdata, GLushort *newimage)
4879 GLint groups_per_line;
4881 GLint elements_per_line;
4882 const GLubyte *start;
4883 const GLubyte *iter;
4888 myswap_bytes = psm->unpack_swap_bytes;
4889 components = elements_per_group(format,type);
4890 if (psm->unpack_row_length > 0) {
4891 groups_per_line = psm->unpack_row_length;
4893 groups_per_line = width;
4896 /* All formats except GL_BITMAP fall out trivially */
4897 if (type == GL_BITMAP) {
4901 rowsize = (groups_per_line * components + 7) / 8;
4902 padding = (rowsize % psm->unpack_alignment);
4904 rowsize += psm->unpack_alignment - padding;
4906 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4907 (psm->unpack_skip_pixels * components / 8);
4908 elements_per_line = width * components;
4910 for (i = 0; i < height; i++) {
4912 bit_offset = (psm->unpack_skip_pixels * components) % 8;
4913 for (j = 0; j < elements_per_line; j++) {
4915 if (psm->unpack_lsb_first) {
4916 current_bit = iter[0] & (1 << bit_offset);
4918 current_bit = iter[0] & (1 << (7 - bit_offset));
4930 if (bit_offset == 8) {
4939 element_size = bytes_per_element(type);
4940 group_size = element_size * components;
4941 if (element_size == 1) myswap_bytes = 0;
4943 rowsize = groups_per_line * group_size;
4944 padding = (rowsize % psm->unpack_alignment);
4946 rowsize += psm->unpack_alignment - padding;
4948 start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
4949 psm->unpack_skip_pixels * group_size;
4950 elements_per_line = width * components;
4953 for (i = 0; i < height; i++) {
4955 for (j = 0; j < elements_per_line; j++) {
4957 float extractComponents[4];
4960 case GL_UNSIGNED_BYTE_3_3_2:
4961 extract332(0,iter,extractComponents);
4962 for (k = 0; k < 3; k++) {
4963 *iter2++ = (GLushort)(extractComponents[k]*65535);
4966 case GL_UNSIGNED_BYTE_2_3_3_REV:
4967 extract233rev(0,iter,extractComponents);
4968 for (k = 0; k < 3; k++) {
4969 *iter2++ = (GLushort)(extractComponents[k]*65535);
4972 case GL_UNSIGNED_BYTE:
4976 *iter2++ = (*iter) * 257;
4981 *iter2++ = *((const GLbyte *) iter);
4984 *iter2++ = (*((const GLbyte *) iter)) * 516;
4987 case GL_UNSIGNED_SHORT_5_6_5:
4988 extract565(myswap_bytes,iter,extractComponents);
4989 for (k = 0; k < 3; k++) {
4990 *iter2++ = (GLushort)(extractComponents[k]*65535);
4993 case GL_UNSIGNED_SHORT_5_6_5_REV:
4994 extract565rev(myswap_bytes,iter,extractComponents);
4995 for (k = 0; k < 3; k++) {
4996 *iter2++ = (GLushort)(extractComponents[k]*65535);
4999 case GL_UNSIGNED_SHORT_4_4_4_4:
5000 extract4444(myswap_bytes,iter,extractComponents);
5001 for (k = 0; k < 4; k++) {
5002 *iter2++ = (GLushort)(extractComponents[k]*65535);
5005 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5006 extract4444rev(myswap_bytes,iter,extractComponents);
5007 for (k = 0; k < 4; k++) {
5008 *iter2++ = (GLushort)(extractComponents[k]*65535);
5011 case GL_UNSIGNED_SHORT_5_5_5_1:
5012 extract5551(myswap_bytes,iter,extractComponents);
5013 for (k = 0; k < 4; k++) {
5014 *iter2++ = (GLushort)(extractComponents[k]*65535);
5017 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5018 extract1555rev(myswap_bytes,iter,extractComponents);
5019 for (k = 0; k < 4; k++) {
5020 *iter2++ = (GLushort)(extractComponents[k]*65535);
5023 case GL_UNSIGNED_SHORT:
5026 widget.ub[0] = iter[1];
5027 widget.ub[1] = iter[0];
5029 widget.ub[0] = iter[0];
5030 widget.ub[1] = iter[1];
5032 if (type == GL_SHORT) {
5034 *iter2++ = widget.s[0];
5037 *iter2++ = widget.s[0]*2;
5040 *iter2++ = widget.us[0];
5043 case GL_UNSIGNED_INT_8_8_8_8:
5044 extract8888(myswap_bytes,iter,extractComponents);
5045 for (k = 0; k < 4; k++) {
5046 *iter2++ = (GLushort)(extractComponents[k]*65535);
5049 case GL_UNSIGNED_INT_8_8_8_8_REV:
5050 extract8888rev(myswap_bytes,iter,extractComponents);
5051 for (k = 0; k < 4; k++) {
5052 *iter2++ = (GLushort)(extractComponents[k]*65535);
5055 case GL_UNSIGNED_INT_10_10_10_2:
5056 extract1010102(myswap_bytes,iter,extractComponents);
5057 for (k = 0; k < 4; k++) {
5058 *iter2++ = (GLushort)(extractComponents[k]*65535);
5061 case GL_UNSIGNED_INT_2_10_10_10_REV:
5062 extract2101010rev(myswap_bytes,iter,extractComponents);
5063 for (k = 0; k < 4; k++) {
5064 *iter2++ = (GLushort)(extractComponents[k]*65535);
5068 case GL_UNSIGNED_INT:
5071 widget.ub[0] = iter[3];
5072 widget.ub[1] = iter[2];
5073 widget.ub[2] = iter[1];
5074 widget.ub[3] = iter[0];
5076 widget.ub[0] = iter[0];
5077 widget.ub[1] = iter[1];
5078 widget.ub[2] = iter[2];
5079 widget.ub[3] = iter[3];
5081 if (type == GL_FLOAT) {
5083 *iter2++ = widget.f;
5085 *iter2++ = 65535 * widget.f;
5087 } else if (type == GL_UNSIGNED_INT) {
5089 *iter2++ = widget.ui;
5091 *iter2++ = widget.ui >> 16;
5095 *iter2++ = widget.i;
5097 *iter2++ = widget.i >> 15;
5102 iter += element_size;
5106 /* want 'iter' pointing at start, not within, row for assertion
5113 /* iterators should be one byte past end */
5114 if (!isTypePackedPixel(type)) {
5115 assert(iter2 == &newimage[width*height*components]);
5118 assert(iter2 == &newimage[width*height*
5119 elements_per_group(format,0)]);
5121 assert( iter == &((const GLubyte *)userdata)[rowsize*height +
5122 psm->unpack_skip_rows * rowsize +
5123 psm->unpack_skip_pixels * group_size] );
5126 } /* fill_image() */
5129 ** Insert array into user's data applying all pixel store modes.
5130 ** The internal format is an array of unsigned shorts.
5131 ** empty_image() because it is the opposite of fill_image().
5133 static void empty_image(const PixelStorageModes *psm,
5134 GLint width, GLint height, GLenum format,
5135 GLenum type, GLboolean index_format,
5136 const GLushort *oldimage, void *userdata)
5142 GLint groups_per_line;
5144 GLint elements_per_line;
5147 const GLushort *iter2;
5151 myswap_bytes = psm->pack_swap_bytes;
5152 components = elements_per_group(format,type);
5153 if (psm->pack_row_length > 0) {
5154 groups_per_line = psm->pack_row_length;
5156 groups_per_line = width;
5159 /* All formats except GL_BITMAP fall out trivially */
5160 if (type == GL_BITMAP) {
5164 rowsize = (groups_per_line * components + 7) / 8;
5165 padding = (rowsize % psm->pack_alignment);
5167 rowsize += psm->pack_alignment - padding;
5169 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5170 (psm->pack_skip_pixels * components / 8);
5171 elements_per_line = width * components;
5173 for (i = 0; i < height; i++) {
5175 bit_offset = (psm->pack_skip_pixels * components) % 8;
5176 for (j = 0; j < elements_per_line; j++) {
5178 current_bit = iter2[0] & 1;
5180 if (iter2[0] > 32767) {
5188 if (psm->pack_lsb_first) {
5189 *iter |= (1 << bit_offset);
5191 *iter |= (1 << (7 - bit_offset));
5194 if (psm->pack_lsb_first) {
5195 *iter &= ~(1 << bit_offset);
5197 *iter &= ~(1 << (7 - bit_offset));
5202 if (bit_offset == 8) {
5211 float shoveComponents[4];
5213 element_size = bytes_per_element(type);
5214 group_size = element_size * components;
5215 if (element_size == 1) myswap_bytes = 0;
5217 rowsize = groups_per_line * group_size;
5218 padding = (rowsize % psm->pack_alignment);
5220 rowsize += psm->pack_alignment - padding;
5222 start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
5223 psm->pack_skip_pixels * group_size;
5224 elements_per_line = width * components;
5227 for (i = 0; i < height; i++) {
5229 for (j = 0; j < elements_per_line; j++) {
5233 case GL_UNSIGNED_BYTE_3_3_2:
5234 for (k = 0; k < 3; k++) {
5235 shoveComponents[k]= *iter2++ / 65535.0;
5237 shove332(shoveComponents,0,(void *)iter);
5239 case GL_UNSIGNED_BYTE_2_3_3_REV:
5240 for (k = 0; k < 3; k++) {
5241 shoveComponents[k]= *iter2++ / 65535.0;
5243 shove233rev(shoveComponents,0,(void *)iter);
5245 case GL_UNSIGNED_BYTE:
5249 *iter = *iter2++ >> 8;
5254 *((GLbyte *) iter) = *iter2++;
5256 *((GLbyte *) iter) = *iter2++ >> 9;
5259 case GL_UNSIGNED_SHORT_5_6_5:
5260 for (k = 0; k < 3; k++) {
5261 shoveComponents[k]= *iter2++ / 65535.0;
5263 shove565(shoveComponents,0,(void *)&widget.us[0]);
5265 iter[0] = widget.ub[1];
5266 iter[1] = widget.ub[0];
5269 *(GLushort *)iter = widget.us[0];
5272 case GL_UNSIGNED_SHORT_5_6_5_REV:
5273 for (k = 0; k < 3; k++) {
5274 shoveComponents[k]= *iter2++ / 65535.0;
5276 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
5278 iter[0] = widget.ub[1];
5279 iter[1] = widget.ub[0];
5282 *(GLushort *)iter = widget.us[0];
5285 case GL_UNSIGNED_SHORT_4_4_4_4:
5286 for (k = 0; k < 4; k++) {
5287 shoveComponents[k]= *iter2++ / 65535.0;
5289 shove4444(shoveComponents,0,(void *)&widget.us[0]);
5291 iter[0] = widget.ub[1];
5292 iter[1] = widget.ub[0];
5294 *(GLushort *)iter = widget.us[0];
5297 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
5298 for (k = 0; k < 4; k++) {
5299 shoveComponents[k]= *iter2++ / 65535.0;
5301 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
5303 iter[0] = widget.ub[1];
5304 iter[1] = widget.ub[0];
5306 *(GLushort *)iter = widget.us[0];
5309 case GL_UNSIGNED_SHORT_5_5_5_1:
5310 for (k = 0; k < 4; k++) {
5311 shoveComponents[k]= *iter2++ / 65535.0;
5313 shove5551(shoveComponents,0,(void *)&widget.us[0]);
5315 iter[0] = widget.ub[1];
5316 iter[1] = widget.ub[0];
5318 *(GLushort *)iter = widget.us[0];
5321 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
5322 for (k = 0; k < 4; k++) {
5323 shoveComponents[k]= *iter2++ / 65535.0;
5325 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
5327 iter[0] = widget.ub[1];
5328 iter[1] = widget.ub[0];
5330 *(GLushort *)iter = widget.us[0];
5333 case GL_UNSIGNED_SHORT:
5335 if (type == GL_SHORT) {
5337 widget.s[0] = *iter2++;
5339 widget.s[0] = *iter2++ >> 1;
5342 widget.us[0] = *iter2++;
5345 iter[0] = widget.ub[1];
5346 iter[1] = widget.ub[0];
5348 iter[0] = widget.ub[0];
5349 iter[1] = widget.ub[1];
5352 case GL_UNSIGNED_INT_8_8_8_8:
5353 for (k = 0; k < 4; k++) {
5354 shoveComponents[k]= *iter2++ / 65535.0;
5356 shove8888(shoveComponents,0,(void *)&widget.ui);
5358 iter[3] = widget.ub[0];
5359 iter[2] = widget.ub[1];
5360 iter[1] = widget.ub[2];
5361 iter[0] = widget.ub[3];
5363 *(GLuint *)iter= widget.ui;
5367 case GL_UNSIGNED_INT_8_8_8_8_REV:
5368 for (k = 0; k < 4; k++) {
5369 shoveComponents[k]= *iter2++ / 65535.0;
5371 shove8888rev(shoveComponents,0,(void *)&widget.ui);
5373 iter[3] = widget.ub[0];
5374 iter[2] = widget.ub[1];
5375 iter[1] = widget.ub[2];
5376 iter[0] = widget.ub[3];
5378 *(GLuint *)iter= widget.ui;
5381 case GL_UNSIGNED_INT_10_10_10_2:
5382 for (k = 0; k < 4; k++) {
5383 shoveComponents[k]= *iter2++ / 65535.0;
5385 shove1010102(shoveComponents,0,(void *)&widget.ui);
5387 iter[3] = widget.ub[0];
5388 iter[2] = widget.ub[1];
5389 iter[1] = widget.ub[2];
5390 iter[0] = widget.ub[3];
5392 *(GLuint *)iter= widget.ui;
5395 case GL_UNSIGNED_INT_2_10_10_10_REV:
5396 for (k = 0; k < 4; k++) {
5397 shoveComponents[k]= *iter2++ / 65535.0;
5399 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
5401 iter[3] = widget.ub[0];
5402 iter[2] = widget.ub[1];
5403 iter[1] = widget.ub[2];
5404 iter[0] = widget.ub[3];
5406 *(GLuint *)iter= widget.ui;
5410 case GL_UNSIGNED_INT:
5412 if (type == GL_FLOAT) {
5414 widget.f = *iter2++;
5416 widget.f = *iter2++ / (float) 65535.0;
5418 } else if (type == GL_UNSIGNED_INT) {
5420 widget.ui = *iter2++;
5422 widget.ui = (unsigned int) *iter2++ * 65537;
5426 widget.i = *iter2++;
5428 widget.i = ((unsigned int) *iter2++ * 65537)/2;
5432 iter[3] = widget.ub[0];
5433 iter[2] = widget.ub[1];
5434 iter[1] = widget.ub[2];
5435 iter[0] = widget.ub[3];
5437 iter[0] = widget.ub[0];
5438 iter[1] = widget.ub[1];
5439 iter[2] = widget.ub[2];
5440 iter[3] = widget.ub[3];
5444 iter += element_size;
5448 /* want 'iter' pointing at start, not within, row for assertion
5455 /* iterators should be one byte past end */
5456 if (!isTypePackedPixel(type)) {
5457 assert(iter2 == &oldimage[width*height*components]);
5460 assert(iter2 == &oldimage[width*height*
5461 elements_per_group(format,0)]);
5463 assert( iter == &((GLubyte *)userdata)[rowsize*height +
5464 psm->pack_skip_rows * rowsize +
5465 psm->pack_skip_pixels * group_size] );
5468 } /* empty_image() */
5470 /*--------------------------------------------------------------------------
5471 * Decimation of packed pixel types
5472 *--------------------------------------------------------------------------
5474 static void extract332(int isSwap,
5475 const void *packedPixel, GLfloat extractComponents[])
5477 GLubyte ubyte= *(const GLubyte *)packedPixel;
5479 isSwap= isSwap; /* turn off warnings */
5481 /* 11100000 == 0xe0 */
5482 /* 00011100 == 0x1c */
5483 /* 00000011 == 0x03 */
5485 extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0;
5486 extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5487 extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */
5488 } /* extract332() */
5490 static void shove332(const GLfloat shoveComponents[],
5491 int index, void *packedPixel)
5493 /* 11100000 == 0xe0 */
5494 /* 00011100 == 0x1c */
5495 /* 00000011 == 0x03 */
5497 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5498 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5499 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5501 /* due to limited precision, need to round before shoving */
5502 ((GLubyte *)packedPixel)[index] =
5503 ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0;
5504 ((GLubyte *)packedPixel)[index] |=
5505 ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c;
5506 ((GLubyte *)packedPixel)[index] |=
5507 ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03;
5510 static void extract233rev(int isSwap,
5511 const void *packedPixel, GLfloat extractComponents[])
5513 GLubyte ubyte= *(const GLubyte *)packedPixel;
5515 isSwap= isSwap; /* turn off warnings */
5517 /* 0000,0111 == 0x07 */
5518 /* 0011,1000 == 0x38 */
5519 /* 1100,0000 == 0xC0 */
5521 extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0;
5522 extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
5523 extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
5524 } /* extract233rev() */
5526 static void shove233rev(const GLfloat shoveComponents[],
5527 int index, void *packedPixel)
5529 /* 0000,0111 == 0x07 */
5530 /* 0011,1000 == 0x38 */
5531 /* 1100,0000 == 0xC0 */
5533 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5534 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5535 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5537 /* due to limited precision, need to round before shoving */
5538 ((GLubyte *)packedPixel)[index] =
5539 ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07;
5540 ((GLubyte *)packedPixel)[index]|=
5541 ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
5542 ((GLubyte *)packedPixel)[index]|=
5543 ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
5544 } /* shove233rev() */
5546 static void extract565(int isSwap,
5547 const void *packedPixel, GLfloat extractComponents[])
5549 GLushort ushort= *(const GLushort *)packedPixel;
5552 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5555 ushort= *(const GLushort *)packedPixel;
5558 /* 11111000,00000000 == 0xf800 */
5559 /* 00000111,11100000 == 0x07e0 */
5560 /* 00000000,00011111 == 0x001f */
5562 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5563 extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5564 extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0;
5565 } /* extract565() */
5567 static void shove565(const GLfloat shoveComponents[],
5568 int index,void *packedPixel)
5570 /* 11111000,00000000 == 0xf800 */
5571 /* 00000111,11100000 == 0x07e0 */
5572 /* 00000000,00011111 == 0x001f */
5574 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5575 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5576 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5578 /* due to limited precision, need to round before shoving */
5579 ((GLushort *)packedPixel)[index] =
5580 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5581 ((GLushort *)packedPixel)[index]|=
5582 ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0;
5583 ((GLushort *)packedPixel)[index]|=
5584 ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f;
5587 static void extract565rev(int isSwap,
5588 const void *packedPixel, GLfloat extractComponents[])
5590 GLushort ushort= *(const GLushort *)packedPixel;
5593 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5596 ushort= *(const GLushort *)packedPixel;
5599 /* 00000000,00011111 == 0x001f */
5600 /* 00000111,11100000 == 0x07e0 */
5601 /* 11111000,00000000 == 0xf800 */
5603 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5604 extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0;
5605 extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
5606 } /* extract565rev() */
5608 static void shove565rev(const GLfloat shoveComponents[],
5609 int index,void *packedPixel)
5611 /* 00000000,00011111 == 0x001f */
5612 /* 00000111,11100000 == 0x07e0 */
5613 /* 11111000,00000000 == 0xf800 */
5615 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5616 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5617 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5619 /* due to limited precision, need to round before shoving */
5620 ((GLushort *)packedPixel)[index] =
5621 ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F;
5622 ((GLushort *)packedPixel)[index]|=
5623 ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0;
5624 ((GLushort *)packedPixel)[index]|=
5625 ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
5626 } /* shove565rev() */
5628 static void extract4444(int isSwap,const void *packedPixel,
5629 GLfloat extractComponents[])
5634 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5637 ushort= *(const GLushort *)packedPixel;
5640 /* 11110000,00000000 == 0xf000 */
5641 /* 00001111,00000000 == 0x0f00 */
5642 /* 00000000,11110000 == 0x00f0 */
5643 /* 00000000,00001111 == 0x000f */
5645 extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5646 extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0;
5647 extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0;
5648 extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0;
5649 } /* extract4444() */
5651 static void shove4444(const GLfloat shoveComponents[],
5652 int index,void *packedPixel)
5654 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5655 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5656 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5657 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5659 /* due to limited precision, need to round before shoving */
5660 ((GLushort *)packedPixel)[index] =
5661 ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
5662 ((GLushort *)packedPixel)[index]|=
5663 ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00;
5664 ((GLushort *)packedPixel)[index]|=
5665 ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0;
5666 ((GLushort *)packedPixel)[index]|=
5667 ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f;
5670 static void extract4444rev(int isSwap,const void *packedPixel,
5671 GLfloat extractComponents[])
5676 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5679 ushort= *(const GLushort *)packedPixel;
5682 /* 00000000,00001111 == 0x000f */
5683 /* 00000000,11110000 == 0x00f0 */
5684 /* 00001111,00000000 == 0x0f00 */
5685 /* 11110000,00000000 == 0xf000 */
5688 extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0;
5689 extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0;
5690 extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0;
5691 extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
5692 } /* extract4444rev() */
5694 static void shove4444rev(const GLfloat shoveComponents[],
5695 int index,void *packedPixel)
5697 /* 00000000,00001111 == 0x000f */
5698 /* 00000000,11110000 == 0x00f0 */
5699 /* 00001111,00000000 == 0x0f00 */
5700 /* 11110000,00000000 == 0xf000 */
5702 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5703 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5704 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5705 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5707 /* due to limited precision, need to round before shoving */
5708 ((GLushort *)packedPixel)[index] =
5709 ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F;
5710 ((GLushort *)packedPixel)[index]|=
5711 ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0;
5712 ((GLushort *)packedPixel)[index]|=
5713 ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00;
5714 ((GLushort *)packedPixel)[index]|=
5715 ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
5716 } /* shove4444rev() */
5718 static void extract5551(int isSwap,const void *packedPixel,
5719 GLfloat extractComponents[])
5724 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5727 ushort= *(const GLushort *)packedPixel;
5730 /* 11111000,00000000 == 0xf800 */
5731 /* 00000111,11000000 == 0x07c0 */
5732 /* 00000000,00111110 == 0x003e */
5733 /* 00000000,00000001 == 0x0001 */
5735 extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5736 extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0;
5737 extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0;
5738 extractComponents[3]=(float)((ushort & 0x0001) );
5739 } /* extract5551() */
5741 static void shove5551(const GLfloat shoveComponents[],
5742 int index,void *packedPixel)
5744 /* 11111000,00000000 == 0xf800 */
5745 /* 00000111,11000000 == 0x07c0 */
5746 /* 00000000,00111110 == 0x003e */
5747 /* 00000000,00000001 == 0x0001 */
5749 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5750 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5751 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5752 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5754 /* due to limited precision, need to round before shoving */
5755 ((GLushort *)packedPixel)[index] =
5756 ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
5757 ((GLushort *)packedPixel)[index]|=
5758 ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0;
5759 ((GLushort *)packedPixel)[index]|=
5760 ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e;
5761 ((GLushort *)packedPixel)[index]|=
5762 ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001;
5765 static void extract1555rev(int isSwap,const void *packedPixel,
5766 GLfloat extractComponents[])
5771 ushort= __GLU_SWAP_2_BYTES(packedPixel);
5774 ushort= *(const GLushort *)packedPixel;
5777 /* 00000000,00011111 == 0x001F */
5778 /* 00000011,11100000 == 0x03E0 */
5779 /* 01111100,00000000 == 0x7C00 */
5780 /* 10000000,00000000 == 0x8000 */
5783 extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
5784 extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0;
5785 extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
5786 extractComponents[3]= (float)((ushort & 0x8000) >> 15);
5787 } /* extract1555rev() */
5789 static void shove1555rev(const GLfloat shoveComponents[],
5790 int index,void *packedPixel)
5792 /* 00000000,00011111 == 0x001F */
5793 /* 00000011,11100000 == 0x03E0 */
5794 /* 01111100,00000000 == 0x7C00 */
5795 /* 10000000,00000000 == 0x8000 */
5797 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5798 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5799 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5800 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5802 /* due to limited precision, need to round before shoving */
5803 ((GLushort *)packedPixel)[index] =
5804 ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F;
5805 ((GLushort *)packedPixel)[index]|=
5806 ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0;
5807 ((GLushort *)packedPixel)[index]|=
5808 ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
5809 ((GLushort *)packedPixel)[index]|=
5810 ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000;
5811 } /* shove1555rev() */
5813 static void extract8888(int isSwap,
5814 const void *packedPixel, GLfloat extractComponents[])
5819 uint= __GLU_SWAP_4_BYTES(packedPixel);
5822 uint= *(const GLuint *)packedPixel;
5825 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5826 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5827 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5828 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5831 extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
5832 extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
5833 extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0;
5834 extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0;
5835 } /* extract8888() */
5837 static void shove8888(const GLfloat shoveComponents[],
5838 int index,void *packedPixel)
5840 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5841 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5842 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5843 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5845 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5846 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5847 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5848 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5850 /* due to limited precision, need to round before shoving */
5851 ((GLuint *)packedPixel)[index] =
5852 ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
5853 ((GLuint *)packedPixel)[index]|=
5854 ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
5855 ((GLuint *)packedPixel)[index]|=
5856 ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00;
5857 ((GLuint *)packedPixel)[index]|=
5858 ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff;
5861 static void extract8888rev(int isSwap,
5862 const void *packedPixel,GLfloat extractComponents[])
5867 uint= __GLU_SWAP_4_BYTES(packedPixel);
5870 uint= *(const GLuint *)packedPixel;
5873 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5874 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5875 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5876 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5879 extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0;
5880 extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0;
5881 extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
5882 extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
5883 } /* extract8888rev() */
5885 static void shove8888rev(const GLfloat shoveComponents[],
5886 int index,void *packedPixel)
5888 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5889 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5890 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5891 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5893 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5894 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5895 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5896 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5898 /* due to limited precision, need to round before shoving */
5899 ((GLuint *)packedPixel)[index] =
5900 ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF;
5901 ((GLuint *)packedPixel)[index]|=
5902 ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00;
5903 ((GLuint *)packedPixel)[index]|=
5904 ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
5905 ((GLuint *)packedPixel)[index]|=
5906 ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
5907 } /* shove8888rev() */
5909 static void extract1010102(int isSwap,
5910 const void *packedPixel,GLfloat extractComponents[])
5915 uint= __GLU_SWAP_4_BYTES(packedPixel);
5918 uint= *(const GLuint *)packedPixel;
5921 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5922 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5923 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5924 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5927 extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
5928 extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
5929 extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0;
5930 extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0;
5931 } /* extract1010102() */
5933 static void shove1010102(const GLfloat shoveComponents[],
5934 int index,void *packedPixel)
5936 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5937 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5938 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5939 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5941 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5942 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5943 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5944 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5946 /* due to limited precision, need to round before shoving */
5947 ((GLuint *)packedPixel)[index] =
5948 ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
5949 ((GLuint *)packedPixel)[index]|=
5950 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
5951 ((GLuint *)packedPixel)[index]|=
5952 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc;
5953 ((GLuint *)packedPixel)[index]|=
5954 ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003;
5955 } /* shove1010102() */
5957 static void extract2101010rev(int isSwap,
5958 const void *packedPixel,
5959 GLfloat extractComponents[])
5964 uint= __GLU_SWAP_4_BYTES(packedPixel);
5967 uint= *(const GLuint *)packedPixel;
5970 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5971 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5972 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5973 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5976 extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0;
5977 extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
5978 extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
5979 extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
5981 } /* extract2101010rev() */
5983 static void shove2101010rev(const GLfloat shoveComponents[],
5984 int index,void *packedPixel)
5986 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5987 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5988 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5989 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5991 assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
5992 assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
5993 assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
5994 assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
5996 /* due to limited precision, need to round before shoving */
5997 ((GLuint *)packedPixel)[index] =
5998 ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF;
5999 ((GLuint *)packedPixel)[index]|=
6000 ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
6001 ((GLuint *)packedPixel)[index]|=
6002 ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
6003 ((GLuint *)packedPixel)[index]|=
6004 ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000;
6005 } /* shove2101010rev() */
6007 static void scaleInternalPackedPixel(int components,
6008 void (*extractPackedPixel)
6009 (int, const void *,GLfloat []),
6010 void (*shovePackedPixel)
6011 (const GLfloat [], int, void *),
6012 GLint widthIn,GLint heightIn,
6014 GLint widthOut,GLint heightOut,
6016 GLint pixelSizeInBytes,
6017 GLint rowSizeInBytes,GLint isSwap)
6023 /* Max components in a format is 4, so... */
6025 float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
6030 const char *temp, *temp0;
6033 int lowx_int, highx_int, lowy_int, highy_int;
6034 float x_percent, y_percent;
6035 float lowx_float, highx_float, lowy_float, highy_float;
6036 float convy_float, convx_float;
6037 int convy_int, convx_int;
6039 const char *left, *right;
6041 if (widthIn == widthOut*2 && heightIn == heightOut*2) {
6042 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6043 widthIn, heightIn, dataIn, dataOut,
6044 pixelSizeInBytes,rowSizeInBytes,isSwap);
6047 convy = (float) heightIn/heightOut;
6048 convx = (float) widthIn/widthOut;
6049 convy_int = floor(convy);
6050 convy_float = convy - convy_int;
6051 convx_int = floor(convx);
6052 convx_float = convx - convx_int;
6054 area = convx * convy;
6058 highy_int = convy_int;
6059 highy_float = convy_float;
6061 for (i = 0; i < heightOut; i++) {
6064 highx_int = convx_int;
6065 highx_float = convx_float;
6067 for (j = 0; j < widthOut; j++) {
6069 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6070 ** to (highx, highy) on input data into this pixel on output
6073 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6075 /* calculate the value for pixels in the 1st row */
6076 xindex = lowx_int*pixelSizeInBytes;
6077 if((highy_int>lowy_int) && (highx_int>lowx_int)) {
6079 y_percent = 1-lowy_float;
6080 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6081 percent = y_percent * (1-lowx_float);
6083 for (k = 0, temp_index = temp; k < components;
6084 k++, temp_index += element_size) {
6086 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6088 totals[k] += *(const GLushort*)temp_index * percent;
6092 (*extractPackedPixel)(isSwap,temp,extractTotals);
6093 for (k = 0; k < components; k++) {
6094 totals[k]+= extractTotals[k] * percent;
6098 for(l = lowx_int+1; l < highx_int; l++) {
6099 temp += pixelSizeInBytes;
6101 for (k = 0, temp_index = temp; k < components;
6102 k++, temp_index += element_size) {
6105 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6107 totals[k] += *(const GLushort*)temp_index * y_percent;
6111 (*extractPackedPixel)(isSwap,temp,extractTotals);
6112 for (k = 0; k < components; k++) {
6113 totals[k]+= extractTotals[k] * y_percent;
6117 temp += pixelSizeInBytes;
6119 percent = y_percent * highx_float;
6121 for (k = 0, temp_index = temp; k < components;
6122 k++, temp_index += element_size) {
6124 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6126 totals[k] += *(const GLushort*)temp_index * percent;
6130 (*extractPackedPixel)(isSwap,temp,extractTotals);
6131 for (k = 0; k < components; k++) {
6132 totals[k]+= extractTotals[k] * percent;
6136 /* calculate the value for pixels in the last row */
6138 y_percent = highy_float;
6139 percent = y_percent * (1-lowx_float);
6140 temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
6142 for (k = 0, temp_index = temp; k < components;
6143 k++, temp_index += element_size) {
6145 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6147 totals[k] += *(const GLushort*)temp_index * percent;
6151 (*extractPackedPixel)(isSwap,temp,extractTotals);
6152 for (k = 0; k < components; k++) {
6153 totals[k]+= extractTotals[k] * percent;
6156 for(l = lowx_int+1; l < highx_int; l++) {
6157 temp += pixelSizeInBytes;
6159 for (k = 0, temp_index = temp; k < components;
6160 k++, temp_index += element_size) {
6163 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6165 totals[k] += *(const GLushort*)temp_index * y_percent;
6169 (*extractPackedPixel)(isSwap,temp,extractTotals);
6170 for (k = 0; k < components; k++) {
6171 totals[k]+= extractTotals[k] * y_percent;
6176 temp += pixelSizeInBytes;
6177 percent = y_percent * highx_float;
6179 for (k = 0, temp_index = temp; k < components;
6180 k++, temp_index += element_size) {
6182 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6184 totals[k] += *(const GLushort*)temp_index * percent;
6188 (*extractPackedPixel)(isSwap,temp,extractTotals);
6189 for (k = 0; k < components; k++) {
6190 totals[k]+= extractTotals[k] * percent;
6194 /* calculate the value for pixels in the 1st and last column */
6195 for(m = lowy_int+1; m < highy_int; m++) {
6196 left += rowSizeInBytes;
6197 right += rowSizeInBytes;
6199 for (k = 0; k < components;
6200 k++, left += element_size, right += element_size) {
6203 __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
6204 __GLU_SWAP_2_BYTES(right) * highx_float;
6206 totals[k] += *(const GLushort*)left * (1-lowx_float)
6207 + *(const GLushort*)right * highx_float;
6211 (*extractPackedPixel)(isSwap,left,extractTotals);
6212 (*extractPackedPixel)(isSwap,right,extractMoreTotals);
6213 for (k = 0; k < components; k++) {
6214 totals[k]+= (extractTotals[k]*(1-lowx_float) +
6215 extractMoreTotals[k]*highx_float);
6219 } else if (highy_int > lowy_int) {
6220 x_percent = highx_float - lowx_float;
6221 percent = (1-lowy_float)*x_percent;
6222 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6224 for (k = 0, temp_index = temp; k < components;
6225 k++, temp_index += element_size) {
6227 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6229 totals[k] += *(const GLushort*)temp_index * percent;
6233 (*extractPackedPixel)(isSwap,temp,extractTotals);
6234 for (k = 0; k < components; k++) {
6235 totals[k]+= extractTotals[k] * percent;
6238 for(m = lowy_int+1; m < highy_int; m++) {
6239 temp += rowSizeInBytes;
6241 for (k = 0, temp_index = temp; k < components;
6242 k++, temp_index += element_size) {
6245 __GLU_SWAP_2_BYTES(temp_index) * x_percent;
6247 totals[k] += *(const GLushort*)temp_index * x_percent;
6251 (*extractPackedPixel)(isSwap,temp,extractTotals);
6252 for (k = 0; k < components; k++) {
6253 totals[k]+= extractTotals[k] * x_percent;
6257 percent = x_percent * highy_float;
6258 temp += rowSizeInBytes;
6260 for (k = 0, temp_index = temp; k < components;
6261 k++, temp_index += element_size) {
6263 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6265 totals[k] += *(const GLushort*)temp_index * percent;
6269 (*extractPackedPixel)(isSwap,temp,extractTotals);
6270 for (k = 0; k < components; k++) {
6271 totals[k]+= extractTotals[k] * percent;
6274 } else if (highx_int > lowx_int) {
6275 y_percent = highy_float - lowy_float;
6276 percent = (1-lowx_float)*y_percent;
6277 temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
6279 for (k = 0, temp_index = temp; k < components;
6280 k++, temp_index += element_size) {
6282 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6284 totals[k] += *(const GLushort*)temp_index * percent;
6288 (*extractPackedPixel)(isSwap,temp,extractTotals);
6289 for (k = 0; k < components; k++) {
6290 totals[k]+= extractTotals[k] * percent;
6293 for (l = lowx_int+1; l < highx_int; l++) {
6294 temp += pixelSizeInBytes;
6296 for (k = 0, temp_index = temp; k < components;
6297 k++, temp_index += element_size) {
6300 __GLU_SWAP_2_BYTES(temp_index) * y_percent;
6302 totals[k] += *(const GLushort*)temp_index * y_percent;
6306 (*extractPackedPixel)(isSwap,temp,extractTotals);
6307 for (k = 0; k < components; k++) {
6308 totals[k]+= extractTotals[k] * y_percent;
6312 temp += pixelSizeInBytes;
6313 percent = y_percent * highx_float;
6315 for (k = 0, temp_index = temp; k < components;
6316 k++, temp_index += element_size) {
6318 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6320 totals[k] += *(const GLushort*)temp_index * percent;
6324 (*extractPackedPixel)(isSwap,temp,extractTotals);
6325 for (k = 0; k < components; k++) {
6326 totals[k]+= extractTotals[k] * percent;
6330 percent = (highy_float-lowy_float)*(highx_float-lowx_float);
6331 temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
6333 for (k = 0, temp_index = temp; k < components;
6334 k++, temp_index += element_size) {
6336 totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
6338 totals[k] += *(const GLushort*)temp_index * percent;
6342 (*extractPackedPixel)(isSwap,temp,extractTotals);
6343 for (k = 0; k < components; k++) {
6344 totals[k]+= extractTotals[k] * percent;
6349 /* this is for the pixels in the body */
6350 temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
6351 for (m = lowy_int+1; m < highy_int; m++) {
6353 for(l = lowx_int+1; l < highx_int; l++) {
6355 for (k = 0, temp_index = temp; k < components;
6356 k++, temp_index += element_size) {
6358 totals[k] += __GLU_SWAP_2_BYTES(temp_index);
6360 totals[k] += *(const GLushort*)temp_index;
6364 (*extractPackedPixel)(isSwap,temp,extractTotals);
6365 for (k = 0; k < components; k++) {
6366 totals[k]+= extractTotals[k];
6369 temp += pixelSizeInBytes;
6371 temp0 += rowSizeInBytes;
6374 outindex = (j + (i * widthOut)); /* * (components == 1) */
6376 for (k = 0; k < components; k++) {
6377 dataout[outindex + k] = totals[k]/area;
6378 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6381 for (k = 0; k < components; k++) {
6382 shoveTotals[k]= totals[k]/area;
6384 (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
6386 lowx_int = highx_int;
6387 lowx_float = highx_float;
6388 highx_int += convx_int;
6389 highx_float += convx_float;
6390 if(highx_float > 1) {
6395 lowy_int = highy_int;
6396 lowy_float = highy_float;
6397 highy_int += convy_int;
6398 highy_float += convy_float;
6399 if(highy_float > 1) {
6405 assert(outindex == (widthOut*heightOut - 1));
6406 } /* scaleInternalPackedPixel() */
6408 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6409 * inputs; not always equal. Output NEVER has row padding.
6411 static void halveImagePackedPixel(int components,
6412 void (*extractPackedPixel)
6413 (int, const void *,GLfloat []),
6414 void (*shovePackedPixel)
6415 (const GLfloat [],int, void *),
6416 GLint width, GLint height,
6417 const void *dataIn, void *dataOut,
6418 GLint pixelSizeInBytes,
6419 GLint rowSizeInBytes, GLint isSwap)
6421 /* handle case where there is only 1 column/row */
6422 if (width == 1 || height == 1) {
6423 assert(!(width == 1 && height == 1)); /* can't be 1x1 */
6424 halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
6425 width,height,dataIn,dataOut,pixelSizeInBytes,
6426 rowSizeInBytes,isSwap);
6433 int halfWidth= width / 2;
6434 int halfHeight= height / 2;
6435 const char *src= (const char *) dataIn;
6436 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6439 for (ii= 0; ii< halfHeight; ii++) {
6440 for (jj= 0; jj< halfWidth; jj++) {
6442 float totals[4]; /* 4 is maximum components */
6443 float extractTotals[BOX4][4]; /* 4 is maximum components */
6446 (*extractPackedPixel)(isSwap,src,
6447 &extractTotals[0][0]);
6448 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6449 &extractTotals[1][0]);
6450 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6451 &extractTotals[2][0]);
6452 (*extractPackedPixel)(isSwap,
6453 (src+rowSizeInBytes+pixelSizeInBytes),
6454 &extractTotals[3][0]);
6455 for (cc = 0; cc < components; cc++) {
6458 /* grab 4 pixels to average */
6460 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6461 * extractTotals[2][RED]+extractTotals[3][RED];
6462 * totals[RED]/= 4.0;
6464 for (kk = 0; kk < BOX4; kk++) {
6465 totals[cc]+= extractTotals[kk][cc];
6467 totals[cc]/= (float)BOX4;
6469 (*shovePackedPixel)(totals,outIndex,dataOut);
6472 /* skip over to next square of 4 */
6473 src+= pixelSizeInBytes + pixelSizeInBytes;
6475 /* skip past pad bytes, if any, to get to next row */
6478 /* src is at beginning of a row here, but it's the second row of
6479 * the square block of 4 pixels that we just worked on so we
6480 * need to go one more row.
6488 src+= rowSizeInBytes;
6491 /* both pointers must reach one byte after the end */
6492 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6493 assert(outIndex == halfWidth * halfHeight);
6495 } /* halveImagePackedPixel() */
6497 static void halve1DimagePackedPixel(int components,
6498 void (*extractPackedPixel)
6499 (int, const void *,GLfloat []),
6500 void (*shovePackedPixel)
6501 (const GLfloat [],int, void *),
6502 GLint width, GLint height,
6503 const void *dataIn, void *dataOut,
6504 GLint pixelSizeInBytes,
6505 GLint rowSizeInBytes, GLint isSwap)
6507 int halfWidth= width / 2;
6508 int halfHeight= height / 2;
6509 const char *src= (const char *) dataIn;
6512 assert(width == 1 || height == 1); /* must be 1D */
6513 assert(width != height); /* can't be square */
6515 if (height == 1) { /* 1 row */
6518 assert(width != 1); /* widthxheight can't be 1x1 */
6521 /* one horizontal row with possible pad bytes */
6523 for (jj= 0; jj< halfWidth; jj++) {
6525 float totals[4]; /* 4 is maximum components */
6526 float extractTotals[BOX2][4]; /* 4 is maximum components */
6529 /* average two at a time, instead of four */
6530 (*extractPackedPixel)(isSwap,src,
6531 &extractTotals[0][0]);
6532 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
6533 &extractTotals[1][0]);
6534 for (cc = 0; cc < components; cc++) {
6537 /* grab 2 pixels to average */
6539 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6540 * totals[RED]/= 2.0;
6542 for (kk = 0; kk < BOX2; kk++) {
6543 totals[cc]+= extractTotals[kk][cc];
6545 totals[cc]/= (float)BOX2;
6547 (*shovePackedPixel)(totals,outIndex,dataOut);
6550 /* skip over to next group of 2 */
6551 src+= pixelSizeInBytes + pixelSizeInBytes;
6555 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
6556 src+= padBytes; /* for assertion only */
6558 assert(src == &((const char *)dataIn)[rowSizeInBytes]);
6559 assert(outIndex == halfWidth * halfHeight);
6561 else if (width == 1) { /* 1 column */
6564 assert(height != 1); /* widthxheight can't be 1x1 */
6566 /* one vertical column with possible pad bytes per row */
6567 /* average two at a time */
6569 for (jj= 0; jj< halfHeight; jj++) {
6571 float totals[4]; /* 4 is maximum components */
6572 float extractTotals[BOX2][4]; /* 4 is maximum components */
6575 /* average two at a time, instead of four */
6576 (*extractPackedPixel)(isSwap,src,
6577 &extractTotals[0][0]);
6578 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
6579 &extractTotals[1][0]);
6580 for (cc = 0; cc < components; cc++) {
6583 /* grab 2 pixels to average */
6585 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6586 * totals[RED]/= 2.0;
6588 for (kk = 0; kk < BOX2; kk++) {
6589 totals[cc]+= extractTotals[kk][cc];
6591 totals[cc]/= (float)BOX2;
6593 (*shovePackedPixel)(totals,outIndex,dataOut);
6596 src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
6599 assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
6600 assert(outIndex == halfWidth * halfHeight);
6602 } /* halve1DimagePackedPixel() */
6604 /*===========================================================================*/
6606 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6608 * This section ensures that GLU 1.3 will load and run on
6609 * a GL 1.1 implementation. It dynamically resolves the
6610 * call to glTexImage3D() which might not be available.
6611 * Or is it might be supported as an extension.
6612 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6615 typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
6616 GLenum internalFormat,
6617 GLsizei width, GLsizei height,
6618 GLsizei depth, GLint border,
6619 GLenum format, GLenum type,
6620 const GLvoid *pixels );
6622 static TexImage3Dproc pTexImage3D = 0;
6624 #if !defined(_WIN32) && !defined(__WIN32__)
6626 # include <sys/types.h>
6628 WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR);
6631 static void gluTexImage3D( GLenum target, GLint level,
6632 GLenum internalFormat,
6633 GLsizei width, GLsizei height,
6634 GLsizei depth, GLint border,
6635 GLenum format, GLenum type,
6636 const GLvoid *pixels )
6639 #if defined(_WIN32) || defined(__WIN32__)
6640 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
6642 pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
6644 void *libHandle = dlopen("libgl.so", RTLD_LAZY);
6645 pTexImage3D = TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
6647 pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
6652 /* Now call glTexImage3D */
6654 pTexImage3D(target, level, internalFormat, width, height,
6655 depth, border, format, type, pixels);
6660 /* Only bind to a GL 1.2 implementation: */
6661 #define gluTexImage3D glTexImage3D
6665 static GLint imageSize3D(GLint width, GLint height, GLint depth,
6666 GLenum format, GLenum type)
6668 int components= elements_per_group(format,type);
6669 int bytes_per_row= bytes_per_element(type) * width;
6671 assert(width > 0 && height > 0 && depth > 0);
6672 assert(type != GL_BITMAP);
6674 return bytes_per_row * height * depth * components;
6675 } /* imageSize3D() */
6677 static void fillImage3D(const PixelStorageModes *psm,
6678 GLint width, GLint height, GLint depth, GLenum format,
6679 GLenum type, GLboolean indexFormat,
6680 const void *userImage, GLushort *newImage)
6689 int elementsPerLine;
6692 const GLubyte *start, *rowStart, *iter;
6696 myswapBytes= psm->unpack_swap_bytes;
6697 components= elements_per_group(format,type);
6698 if (psm->unpack_row_length > 0) {
6699 groupsPerLine= psm->unpack_row_length;
6702 groupsPerLine= width;
6704 elementSize= bytes_per_element(type);
6705 groupSize= elementSize * components;
6706 if (elementSize == 1) myswapBytes= 0;
6709 if (psm->unpack_image_height > 0) {
6710 rowsPerImage= psm->unpack_image_height;
6713 rowsPerImage= height;
6717 rowSize= groupsPerLine * groupSize;
6718 padding= rowSize % psm->unpack_alignment;
6720 rowSize+= psm->unpack_alignment - padding;
6723 imageSize= rowsPerImage * rowSize; /* 3dstuff */
6725 start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
6726 psm->unpack_skip_pixels * groupSize +
6728 psm->unpack_skip_images * imageSize;
6729 elementsPerLine = width * components;
6732 for (dd= 0; dd < depth; dd++) {
6735 for (hh= 0; hh < height; hh++) {
6738 for (ww= 0; ww < elementsPerLine; ww++) {
6740 float extractComponents[4];
6743 case GL_UNSIGNED_BYTE:
6747 *iter2++ = (*iter) * 257;
6752 *iter2++ = *((const GLbyte *) iter);
6755 *iter2++ = (*((const GLbyte *) iter)) * 516;
6758 case GL_UNSIGNED_BYTE_3_3_2:
6759 extract332(0,iter,extractComponents);
6760 for (k = 0; k < 3; k++) {
6761 *iter2++ = (GLushort)(extractComponents[k]*65535);
6764 case GL_UNSIGNED_BYTE_2_3_3_REV:
6765 extract233rev(0,iter,extractComponents);
6766 for (k = 0; k < 3; k++) {
6767 *iter2++ = (GLushort)(extractComponents[k]*65535);
6770 case GL_UNSIGNED_SHORT_5_6_5:
6771 extract565(myswapBytes,iter,extractComponents);
6772 for (k = 0; k < 3; k++) {
6773 *iter2++ = (GLushort)(extractComponents[k]*65535);
6776 case GL_UNSIGNED_SHORT_5_6_5_REV:
6777 extract565rev(myswapBytes,iter,extractComponents);
6778 for (k = 0; k < 3; k++) {
6779 *iter2++ = (GLushort)(extractComponents[k]*65535);
6782 case GL_UNSIGNED_SHORT_4_4_4_4:
6783 extract4444(myswapBytes,iter,extractComponents);
6784 for (k = 0; k < 4; k++) {
6785 *iter2++ = (GLushort)(extractComponents[k]*65535);
6788 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
6789 extract4444rev(myswapBytes,iter,extractComponents);
6790 for (k = 0; k < 4; k++) {
6791 *iter2++ = (GLushort)(extractComponents[k]*65535);
6794 case GL_UNSIGNED_SHORT_5_5_5_1:
6795 extract5551(myswapBytes,iter,extractComponents);
6796 for (k = 0; k < 4; k++) {
6797 *iter2++ = (GLushort)(extractComponents[k]*65535);
6800 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
6801 extract1555rev(myswapBytes,iter,extractComponents);
6802 for (k = 0; k < 4; k++) {
6803 *iter2++ = (GLushort)(extractComponents[k]*65535);
6806 case GL_UNSIGNED_SHORT:
6809 widget.ub[0] = iter[1];
6810 widget.ub[1] = iter[0];
6812 widget.ub[0] = iter[0];
6813 widget.ub[1] = iter[1];
6815 if (type == GL_SHORT) {
6817 *iter2++ = widget.s[0];
6820 *iter2++ = widget.s[0]*2;
6823 *iter2++ = widget.us[0];
6826 case GL_UNSIGNED_INT_8_8_8_8:
6827 extract8888(myswapBytes,iter,extractComponents);
6828 for (k = 0; k < 4; k++) {
6829 *iter2++ = (GLushort)(extractComponents[k]*65535);
6832 case GL_UNSIGNED_INT_8_8_8_8_REV:
6833 extract8888rev(myswapBytes,iter,extractComponents);
6834 for (k = 0; k < 4; k++) {
6835 *iter2++ = (GLushort)(extractComponents[k]*65535);
6838 case GL_UNSIGNED_INT_10_10_10_2:
6839 extract1010102(myswapBytes,iter,extractComponents);
6840 for (k = 0; k < 4; k++) {
6841 *iter2++ = (GLushort)(extractComponents[k]*65535);
6844 case GL_UNSIGNED_INT_2_10_10_10_REV:
6845 extract2101010rev(myswapBytes,iter,extractComponents);
6846 for (k = 0; k < 4; k++) {
6847 *iter2++ = (GLushort)(extractComponents[k]*65535);
6851 case GL_UNSIGNED_INT:
6854 widget.ub[0] = iter[3];
6855 widget.ub[1] = iter[2];
6856 widget.ub[2] = iter[1];
6857 widget.ub[3] = iter[0];
6859 widget.ub[0] = iter[0];
6860 widget.ub[1] = iter[1];
6861 widget.ub[2] = iter[2];
6862 widget.ub[3] = iter[3];
6864 if (type == GL_FLOAT) {
6866 *iter2++ = widget.f;
6868 *iter2++ = 65535 * widget.f;
6870 } else if (type == GL_UNSIGNED_INT) {
6872 *iter2++ = widget.ui;
6874 *iter2++ = widget.ui >> 16;
6878 *iter2++ = widget.i;
6880 *iter2++ = widget.i >> 15;
6892 iter= rowStart; /* for assertion purposes */
6898 /* iterators should be one byte past end */
6899 if (!isTypePackedPixel(type)) {
6900 assert(iter2 == &newImage[width*height*depth*components]);
6903 assert(iter2 == &newImage[width*height*depth*
6904 elements_per_group(format,0)]);
6906 assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
6907 psm->unpack_skip_rows * rowSize +
6908 psm->unpack_skip_pixels * groupSize +
6910 psm->unpack_skip_images * imageSize] );
6911 } /* fillImage3D () */
6913 static void scaleInternal3D(GLint components,
6914 GLint widthIn, GLint heightIn, GLint depthIn,
6915 const GLushort *dataIn,
6916 GLint widthOut, GLint heightOut, GLint depthOut,
6919 float x, lowx, highx, convx, halfconvx;
6920 float y, lowy, highy, convy, halfconvy;
6921 float z, lowz, highz, convz, halfconvz;
6922 float xpercent,ypercent,zpercent;
6924 /* Max components in a format is 4, so... */
6927 int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
6930 convz = (float) depthIn/depthOut;
6931 convy = (float) heightIn/heightOut;
6932 convx = (float) widthIn/widthOut;
6933 halfconvx = convx/2;
6934 halfconvy = convy/2;
6935 halfconvz = convz/2;
6936 for (d = 0; d < depthOut; d++) {
6937 z = convz * (d+0.5);
6938 if (depthIn > depthOut) {
6939 highz = z + halfconvz;
6940 lowz = z - halfconvz;
6945 for (i = 0; i < heightOut; i++) {
6946 y = convy * (i+0.5);
6947 if (heightIn > heightOut) {
6948 highy = y + halfconvy;
6949 lowy = y - halfconvy;
6954 for (j = 0; j < widthOut; j++) {
6955 x = convx * (j+0.5);
6956 if (widthIn > widthOut) {
6957 highx = x + halfconvx;
6958 lowx = x - halfconvx;
6965 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6966 ** lowz) to (highx, highy, highz) on input data into this pixel
6969 totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
6975 zindex = (zint + depthIn) % depthIn;
6976 if (highz < zint+1) {
6977 zpercent = highz - z;
6979 zpercent = zint+1 - z;
6985 yindex = (yint + heightIn) % heightIn;
6986 if (highy < yint+1) {
6987 ypercent = highy - y;
6989 ypercent = yint+1 - y;
6996 xindex = (xint + widthIn) % widthIn;
6997 if (highx < xint+1) {
6998 xpercent = highx - x;
7000 xpercent = xint+1 - x;
7003 percent = xpercent * ypercent * zpercent;
7006 temp = (xindex + (yindex*widthIn) +
7007 (zindex*widthIn*heightIn)) * components;
7008 for (k = 0; k < components; k++) {
7009 assert(0 <= (temp+k) &&
7011 (widthIn*heightIn*depthIn*components));
7012 totals[k] += dataIn[temp + k] * percent;
7027 temp = (j + (i * widthOut) +
7028 (d*widthOut*heightOut)) * components;
7029 for (k = 0; k < components; k++) {
7030 /* totals[] should be rounded in the case of enlarging an
7031 * RGB ramp when the type is 332 or 4444
7033 assert(0 <= (temp+k) &&
7034 (temp+k) < (widthOut*heightOut*depthOut*components));
7035 dataOut[temp + k] = (totals[k]+0.5)/volume;
7040 } /* scaleInternal3D() */
7042 static void emptyImage3D(const PixelStorageModes *psm,
7043 GLint width, GLint height, GLint depth,
7044 GLenum format, GLenum type, GLboolean indexFormat,
7045 const GLushort *oldImage, void *userImage)
7054 GLubyte *start, *rowStart, *iter;
7055 int elementsPerLine;
7056 const GLushort *iter2;
7061 myswapBytes= psm->pack_swap_bytes;
7062 components = elements_per_group(format,type);
7063 if (psm->pack_row_length > 0) {
7064 groupsPerLine = psm->pack_row_length;
7067 groupsPerLine = width;
7070 elementSize= bytes_per_element(type);
7071 groupSize= elementSize * components;
7072 if (elementSize == 1) myswapBytes= 0;
7075 if (psm->pack_image_height > 0) {
7076 rowsPerImage= psm->pack_image_height;
7079 rowsPerImage= height;
7084 rowSize = groupsPerLine * groupSize;
7085 padding = rowSize % psm->pack_alignment;
7087 rowSize+= psm->pack_alignment - padding;
7090 imageSize= rowsPerImage * rowSize; /* 3dstuff */
7092 start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
7093 psm->pack_skip_pixels * groupSize +
7095 psm->pack_skip_images * imageSize;
7096 elementsPerLine= width * components;
7099 for (dd= 0; dd < depth; dd++) {
7102 for (ii= 0; ii< height; ii++) {
7105 for (jj = 0; jj < elementsPerLine; jj++) {
7107 float shoveComponents[4];
7110 case GL_UNSIGNED_BYTE:
7114 *iter = *iter2++ >> 8;
7119 *((GLbyte *) iter) = *iter2++;
7121 *((GLbyte *) iter) = *iter2++ >> 9;
7124 case GL_UNSIGNED_BYTE_3_3_2:
7125 for (k = 0; k < 3; k++) {
7126 shoveComponents[k]= *iter2++ / 65535.0;
7128 shove332(shoveComponents,0,(void *)iter);
7130 case GL_UNSIGNED_BYTE_2_3_3_REV:
7131 for (k = 0; k < 3; k++) {
7132 shoveComponents[k]= *iter2++ / 65535.0;
7134 shove233rev(shoveComponents,0,(void *)iter);
7136 case GL_UNSIGNED_SHORT_5_6_5:
7137 for (k = 0; k < 3; k++) {
7138 shoveComponents[k]= *iter2++ / 65535.0;
7140 shove565(shoveComponents,0,(void *)&widget.us[0]);
7142 iter[0] = widget.ub[1];
7143 iter[1] = widget.ub[0];
7146 *(GLushort *)iter = widget.us[0];
7149 case GL_UNSIGNED_SHORT_5_6_5_REV:
7150 for (k = 0; k < 3; k++) {
7151 shoveComponents[k]= *iter2++ / 65535.0;
7153 shove565rev(shoveComponents,0,(void *)&widget.us[0]);
7155 iter[0] = widget.ub[1];
7156 iter[1] = widget.ub[0];
7159 *(GLushort *)iter = widget.us[0];
7162 case GL_UNSIGNED_SHORT_4_4_4_4:
7163 for (k = 0; k < 4; k++) {
7164 shoveComponents[k]= *iter2++ / 65535.0;
7166 shove4444(shoveComponents,0,(void *)&widget.us[0]);
7168 iter[0] = widget.ub[1];
7169 iter[1] = widget.ub[0];
7171 *(GLushort *)iter = widget.us[0];
7174 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7175 for (k = 0; k < 4; k++) {
7176 shoveComponents[k]= *iter2++ / 65535.0;
7178 shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
7180 iter[0] = widget.ub[1];
7181 iter[1] = widget.ub[0];
7183 *(GLushort *)iter = widget.us[0];
7186 case GL_UNSIGNED_SHORT_5_5_5_1:
7187 for (k = 0; k < 4; k++) {
7188 shoveComponents[k]= *iter2++ / 65535.0;
7190 shove5551(shoveComponents,0,(void *)&widget.us[0]);
7192 iter[0] = widget.ub[1];
7193 iter[1] = widget.ub[0];
7195 *(GLushort *)iter = widget.us[0];
7198 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7199 for (k = 0; k < 4; k++) {
7200 shoveComponents[k]= *iter2++ / 65535.0;
7202 shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
7204 iter[0] = widget.ub[1];
7205 iter[1] = widget.ub[0];
7207 *(GLushort *)iter = widget.us[0];
7210 case GL_UNSIGNED_SHORT:
7212 if (type == GL_SHORT) {
7214 widget.s[0] = *iter2++;
7216 widget.s[0] = *iter2++ >> 1;
7219 widget.us[0] = *iter2++;
7222 iter[0] = widget.ub[1];
7223 iter[1] = widget.ub[0];
7225 iter[0] = widget.ub[0];
7226 iter[1] = widget.ub[1];
7229 case GL_UNSIGNED_INT_8_8_8_8:
7230 for (k = 0; k < 4; k++) {
7231 shoveComponents[k]= *iter2++ / 65535.0;
7233 shove8888(shoveComponents,0,(void *)&widget.ui);
7235 iter[3] = widget.ub[0];
7236 iter[2] = widget.ub[1];
7237 iter[1] = widget.ub[2];
7238 iter[0] = widget.ub[3];
7240 *(GLuint *)iter= widget.ui;
7243 case GL_UNSIGNED_INT_8_8_8_8_REV:
7244 for (k = 0; k < 4; k++) {
7245 shoveComponents[k]= *iter2++ / 65535.0;
7247 shove8888rev(shoveComponents,0,(void *)&widget.ui);
7249 iter[3] = widget.ub[0];
7250 iter[2] = widget.ub[1];
7251 iter[1] = widget.ub[2];
7252 iter[0] = widget.ub[3];
7254 *(GLuint *)iter= widget.ui;
7257 case GL_UNSIGNED_INT_10_10_10_2:
7258 for (k = 0; k < 4; k++) {
7259 shoveComponents[k]= *iter2++ / 65535.0;
7261 shove1010102(shoveComponents,0,(void *)&widget.ui);
7263 iter[3] = widget.ub[0];
7264 iter[2] = widget.ub[1];
7265 iter[1] = widget.ub[2];
7266 iter[0] = widget.ub[3];
7268 *(GLuint *)iter= widget.ui;
7271 case GL_UNSIGNED_INT_2_10_10_10_REV:
7272 for (k = 0; k < 4; k++) {
7273 shoveComponents[k]= *iter2++ / 65535.0;
7275 shove2101010rev(shoveComponents,0,(void *)&widget.ui);
7277 iter[3] = widget.ub[0];
7278 iter[2] = widget.ub[1];
7279 iter[1] = widget.ub[2];
7280 iter[0] = widget.ub[3];
7282 *(GLuint *)iter= widget.ui;
7286 case GL_UNSIGNED_INT:
7288 if (type == GL_FLOAT) {
7290 widget.f = *iter2++;
7292 widget.f = *iter2++ / (float) 65535.0;
7294 } else if (type == GL_UNSIGNED_INT) {
7296 widget.ui = *iter2++;
7298 widget.ui = (unsigned int) *iter2++ * 65537;
7302 widget.i = *iter2++;
7304 widget.i = ((unsigned int) *iter2++ * 65537)/2;
7308 iter[3] = widget.ub[0];
7309 iter[2] = widget.ub[1];
7310 iter[1] = widget.ub[2];
7311 iter[0] = widget.ub[3];
7313 iter[0] = widget.ub[0];
7314 iter[1] = widget.ub[1];
7315 iter[2] = widget.ub[2];
7316 iter[3] = widget.ub[3];
7332 /* iterators should be one byte past end */
7333 if (!isTypePackedPixel(type)) {
7334 assert(iter2 == &oldImage[width*height*depth*components]);
7337 assert(iter2 == &oldImage[width*height*depth*
7338 elements_per_group(format,0)]);
7340 assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
7341 psm->unpack_skip_rows * rowSize +
7342 psm->unpack_skip_pixels * groupSize +
7344 psm->unpack_skip_images * imageSize] );
7345 } /* emptyImage3D() */
7348 int gluScaleImage3D(GLenum format,
7349 GLint widthIn, GLint heightIn, GLint depthIn,
7350 GLenum typeIn, const void *dataIn,
7351 GLint widthOut, GLint heightOut, GLint depthOut,
7352 GLenum typeOut, void *dataOut)
7355 GLushort *beforeImage, *afterImage;
7356 PixelStorageModes psm;
7358 if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
7359 widthOut == 0 || heightOut == 0 || depthOut == 0) {
7363 if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
7364 widthOut < 0 || heightOut < 0 || depthOut < 0) {
7365 return GLU_INVALID_VALUE;
7368 if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
7369 typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
7370 return GLU_INVALID_ENUM;
7372 if (!isLegalFormatForPackedPixelType(format, typeIn)) {
7373 return GLU_INVALID_OPERATION;
7375 if (!isLegalFormatForPackedPixelType(format, typeOut)) {
7376 return GLU_INVALID_OPERATION;
7379 beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
7380 GL_UNSIGNED_SHORT));
7381 afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
7382 GL_UNSIGNED_SHORT));
7383 if (beforeImage == NULL || afterImage == NULL) {
7384 return GLU_OUT_OF_MEMORY;
7386 retrieveStoreModes3D(&psm);
7388 fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
7389 dataIn, beforeImage);
7390 components = elements_per_group(format,0);
7391 scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
7392 widthOut,heightOut,depthOut,afterImage);
7393 emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
7394 is_index(format),afterImage, dataOut);
7395 free((void *) beforeImage);
7396 free((void *) afterImage);
7399 } /* gluScaleImage3D() */
7402 static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
7403 GLint internalFormat, GLenum format, GLenum type,
7404 GLint *newWidth, GLint *newHeight, GLint *newDepth)
7406 GLint widthPowerOf2= nearestPower(width);
7407 GLint heightPowerOf2= nearestPower(height);
7408 GLint depthPowerOf2= nearestPower(depth);
7412 /* compute level 1 width & height & depth, clamping each at 1 */
7413 GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
7414 widthPowerOf2 >> 1 :
7416 GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
7417 heightPowerOf2 >> 1 :
7419 GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
7420 depthPowerOf2 >> 1 :
7422 GLenum proxyTarget = GL_PROXY_TEXTURE_3D;
7423 assert(widthAtLevelOne > 0);
7424 assert(heightAtLevelOne > 0);
7425 assert(depthAtLevelOne > 0);
7427 /* does width x height x depth at level 1 & all their mipmaps fit? */
7428 assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D);
7429 gluTexImage3D(proxyTarget, 1, /* must be non-zero */
7431 widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
7432 0,format,type,NULL);
7433 glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
7434 /* does it fit??? */
7435 if (proxyWidth == 0) { /* nope, so try again with these sizes */
7436 if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
7437 depthPowerOf2 == 1) {
7438 *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
7441 widthPowerOf2= widthAtLevelOne;
7442 heightPowerOf2= heightAtLevelOne;
7443 depthPowerOf2= depthAtLevelOne;
7445 /* else it does fit */
7446 } while (proxyWidth == 0);
7447 /* loop must terminate! */
7449 /* return the width & height at level 0 that fits */
7450 *newWidth= widthPowerOf2;
7451 *newHeight= heightPowerOf2;
7452 *newDepth= depthPowerOf2;
7453 /*printf("Proxy Textures\n");*/
7454 } /* closestFit3D() */
7456 static void halveImagePackedPixelSlice(int components,
7457 void (*extractPackedPixel)
7458 (int, const void *,GLfloat []),
7459 void (*shovePackedPixel)
7460 (const GLfloat [],int, void *),
7461 GLint width, GLint height, GLint depth,
7462 const void *dataIn, void *dataOut,
7463 GLint pixelSizeInBytes,
7464 GLint rowSizeInBytes,
7465 GLint imageSizeInBytes,
7469 int halfWidth= width / 2;
7470 int halfHeight= height / 2;
7471 int halfDepth= depth / 2;
7472 const char *src= (const char *)dataIn;
7475 assert((width == 1 || height == 1) && depth >= 2);
7477 if (width == height) { /* a 1-pixel column viewed from top */
7478 assert(width == 1 && height == 1);
7481 for (ii= 0; ii< halfDepth; ii++) {
7483 float extractTotals[BOX2][4];
7486 (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
7487 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7488 &extractTotals[1][0]);
7489 for (cc = 0; cc < components; cc++) {
7492 /* average 2 pixels since only a column */
7494 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7495 * totals[RED]/= 2.0;
7497 for (kk = 0; kk < BOX2; kk++) {
7498 totals[cc]+= extractTotals[kk][cc];
7500 totals[cc]/= (float)BOX2;
7503 (*shovePackedPixel)(totals,outIndex,dataOut);
7505 /* skip over to next group of 2 */
7506 src+= imageSizeInBytes + imageSizeInBytes;
7509 else if (height == 1) { /* horizontal slice viewed from top */
7512 for (ii= 0; ii< halfDepth; ii++) {
7513 for (jj= 0; jj< halfWidth; jj++) {
7515 float extractTotals[BOX4][4];
7518 (*extractPackedPixel)(isSwap,src,
7519 &extractTotals[0][0]);
7520 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7521 &extractTotals[1][0]);
7522 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7523 &extractTotals[2][0]);
7524 (*extractPackedPixel)(isSwap,
7525 (src+imageSizeInBytes+pixelSizeInBytes),
7526 &extractTotals[3][0]);
7527 for (cc = 0; cc < components; cc++) {
7530 /* grab 4 pixels to average */
7532 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7533 * extractTotals[2][RED]+extractTotals[3][RED];
7534 * totals[RED]/= 4.0;
7536 for (kk = 0; kk < BOX4; kk++) {
7537 totals[cc]+= extractTotals[kk][cc];
7539 totals[cc]/= (float)BOX4;
7541 (*shovePackedPixel)(totals,outIndex,dataOut);
7544 /* skip over to next horizontal square of 4 */
7545 src+= imageSizeInBytes + imageSizeInBytes;
7551 else if (width == 1) { /* vertical slice viewed from top */
7552 assert(height != 1);
7554 for (ii= 0; ii< halfDepth; ii++) {
7555 for (jj= 0; jj< halfHeight; jj++) {
7557 float extractTotals[BOX4][4];
7560 (*extractPackedPixel)(isSwap,src,
7561 &extractTotals[0][0]);
7562 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7563 &extractTotals[1][0]);
7564 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7565 &extractTotals[2][0]);
7566 (*extractPackedPixel)(isSwap,
7567 (src+imageSizeInBytes+rowSizeInBytes),
7568 &extractTotals[3][0]);
7569 for (cc = 0; cc < components; cc++) {
7572 /* grab 4 pixels to average */
7574 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7575 * extractTotals[2][RED]+extractTotals[3][RED];
7576 * totals[RED]/= 4.0;
7578 for (kk = 0; kk < BOX4; kk++) {
7579 totals[cc]+= extractTotals[kk][cc];
7581 totals[cc]/= (float)BOX4;
7583 (*shovePackedPixel)(totals,outIndex,dataOut);
7587 /* skip over to next vertical square of 4 */
7588 src+= imageSizeInBytes + imageSizeInBytes;
7594 } /* halveImagePackedPixelSlice() */
7596 static void halveImagePackedPixel3D(int components,
7597 void (*extractPackedPixel)
7598 (int, const void *,GLfloat []),
7599 void (*shovePackedPixel)
7600 (const GLfloat [],int, void *),
7601 GLint width, GLint height, GLint depth,
7602 const void *dataIn, void *dataOut,
7603 GLint pixelSizeInBytes,
7604 GLint rowSizeInBytes,
7605 GLint imageSizeInBytes,
7609 assert(1 <= width && 1 <= height);
7611 halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
7612 width,height,dataIn,dataOut,pixelSizeInBytes,
7613 rowSizeInBytes,isSwap);
7616 /* a horizontal or vertical slice viewed from top */
7617 else if (width == 1 || height == 1) {
7620 halveImagePackedPixelSlice(components,
7621 extractPackedPixel,shovePackedPixel,
7622 width, height, depth, dataIn, dataOut,
7623 pixelSizeInBytes, rowSizeInBytes,
7624 imageSizeInBytes, isSwap);
7630 int halfWidth= width / 2;
7631 int halfHeight= height / 2;
7632 int halfDepth= depth / 2;
7633 const char *src= (const char *) dataIn;
7634 int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
7637 for (dd= 0; dd < halfDepth; dd++) {
7638 for (ii= 0; ii< halfHeight; ii++) {
7639 for (jj= 0; jj< halfWidth; jj++) {
7641 float totals[4]; /* 4 is maximum components */
7642 float extractTotals[BOX8][4]; /* 4 is maximum components */
7645 (*extractPackedPixel)(isSwap,src,
7646 &extractTotals[0][0]);
7647 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
7648 &extractTotals[1][0]);
7649 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
7650 &extractTotals[2][0]);
7651 (*extractPackedPixel)(isSwap,
7652 (src+rowSizeInBytes+pixelSizeInBytes),
7653 &extractTotals[3][0]);
7655 (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
7656 &extractTotals[4][0]);
7657 (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
7658 &extractTotals[5][0]);
7659 (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
7660 &extractTotals[6][0]);
7661 (*extractPackedPixel)(isSwap,
7662 (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
7663 &extractTotals[7][0]);
7664 for (cc = 0; cc < components; cc++) {
7667 /* grab 8 pixels to average */
7669 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7670 * extractTotals[2][RED]+extractTotals[3][RED]+
7671 * extractTotals[4][RED]+extractTotals[5][RED]+
7672 * extractTotals[6][RED]+extractTotals[7][RED];
7673 * totals[RED]/= 8.0;
7675 for (kk = 0; kk < BOX8; kk++) {
7676 totals[cc]+= extractTotals[kk][cc];
7678 totals[cc]/= (float)BOX8;
7680 (*shovePackedPixel)(totals,outIndex,dataOut);
7683 /* skip over to next square of 4 */
7684 src+= pixelSizeInBytes + pixelSizeInBytes;
7686 /* skip past pad bytes, if any, to get to next row */
7689 /* src is at beginning of a row here, but it's the second row of
7690 * the square block of 4 pixels that we just worked on so we
7691 * need to go one more row.
7699 src+= rowSizeInBytes;
7702 src+= imageSizeInBytes;
7705 /* both pointers must reach one byte after the end */
7706 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
7707 assert(outIndex == halfWidth * halfHeight * halfDepth);
7710 } /* halveImagePackedPixel3D() */
7712 static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
7716 GLsizei widthPowerOf2,
7717 GLsizei heightPowerOf2,
7718 GLsizei depthPowerOf2,
7719 GLenum format, GLenum type,
7721 GLint baseLevel,GLint maxLevel,
7724 GLint newWidth, newHeight, newDepth;
7725 GLint level, levels;
7726 const void *usersImage;
7727 void *srcImage, *dstImage;
7728 __GLU_INIT_SWAP_IMAGE;
7732 GLint myswapBytes, groupsPerLine, elementSize, groupSize;
7733 GLint rowsPerImage, imageSize;
7734 GLint rowSize, padding;
7735 PixelStorageModes psm;
7737 assert(checkMipmapArgs(internalFormat,format,type) == 0);
7738 assert(width >= 1 && height >= 1 && depth >= 1);
7739 assert(type != GL_BITMAP);
7741 srcImage = dstImage = NULL;
7743 newWidth= widthPowerOf2;
7744 newHeight= heightPowerOf2;
7745 newDepth= depthPowerOf2;
7746 levels = computeLog(newWidth);
7747 level = computeLog(newHeight);
7748 if (level > levels) levels=level;
7749 level = computeLog(newDepth);
7750 if (level > levels) levels=level;
7754 retrieveStoreModes3D(&psm);
7755 myswapBytes = psm.unpack_swap_bytes;
7756 cmpts = elements_per_group(format,type);
7757 if (psm.unpack_row_length > 0) {
7758 groupsPerLine = psm.unpack_row_length;
7760 groupsPerLine = width;
7763 elementSize = bytes_per_element(type);
7764 groupSize = elementSize * cmpts;
7765 if (elementSize == 1) myswapBytes = 0;
7768 if (psm.unpack_image_height > 0) {
7769 rowsPerImage= psm.unpack_image_height;
7772 rowsPerImage= height;
7776 rowSize = groupsPerLine * groupSize;
7777 padding = (rowSize % psm.unpack_alignment);
7779 rowSize += psm.unpack_alignment - padding;
7782 imageSize= rowsPerImage * rowSize; /* 3dstuff */
7784 usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
7785 psm.unpack_skip_pixels * groupSize +
7787 psm.unpack_skip_images * imageSize;
7789 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
7790 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
7791 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
7792 glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
7793 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
7797 if (width == newWidth && height == newHeight && depth == newDepth) {
7798 /* Use usersImage for level userLevel */
7799 if (baseLevel <= level && level <= maxLevel) {
7800 gluTexImage3D(target, level, internalFormat, width,
7801 height, depth, 0, format, type,
7804 if(levels == 0) { /* we're done. clean up and return */
7805 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7806 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7807 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7808 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7809 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7810 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7811 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7815 int nextWidth= newWidth/2;
7816 int nextHeight= newHeight/2;
7817 int nextDepth= newDepth/2;
7820 if (nextWidth < 1) nextWidth= 1;
7821 if (nextHeight < 1) nextHeight= 1;
7822 if (nextDepth < 1) nextDepth= 1;
7823 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
7826 case GL_UNSIGNED_BYTE:
7827 dstImage = (GLubyte *)malloc(memReq);
7830 dstImage = (GLbyte *)malloc(memReq);
7832 case GL_UNSIGNED_SHORT:
7833 dstImage = (GLushort *)malloc(memReq);
7836 dstImage = (GLshort *)malloc(memReq);
7838 case GL_UNSIGNED_INT:
7839 dstImage = (GLuint *)malloc(memReq);
7842 dstImage = (GLint *)malloc(memReq);
7845 dstImage = (GLfloat *)malloc(memReq);
7847 case GL_UNSIGNED_BYTE_3_3_2:
7848 case GL_UNSIGNED_BYTE_2_3_3_REV:
7849 dstImage = (GLubyte *)malloc(memReq);
7851 case GL_UNSIGNED_SHORT_5_6_5:
7852 case GL_UNSIGNED_SHORT_5_6_5_REV:
7853 case GL_UNSIGNED_SHORT_4_4_4_4:
7854 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7855 case GL_UNSIGNED_SHORT_5_5_5_1:
7856 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
7857 dstImage = (GLushort *)malloc(memReq);
7859 case GL_UNSIGNED_INT_8_8_8_8:
7860 case GL_UNSIGNED_INT_8_8_8_8_REV:
7861 case GL_UNSIGNED_INT_10_10_10_2:
7862 case GL_UNSIGNED_INT_2_10_10_10_REV:
7863 dstImage = (GLuint *)malloc(memReq);
7866 return GLU_INVALID_ENUM; /* assertion */
7868 if (dstImage == NULL) {
7869 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
7870 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
7871 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
7872 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
7873 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
7874 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
7875 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
7876 return GLU_OUT_OF_MEMORY;
7880 case GL_UNSIGNED_BYTE:
7882 halveImage3D(cmpts,extractUbyte,shoveUbyte,
7884 usersImage,dstImage,elementSize,groupSize,rowSize,
7885 imageSize,myswapBytes);
7888 halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
7889 elementSize,rowSize,groupSize);
7894 halveImage3D(cmpts,extractSbyte,shoveSbyte,
7896 usersImage,dstImage,elementSize,groupSize,rowSize,
7897 imageSize,myswapBytes);
7900 halveImage_byte(cmpts,width,height,usersImage,dstImage,
7901 elementSize,rowSize,groupSize);
7904 case GL_UNSIGNED_SHORT:
7906 halveImage3D(cmpts,extractUshort,shoveUshort,
7908 usersImage,dstImage,elementSize,groupSize,rowSize,
7909 imageSize,myswapBytes);
7912 halveImage_ushort(cmpts,width,height,usersImage,dstImage,
7913 elementSize,rowSize,groupSize,myswapBytes);
7918 halveImage3D(cmpts,extractSshort,shoveSshort,
7920 usersImage,dstImage,elementSize,groupSize,rowSize,
7921 imageSize,myswapBytes);
7924 halveImage_short(cmpts,width,height,usersImage,dstImage,
7925 elementSize,rowSize,groupSize,myswapBytes);
7928 case GL_UNSIGNED_INT:
7930 halveImage3D(cmpts,extractUint,shoveUint,
7932 usersImage,dstImage,elementSize,groupSize,rowSize,
7933 imageSize,myswapBytes);
7936 halveImage_uint(cmpts,width,height,usersImage,dstImage,
7937 elementSize,rowSize,groupSize,myswapBytes);
7942 halveImage3D(cmpts,extractSint,shoveSint,
7944 usersImage,dstImage,elementSize,groupSize,rowSize,
7945 imageSize,myswapBytes);
7948 halveImage_int(cmpts,width,height,usersImage,dstImage,
7949 elementSize,rowSize,groupSize,myswapBytes);
7954 halveImage3D(cmpts,extractFloat,shoveFloat,
7956 usersImage,dstImage,elementSize,groupSize,rowSize,
7957 imageSize,myswapBytes);
7960 halveImage_float(cmpts,width,height,usersImage,dstImage,
7961 elementSize,rowSize,groupSize,myswapBytes);
7964 case GL_UNSIGNED_BYTE_3_3_2:
7965 assert(format == GL_RGB);
7966 halveImagePackedPixel3D(3,extract332,shove332,
7967 width,height,depth,usersImage,dstImage,
7968 elementSize,rowSize,imageSize,myswapBytes);
7970 case GL_UNSIGNED_BYTE_2_3_3_REV:
7971 assert(format == GL_RGB);
7972 halveImagePackedPixel3D(3,extract233rev,shove233rev,
7973 width,height,depth,usersImage,dstImage,
7974 elementSize,rowSize,imageSize,myswapBytes);
7976 case GL_UNSIGNED_SHORT_5_6_5:
7977 halveImagePackedPixel3D(3,extract565,shove565,
7978 width,height,depth,usersImage,dstImage,
7979 elementSize,rowSize,imageSize,myswapBytes);
7981 case GL_UNSIGNED_SHORT_5_6_5_REV:
7982 halveImagePackedPixel3D(3,extract565rev,shove565rev,
7983 width,height,depth,usersImage,dstImage,
7984 elementSize,rowSize,imageSize,myswapBytes);
7986 case GL_UNSIGNED_SHORT_4_4_4_4:
7987 halveImagePackedPixel3D(4,extract4444,shove4444,
7988 width,height,depth,usersImage,dstImage,
7989 elementSize,rowSize,imageSize,myswapBytes);
7991 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
7992 halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
7993 width,height,depth,usersImage,dstImage,
7994 elementSize,rowSize,imageSize,myswapBytes);
7996 case GL_UNSIGNED_SHORT_5_5_5_1:
7997 halveImagePackedPixel3D(4,extract5551,shove5551,
7998 width,height,depth,usersImage,dstImage,
7999 elementSize,rowSize,imageSize,myswapBytes);
8001 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8002 halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8003 width,height,depth,usersImage,dstImage,
8004 elementSize,rowSize,imageSize,myswapBytes);
8006 case GL_UNSIGNED_INT_8_8_8_8:
8007 halveImagePackedPixel3D(4,extract8888,shove8888,
8008 width,height,depth,usersImage,dstImage,
8009 elementSize,rowSize,imageSize,myswapBytes);
8011 case GL_UNSIGNED_INT_8_8_8_8_REV:
8012 halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8013 width,height,depth,usersImage,dstImage,
8014 elementSize,rowSize,imageSize,myswapBytes);
8016 case GL_UNSIGNED_INT_10_10_10_2:
8017 halveImagePackedPixel3D(4,extract1010102,shove1010102,
8018 width,height,depth,usersImage,dstImage,
8019 elementSize,rowSize,imageSize,myswapBytes);
8021 case GL_UNSIGNED_INT_2_10_10_10_REV:
8022 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8023 width,height,depth,usersImage,dstImage,
8024 elementSize,rowSize,imageSize,myswapBytes);
8031 newHeight = height/2;
8034 if (newWidth < 1) newWidth= 1;
8035 if (newHeight < 1) newHeight= 1;
8036 if (newDepth < 1) newDepth= 1;
8039 rowSize = newWidth * groupSize;
8040 imageSize= rowSize * newHeight; /* 3dstuff */
8041 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8042 /* Swap srcImage and dstImage */
8043 __GLU_SWAP_IMAGE(srcImage,dstImage);
8045 case GL_UNSIGNED_BYTE:
8046 dstImage = (GLubyte *)malloc(memReq);
8049 dstImage = (GLbyte *)malloc(memReq);
8051 case GL_UNSIGNED_SHORT:
8052 dstImage = (GLushort *)malloc(memReq);
8055 dstImage = (GLshort *)malloc(memReq);
8057 case GL_UNSIGNED_INT:
8058 dstImage = (GLuint *)malloc(memReq);
8061 dstImage = (GLint *)malloc(memReq);
8064 dstImage = (GLfloat *)malloc(memReq);
8066 case GL_UNSIGNED_BYTE_3_3_2:
8067 case GL_UNSIGNED_BYTE_2_3_3_REV:
8068 dstImage = (GLubyte *)malloc(memReq);
8070 case GL_UNSIGNED_SHORT_5_6_5:
8071 case GL_UNSIGNED_SHORT_5_6_5_REV:
8072 case GL_UNSIGNED_SHORT_4_4_4_4:
8073 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8074 case GL_UNSIGNED_SHORT_5_5_5_1:
8075 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8076 dstImage = (GLushort *)malloc(memReq);
8078 case GL_UNSIGNED_INT_8_8_8_8:
8079 case GL_UNSIGNED_INT_8_8_8_8_REV:
8080 case GL_UNSIGNED_INT_10_10_10_2:
8081 case GL_UNSIGNED_INT_2_10_10_10_REV:
8082 dstImage = (GLuint *)malloc(memReq);
8085 return GLU_INVALID_ENUM; /* assertion */
8087 if (dstImage == NULL) {
8088 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8089 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8090 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8091 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8092 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8093 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8094 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8095 return GLU_OUT_OF_MEMORY;
8097 /* level userLevel+1 is in srcImage; level userLevel already saved */
8098 level = userLevel+1;
8099 } else {/* user's image is *not* nice power-of-2 sized square */
8100 memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
8102 case GL_UNSIGNED_BYTE:
8103 dstImage = (GLubyte *)malloc(memReq);
8106 dstImage = (GLbyte *)malloc(memReq);
8108 case GL_UNSIGNED_SHORT:
8109 dstImage = (GLushort *)malloc(memReq);
8112 dstImage = (GLshort *)malloc(memReq);
8114 case GL_UNSIGNED_INT:
8115 dstImage = (GLuint *)malloc(memReq);
8118 dstImage = (GLint *)malloc(memReq);
8121 dstImage = (GLfloat *)malloc(memReq);
8123 case GL_UNSIGNED_BYTE_3_3_2:
8124 case GL_UNSIGNED_BYTE_2_3_3_REV:
8125 dstImage = (GLubyte *)malloc(memReq);
8127 case GL_UNSIGNED_SHORT_5_6_5:
8128 case GL_UNSIGNED_SHORT_5_6_5_REV:
8129 case GL_UNSIGNED_SHORT_4_4_4_4:
8130 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8131 case GL_UNSIGNED_SHORT_5_5_5_1:
8132 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8133 dstImage = (GLushort *)malloc(memReq);
8135 case GL_UNSIGNED_INT_8_8_8_8:
8136 case GL_UNSIGNED_INT_8_8_8_8_REV:
8137 case GL_UNSIGNED_INT_10_10_10_2:
8138 case GL_UNSIGNED_INT_2_10_10_10_REV:
8139 dstImage = (GLuint *)malloc(memReq);
8142 return GLU_INVALID_ENUM; /* assertion */
8145 if (dstImage == NULL) {
8146 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8147 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8148 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8149 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8150 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8151 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8152 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8153 return GLU_OUT_OF_MEMORY;
8155 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8156 width,height,depth,newWidth,newHeight,newDepth);*/
8158 gluScaleImage3D(format, width, height, depth, type, usersImage,
8159 newWidth, newHeight, newDepth, type, dstImage);
8162 rowSize = newWidth * groupSize;
8163 imageSize = rowSize * newHeight; /* 3dstuff */
8164 /* Swap dstImage and srcImage */
8165 __GLU_SWAP_IMAGE(srcImage,dstImage);
8167 if(levels != 0) { /* use as little memory as possible */
8169 int nextWidth= newWidth/2;
8170 int nextHeight= newHeight/2;
8171 int nextDepth= newDepth/2;
8172 if (nextWidth < 1) nextWidth= 1;
8173 if (nextHeight < 1) nextHeight= 1;
8174 if (nextDepth < 1) nextDepth= 1;
8176 memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
8179 case GL_UNSIGNED_BYTE:
8180 dstImage = (GLubyte *)malloc(memReq);
8183 dstImage = (GLbyte *)malloc(memReq);
8185 case GL_UNSIGNED_SHORT:
8186 dstImage = (GLushort *)malloc(memReq);
8189 dstImage = (GLshort *)malloc(memReq);
8191 case GL_UNSIGNED_INT:
8192 dstImage = (GLuint *)malloc(memReq);
8195 dstImage = (GLint *)malloc(memReq);
8198 dstImage = (GLfloat *)malloc(memReq);
8200 case GL_UNSIGNED_BYTE_3_3_2:
8201 case GL_UNSIGNED_BYTE_2_3_3_REV:
8202 dstImage = (GLubyte *)malloc(memReq);
8204 case GL_UNSIGNED_SHORT_5_6_5:
8205 case GL_UNSIGNED_SHORT_5_6_5_REV:
8206 case GL_UNSIGNED_SHORT_4_4_4_4:
8207 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8208 case GL_UNSIGNED_SHORT_5_5_5_1:
8209 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8210 dstImage = (GLushort *)malloc(memReq);
8212 case GL_UNSIGNED_INT_8_8_8_8:
8213 case GL_UNSIGNED_INT_8_8_8_8_REV:
8214 case GL_UNSIGNED_INT_10_10_10_2:
8215 case GL_UNSIGNED_INT_2_10_10_10_REV:
8216 dstImage = (GLuint *)malloc(memReq);
8219 return GLU_INVALID_ENUM; /* assertion */
8221 if (dstImage == NULL) {
8222 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8223 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8224 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8225 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8226 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8227 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8228 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8229 return GLU_OUT_OF_MEMORY;
8232 /* level userLevel is in srcImage; nothing saved yet */
8236 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
8237 if (baseLevel <= level && level <= maxLevel) {
8238 gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
8239 0,format, type, (void *)srcImage);
8241 level++; /* update current level for the loop */
8242 for (; level <= levels; level++) {
8244 case GL_UNSIGNED_BYTE:
8246 halveImage3D(cmpts,extractUbyte,shoveUbyte,
8247 newWidth,newHeight,newDepth,
8248 srcImage,dstImage,elementSize,groupSize,rowSize,
8249 imageSize,myswapBytes);
8252 halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
8253 elementSize,rowSize,groupSize);
8258 halveImage3D(cmpts,extractSbyte,shoveSbyte,
8259 newWidth,newHeight,newDepth,
8260 srcImage,dstImage,elementSize,groupSize,rowSize,
8261 imageSize,myswapBytes);
8264 halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
8265 elementSize,rowSize,groupSize);
8268 case GL_UNSIGNED_SHORT:
8270 halveImage3D(cmpts,extractUshort,shoveUshort,
8271 newWidth,newHeight,newDepth,
8272 srcImage,dstImage,elementSize,groupSize,rowSize,
8273 imageSize,myswapBytes);
8276 halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
8277 elementSize,rowSize,groupSize,myswapBytes);
8282 halveImage3D(cmpts,extractSshort,shoveSshort,
8283 newWidth,newHeight,newDepth,
8284 srcImage,dstImage,elementSize,groupSize,rowSize,
8285 imageSize,myswapBytes);
8288 halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
8289 elementSize,rowSize,groupSize,myswapBytes);
8292 case GL_UNSIGNED_INT:
8294 halveImage3D(cmpts,extractUint,shoveUint,
8295 newWidth,newHeight,newDepth,
8296 srcImage,dstImage,elementSize,groupSize,rowSize,
8297 imageSize,myswapBytes);
8300 halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
8301 elementSize,rowSize,groupSize,myswapBytes);
8306 halveImage3D(cmpts,extractSint,shoveSint,
8307 newWidth,newHeight,newDepth,
8308 srcImage,dstImage,elementSize,groupSize,rowSize,
8309 imageSize,myswapBytes);
8312 halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
8313 elementSize,rowSize,groupSize,myswapBytes);
8318 halveImage3D(cmpts,extractFloat,shoveFloat,
8319 newWidth,newHeight,newDepth,
8320 srcImage,dstImage,elementSize,groupSize,rowSize,
8321 imageSize,myswapBytes);
8324 halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
8325 elementSize,rowSize,groupSize,myswapBytes);
8328 case GL_UNSIGNED_BYTE_3_3_2:
8329 halveImagePackedPixel3D(3,extract332,shove332,
8330 newWidth,newHeight,newDepth,
8331 srcImage,dstImage,elementSize,rowSize,
8332 imageSize,myswapBytes);
8334 case GL_UNSIGNED_BYTE_2_3_3_REV:
8335 halveImagePackedPixel3D(3,extract233rev,shove233rev,
8336 newWidth,newHeight,newDepth,
8337 srcImage,dstImage,elementSize,rowSize,
8338 imageSize,myswapBytes);
8340 case GL_UNSIGNED_SHORT_5_6_5:
8341 halveImagePackedPixel3D(3,extract565,shove565,
8342 newWidth,newHeight,newDepth,
8343 srcImage,dstImage,elementSize,rowSize,
8344 imageSize,myswapBytes);
8346 case GL_UNSIGNED_SHORT_5_6_5_REV:
8347 halveImagePackedPixel3D(3,extract565rev,shove565rev,
8348 newWidth,newHeight,newDepth,
8349 srcImage,dstImage,elementSize,rowSize,
8350 imageSize,myswapBytes);
8352 case GL_UNSIGNED_SHORT_4_4_4_4:
8353 halveImagePackedPixel3D(4,extract4444,shove4444,
8354 newWidth,newHeight,newDepth,
8355 srcImage,dstImage,elementSize,rowSize,
8356 imageSize,myswapBytes);
8358 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
8359 halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
8360 newWidth,newHeight,newDepth,
8361 srcImage,dstImage,elementSize,rowSize,
8362 imageSize,myswapBytes);
8364 case GL_UNSIGNED_SHORT_5_5_5_1:
8365 halveImagePackedPixel3D(4,extract5551,shove5551,
8366 newWidth,newHeight,newDepth,
8367 srcImage,dstImage,elementSize,rowSize,
8368 imageSize,myswapBytes);
8370 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
8371 halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
8372 newWidth,newHeight,newDepth,
8373 srcImage,dstImage,elementSize,rowSize,
8374 imageSize,myswapBytes);
8376 case GL_UNSIGNED_INT_8_8_8_8:
8377 halveImagePackedPixel3D(4,extract8888,shove8888,
8378 newWidth,newHeight,newDepth,
8379 srcImage,dstImage,elementSize,rowSize,
8380 imageSize,myswapBytes);
8382 case GL_UNSIGNED_INT_8_8_8_8_REV:
8383 halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
8384 newWidth,newHeight,newDepth,
8385 srcImage,dstImage,elementSize,rowSize,
8386 imageSize,myswapBytes);
8388 case GL_UNSIGNED_INT_10_10_10_2:
8389 halveImagePackedPixel3D(4,extract1010102,shove1010102,
8390 newWidth,newHeight,newDepth,
8391 srcImage,dstImage,elementSize,rowSize,
8392 imageSize,myswapBytes);
8394 case GL_UNSIGNED_INT_2_10_10_10_REV:
8395 halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
8396 newWidth,newHeight,newDepth,
8397 srcImage,dstImage,elementSize,rowSize,
8398 imageSize,myswapBytes);
8405 __GLU_SWAP_IMAGE(srcImage,dstImage);
8407 if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
8408 if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
8409 if (newDepth > 1) newDepth /= 2;
8411 /* call tex image with srcImage untouched since it's not padded */
8412 if (baseLevel <= level && level <= maxLevel) {
8413 gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
8414 newDepth,0, format, type, (void *) srcImage);
8418 glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
8419 glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
8420 glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
8421 glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
8422 glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
8423 glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
8424 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
8426 free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
8427 if (dstImage) { /* if it's non-rectangular and only 1 level */
8431 } /* gluBuild3DMipmapLevelsCore() */
8434 gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
8435 GLsizei width, GLsizei height, GLsizei depth,
8436 GLenum format, GLenum type,
8437 GLint userLevel, GLint baseLevel, GLint maxLevel,
8442 int rc= checkMipmapArgs(internalFormat,format,type);
8443 if (rc != 0) return rc;
8445 if (width < 1 || height < 1 || depth < 1) {
8446 return GLU_INVALID_VALUE;
8449 if(type == GL_BITMAP) {
8450 return GLU_INVALID_ENUM;
8453 levels = computeLog(width);
8454 level = computeLog(height);
8455 if (level > levels) levels=level;
8456 level = computeLog(depth);
8457 if (level > levels) levels=level;
8460 if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
8461 return GLU_INVALID_VALUE;
8463 return gluBuild3DMipmapLevelsCore(target, internalFormat,
8464 width, height, depth,
8465 width, height, depth,
8467 userLevel, baseLevel, maxLevel,
8469 } /* gluBuild3DMipmapLevels() */
8472 gluBuild3DMipmaps(GLenum target, GLint internalFormat,
8473 GLsizei width, GLsizei height, GLsizei depth,
8474 GLenum format, GLenum type, const void *data)
8476 GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
8479 int rc= checkMipmapArgs(internalFormat,format,type);
8480 if (rc != 0) return rc;
8482 if (width < 1 || height < 1 || depth < 1) {
8483 return GLU_INVALID_VALUE;
8486 if(type == GL_BITMAP) {
8487 return GLU_INVALID_ENUM;
8490 closestFit3D(target,width,height,depth,internalFormat,format,type,
8491 &widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
8493 levels = computeLog(widthPowerOf2);
8494 level = computeLog(heightPowerOf2);
8495 if (level > levels) levels=level;
8496 level = computeLog(depthPowerOf2);
8497 if (level > levels) levels=level;
8499 return gluBuild3DMipmapLevelsCore(target, internalFormat,
8500 width, height, depth,
8501 widthPowerOf2, heightPowerOf2,
8503 format, type, 0, 0, levels,
8505 } /* gluBuild3DMipmaps() */
8507 static GLdouble extractUbyte(int isSwap, const void *ubyte)
8509 isSwap= isSwap; /* turn off warnings */
8511 assert(*((const GLubyte *)ubyte) <= 255);
8513 return (GLdouble)(*((const GLubyte *)ubyte));
8514 } /* extractUbyte() */
8516 static void shoveUbyte(GLdouble value, int index, void *data)
8518 assert(0.0 <= value && value < 256.0);
8520 ((GLubyte *)data)[index]= (GLubyte)value;
8521 } /* shoveUbyte() */
8523 static GLdouble extractSbyte(int isSwap, const void *sbyte)
8525 isSwap= isSwap; /* turn off warnings */
8527 assert(*((const GLbyte *)sbyte) <= 127);
8529 return (GLdouble)(*((const GLbyte *)sbyte));
8530 } /* extractSbyte() */
8532 static void shoveSbyte(GLdouble value, int index, void *data)
8534 ((GLbyte *)data)[index]= (GLbyte)value;
8535 } /* shoveSbyte() */
8537 static GLdouble extractUshort(int isSwap, const void *uitem)
8542 ushort= __GLU_SWAP_2_BYTES(uitem);
8545 ushort= *(const GLushort *)uitem;
8548 assert(ushort <= 65535);
8550 return (GLdouble)ushort;
8551 } /* extractUshort() */
8553 static void shoveUshort(GLdouble value, int index, void *data)
8555 assert(0.0 <= value && value < 65536.0);
8557 ((GLushort *)data)[index]= (GLushort)value;
8558 } /* shoveUshort() */
8560 static GLdouble extractSshort(int isSwap, const void *sitem)
8565 sshort= __GLU_SWAP_2_BYTES(sitem);
8568 sshort= *(const GLshort *)sitem;
8571 assert(sshort <= 32767);
8573 return (GLdouble)sshort;
8574 } /* extractSshort() */
8576 static void shoveSshort(GLdouble value, int index, void *data)
8578 assert(0.0 <= value && value < 32768.0);
8580 ((GLshort *)data)[index]= (GLshort)value;
8581 } /* shoveSshort() */
8583 static GLdouble extractUint(int isSwap, const void *uitem)
8588 uint= __GLU_SWAP_4_BYTES(uitem);
8591 uint= *(const GLuint *)uitem;
8594 assert(uint <= 0xffffffff);
8596 return (GLdouble)uint;
8597 } /* extractUint() */
8599 static void shoveUint(GLdouble value, int index, void *data)
8601 assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
8603 ((GLuint *)data)[index]= (GLuint)value;
8606 static GLdouble extractSint(int isSwap, const void *sitem)
8611 sint= __GLU_SWAP_4_BYTES(sitem);
8614 sint= *(const GLint *)sitem;
8617 assert(sint <= 0x7fffffff);
8619 return (GLdouble)sint;
8620 } /* extractSint() */
8622 static void shoveSint(GLdouble value, int index, void *data)
8624 assert(0.0 <= value && value <= (GLdouble) INT_MAX);
8626 ((GLint *)data)[index]= (GLint)value;
8629 static GLdouble extractFloat(int isSwap, const void *item)
8634 ffloat= __GLU_SWAP_4_BYTES(item);
8637 ffloat= *(const GLfloat *)item;
8640 assert(ffloat <= 1.0);
8642 return (GLdouble)ffloat;
8643 } /* extractFloat() */
8645 static void shoveFloat(GLdouble value, int index, void *data)
8647 assert(0.0 <= value && value <= 1.0);
8649 ((GLfloat *)data)[index]= value;
8650 } /* shoveFloat() */
8652 static void halveImageSlice(int components,
8653 GLdouble (*extract)(int, const void *),
8654 void (*shove)(GLdouble, int, void *),
8655 GLint width, GLint height, GLint depth,
8656 const void *dataIn, void *dataOut,
8657 GLint elementSizeInBytes,
8658 GLint groupSizeInBytes,
8659 GLint rowSizeInBytes,
8660 GLint imageSizeInBytes,
8664 int halfWidth= width / 2;
8665 int halfHeight= height / 2;
8666 int halfDepth= depth / 2;
8667 const char *src= (const char *)dataIn;
8668 int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes);
8669 int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8672 assert((width == 1 || height == 1) && depth >= 2);
8674 if (width == height) { /* a 1-pixel column viewed from top */
8675 /* printf("1-column\n");*/
8676 assert(width == 1 && height == 1);
8679 for (ii= 0; ii< halfDepth; ii++) {
8682 for (cc = 0; cc < components; cc++) {
8684 double extractTotals[BOX2][4];
8687 extractTotals[0][cc]= (*extract)(isSwap,src);
8688 extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
8690 /* average 2 pixels since only a column */
8692 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8693 * totals[RED]/= 2.0;
8695 for (kk = 0; kk < BOX2; kk++) {
8696 totals[cc]+= extractTotals[kk][cc];
8698 totals[cc]/= (double)BOX2;
8700 (*shove)(totals[cc],outIndex,dataOut);
8702 src+= elementSizeInBytes;
8705 /* skip over to next group of 2 */
8706 src+= rowSizeInBytes;
8709 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8710 assert(outIndex == halfDepth * components);
8712 else if (height == 1) { /* horizontal slice viewed from top */
8713 /* printf("horizontal slice\n"); */
8716 for (ii= 0; ii< halfDepth; ii++) {
8717 for (jj= 0; jj< halfWidth; jj++) {
8720 for (cc = 0; cc < components; cc++) {
8723 double extractTotals[BOX4][4];
8725 extractTotals[0][cc]=(*extract)(isSwap,src);
8726 extractTotals[1][cc]=(*extract)(isSwap,
8727 (src+groupSizeInBytes));
8728 extractTotals[2][cc]=(*extract)(isSwap,
8729 (src+imageSizeInBytes));
8730 extractTotals[3][cc]=(*extract)(isSwap,
8731 (src+imageSizeInBytes+groupSizeInBytes));
8733 /* grab 4 pixels to average */
8735 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8736 * extractTotals[2][RED]+extractTotals[3][RED];
8737 * totals[RED]/= 4.0;
8739 for (kk = 0; kk < BOX4; kk++) {
8740 totals[cc]+= extractTotals[kk][cc];
8742 totals[cc]/= (double)BOX4;
8744 (*shove)(totals[cc],outIndex,dataOut);
8747 src+= elementSizeInBytes;
8750 /* skip over to next horizontal square of 4 */
8751 src+= groupSizeInBytes;
8755 src+= rowSizeInBytes;
8758 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8759 assert(outIndex == halfWidth * halfDepth * components);
8761 else if (width == 1) { /* vertical slice viewed from top */
8762 /* printf("vertical slice\n"); */
8763 assert(height != 1);
8765 for (ii= 0; ii< halfDepth; ii++) {
8766 for (jj= 0; jj< halfHeight; jj++) {
8769 for (cc = 0; cc < components; cc++) {
8772 double extractTotals[BOX4][4];
8774 extractTotals[0][cc]=(*extract)(isSwap,src);
8775 extractTotals[1][cc]=(*extract)(isSwap,
8776 (src+rowSizeInBytes));
8777 extractTotals[2][cc]=(*extract)(isSwap,
8778 (src+imageSizeInBytes));
8779 extractTotals[3][cc]=(*extract)(isSwap,
8780 (src+imageSizeInBytes+rowSizeInBytes));
8782 /* grab 4 pixels to average */
8784 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8785 * extractTotals[2][RED]+extractTotals[3][RED];
8786 * totals[RED]/= 4.0;
8788 for (kk = 0; kk < BOX4; kk++) {
8789 totals[cc]+= extractTotals[kk][cc];
8791 totals[cc]/= (double)BOX4;
8793 (*shove)(totals[cc],outIndex,dataOut);
8796 src+= elementSizeInBytes;
8800 /* skip over to next vertical square of 4 */
8801 src+= rowSizeInBytes;
8803 src+= imagePadBytes;
8805 src+= imageSizeInBytes;
8808 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8809 assert(outIndex == halfHeight * halfDepth * components);
8812 } /* halveImageSlice() */
8814 static void halveImage3D(int components,
8815 GLdouble (*extract)(int, const void *),
8816 void (*shove)(GLdouble, int, void *),
8817 GLint width, GLint height, GLint depth,
8818 const void *dataIn, void *dataOut,
8819 GLint elementSizeInBytes,
8820 GLint groupSizeInBytes,
8821 GLint rowSizeInBytes,
8822 GLint imageSizeInBytes,
8827 /* a horizontal/vertical/one-column slice viewed from top */
8828 if (width == 1 || height == 1) {
8831 halveImageSlice(components,extract,shove, width, height, depth,
8832 dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
8833 rowSizeInBytes, imageSizeInBytes, isSwap);
8839 int halfWidth= width / 2;
8840 int halfHeight= height / 2;
8841 int halfDepth= depth / 2;
8842 const char *src= (const char *) dataIn;
8843 int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes);
8844 int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
8847 for (dd= 0; dd < halfDepth; dd++) {
8848 for (ii= 0; ii< halfHeight; ii++) {
8849 for (jj= 0; jj< halfWidth; jj++) {
8852 for (cc= 0; cc < components; cc++) {
8855 double totals[4]; /* 4 is maximum components */
8856 double extractTotals[BOX8][4]; /* 4 is maximum components */
8858 extractTotals[0][cc]= (*extract)(isSwap,src);
8859 extractTotals[1][cc]= (*extract)(isSwap,
8860 (src+groupSizeInBytes));
8861 extractTotals[2][cc]= (*extract)(isSwap,
8862 (src+rowSizeInBytes));
8863 extractTotals[3][cc]= (*extract)(isSwap,
8864 (src+rowSizeInBytes+groupSizeInBytes));
8866 extractTotals[4][cc]= (*extract)(isSwap,
8867 (src+imageSizeInBytes));
8869 extractTotals[5][cc]= (*extract)(isSwap,
8870 (src+groupSizeInBytes+imageSizeInBytes));
8871 extractTotals[6][cc]= (*extract)(isSwap,
8872 (src+rowSizeInBytes+imageSizeInBytes));
8873 extractTotals[7][cc]= (*extract)(isSwap,
8874 (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
8878 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8879 * extractTotals[2][RED]+extractTotals[3][RED]+
8880 * extractTotals[4][RED]+extractTotals[5][RED]+
8881 * extractTotals[6][RED]+extractTotals[7][RED];
8882 * totals[RED]/= 8.0;
8884 for (kk = 0; kk < BOX8; kk++) {
8885 totals[cc]+= extractTotals[kk][cc];
8887 totals[cc]/= (double)BOX8;
8889 (*shove)(totals[cc],outIndex,dataOut);
8893 src+= elementSizeInBytes; /* go to next component */
8896 /* skip over to next square of 4 */
8897 src+= groupSizeInBytes;
8899 /* skip past pad bytes, if any, to get to next row */
8902 /* src is at beginning of a row here, but it's the second row of
8903 * the square block of 4 pixels that we just worked on so we
8904 * need to go one more row.
8912 src+= rowSizeInBytes;
8915 /* skip past pad bytes, if any, to get to next image */
8916 src+= imagePadBytes;
8918 src+= imageSizeInBytes;
8921 /* both pointers must reach one byte after the end */
8922 assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
8923 assert(outIndex == halfWidth * halfHeight * halfDepth * components);
8925 } /* halveImage3D() */