2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
34 ** $Date: 2002/11/01 23:45:31 $ $Revision: 1.3 $
35 ** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libutil/mipmap.c,v 1.3 2002/11/01 23:45:31 brianp Exp $
44 #include <limits.h> /* UINT_MAX */
58 /* Pixel storage modes */
61 GLint pack_row_length
;
63 GLint pack_skip_pixels
;
65 GLint pack_swap_bytes
;
66 GLint pack_skip_images
;
67 GLint pack_image_height
;
69 GLint unpack_alignment
;
70 GLint unpack_row_length
;
71 GLint unpack_skip_rows
;
72 GLint unpack_skip_pixels
;
73 GLint unpack_lsb_first
;
74 GLint unpack_swap_bytes
;
75 GLint unpack_skip_images
;
76 GLint unpack_image_height
;
79 static int gluBuild1DMipmapLevelsCore(GLenum
, GLint
,
82 GLenum
, GLenum
, GLint
, GLint
, GLint
,
84 static int gluBuild2DMipmapLevelsCore(GLenum
, GLint
,
87 GLenum
, GLenum
, GLint
, GLint
, GLint
,
89 static int gluBuild3DMipmapLevelsCore(GLenum
, GLint
,
90 GLsizei
, GLsizei
, GLsizei
,
91 GLsizei
, GLsizei
, GLsizei
,
92 GLenum
, GLenum
, GLint
, GLint
, GLint
,
96 * internal function declarations
98 static GLfloat
bytes_per_element(GLenum type
);
99 static GLint
elements_per_group(GLenum format
, GLenum type
);
100 static GLint
is_index(GLenum format
);
101 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
);
102 static void fill_image(const PixelStorageModes
*,
103 GLint width
, GLint height
, GLenum format
,
104 GLenum type
, GLboolean index_format
,
105 const void *userdata
, GLushort
*newimage
);
106 static void empty_image(const PixelStorageModes
*,
107 GLint width
, GLint height
, GLenum format
,
108 GLenum type
, GLboolean index_format
,
109 const GLushort
*oldimage
, void *userdata
);
110 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
111 const GLushort
*datain
,
112 GLint widthout
, GLint heightout
,
115 static void scale_internal_ubyte(GLint components
, GLint widthin
,
116 GLint heightin
, const GLubyte
*datain
,
117 GLint widthout
, GLint heightout
,
118 GLubyte
*dataout
, GLint element_size
,
119 GLint ysize
, GLint group_size
);
120 static void scale_internal_byte(GLint components
, GLint widthin
,
121 GLint heightin
, const GLbyte
*datain
,
122 GLint widthout
, GLint heightout
,
123 GLbyte
*dataout
, GLint element_size
,
124 GLint ysize
, GLint group_size
);
125 static void scale_internal_ushort(GLint components
, GLint widthin
,
126 GLint heightin
, const GLushort
*datain
,
127 GLint widthout
, GLint heightout
,
128 GLushort
*dataout
, GLint element_size
,
129 GLint ysize
, GLint group_size
,
131 static void scale_internal_short(GLint components
, GLint widthin
,
132 GLint heightin
, const GLshort
*datain
,
133 GLint widthout
, GLint heightout
,
134 GLshort
*dataout
, GLint element_size
,
135 GLint ysize
, GLint group_size
,
137 static void scale_internal_uint(GLint components
, GLint widthin
,
138 GLint heightin
, const GLuint
*datain
,
139 GLint widthout
, GLint heightout
,
140 GLuint
*dataout
, GLint element_size
,
141 GLint ysize
, GLint group_size
,
143 static void scale_internal_int(GLint components
, GLint widthin
,
144 GLint heightin
, const GLint
*datain
,
145 GLint widthout
, GLint heightout
,
146 GLint
*dataout
, GLint element_size
,
147 GLint ysize
, GLint group_size
,
149 static void scale_internal_float(GLint components
, GLint widthin
,
150 GLint heightin
, const GLfloat
*datain
,
151 GLint widthout
, GLint heightout
,
152 GLfloat
*dataout
, GLint element_size
,
153 GLint ysize
, GLint group_size
,
156 static int checkMipmapArgs(GLenum
, GLenum
, GLenum
);
157 static GLboolean
legalFormat(GLenum
);
158 static GLboolean
legalType(GLenum
);
159 static GLboolean
isTypePackedPixel(GLenum
);
160 static GLboolean
isLegalFormatForPackedPixelType(GLenum
, GLenum
);
161 static GLboolean
isLegalLevels(GLint
, GLint
, GLint
, GLint
);
162 static void closestFit(GLenum
, GLint
, GLint
, GLint
, GLenum
, GLenum
,
165 /* all extract/shove routines must return double to handle unsigned ints */
166 static GLdouble
extractUbyte(int, const void *);
167 static void shoveUbyte(GLdouble
, int, void *);
168 static GLdouble
extractSbyte(int, const void *);
169 static void shoveSbyte(GLdouble
, int, void *);
170 static GLdouble
extractUshort(int, const void *);
171 static void shoveUshort(GLdouble
, int, void *);
172 static GLdouble
extractSshort(int, const void *);
173 static void shoveSshort(GLdouble
, int, void *);
174 static GLdouble
extractUint(int, const void *);
175 static void shoveUint(GLdouble
, int, void *);
176 static GLdouble
extractSint(int, const void *);
177 static void shoveSint(GLdouble
, int, void *);
178 static GLdouble
extractFloat(int, const void *);
179 static void shoveFloat(GLdouble
, int, void *);
180 static void halveImageSlice(int, GLdouble (*)(int, const void *),
181 void (*)(GLdouble
, int, void *),
183 const void *, void *,
184 GLint
, GLint
, GLint
, GLint
, GLint
);
185 static void halveImage3D(int, GLdouble (*)(int, const void *),
186 void (*)(GLdouble
, int, void *),
188 const void *, void *,
189 GLint
, GLint
, GLint
, GLint
, GLint
);
191 /* packedpixel type scale routines */
192 static void extract332(int,const void *, GLfloat
[]);
193 static void shove332(const GLfloat
[],int ,void *);
194 static void extract233rev(int,const void *, GLfloat
[]);
195 static void shove233rev(const GLfloat
[],int ,void *);
196 static void extract565(int,const void *, GLfloat
[]);
197 static void shove565(const GLfloat
[],int ,void *);
198 static void extract565rev(int,const void *, GLfloat
[]);
199 static void shove565rev(const GLfloat
[],int ,void *);
200 static void extract4444(int,const void *, GLfloat
[]);
201 static void shove4444(const GLfloat
[],int ,void *);
202 static void extract4444rev(int,const void *, GLfloat
[]);
203 static void shove4444rev(const GLfloat
[],int ,void *);
204 static void extract5551(int,const void *, GLfloat
[]);
205 static void shove5551(const GLfloat
[],int ,void *);
206 static void extract1555rev(int,const void *, GLfloat
[]);
207 static void shove1555rev(const GLfloat
[],int ,void *);
208 static void extract8888(int,const void *, GLfloat
[]);
209 static void shove8888(const GLfloat
[],int ,void *);
210 static void extract8888rev(int,const void *, GLfloat
[]);
211 static void shove8888rev(const GLfloat
[],int ,void *);
212 static void extract1010102(int,const void *, GLfloat
[]);
213 static void shove1010102(const GLfloat
[],int ,void *);
214 static void extract2101010rev(int,const void *, GLfloat
[]);
215 static void shove2101010rev(const GLfloat
[],int ,void *);
216 static void scaleInternalPackedPixel(int,
217 void (*)(int, const void *,GLfloat
[]),
218 void (*)(const GLfloat
[],int, void *),
219 GLint
,GLint
, const void *,
220 GLint
,GLint
,void *,GLint
,GLint
,GLint
);
221 static void halveImagePackedPixel(int,
222 void (*)(int, const void *,GLfloat
[]),
223 void (*)(const GLfloat
[],int, void *),
224 GLint
, GLint
, const void *,
225 void *, GLint
, GLint
, GLint
);
226 static void halve1DimagePackedPixel(int,
227 void (*)(int, const void *,GLfloat
[]),
228 void (*)(const GLfloat
[],int, void *),
229 GLint
, GLint
, const void *,
230 void *, GLint
, GLint
, GLint
);
232 static void halve1Dimage_ubyte(GLint
, GLuint
, GLuint
,const GLubyte
*,
233 GLubyte
*, GLint
, GLint
, GLint
);
234 static void halve1Dimage_byte(GLint
, GLuint
, GLuint
,const GLbyte
*, GLbyte
*,
235 GLint
, GLint
, GLint
);
236 static void halve1Dimage_ushort(GLint
, GLuint
, GLuint
, const GLushort
*,
237 GLushort
*, GLint
, GLint
, GLint
, GLint
);
238 static void halve1Dimage_short(GLint
, GLuint
, GLuint
,const GLshort
*, GLshort
*,
239 GLint
, GLint
, GLint
, GLint
);
240 static void halve1Dimage_uint(GLint
, GLuint
, GLuint
, const GLuint
*, GLuint
*,
241 GLint
, GLint
, GLint
, GLint
);
242 static void halve1Dimage_int(GLint
, GLuint
, GLuint
, const GLint
*, GLint
*,
243 GLint
, GLint
, GLint
, GLint
);
244 static void halve1Dimage_float(GLint
, GLuint
, GLuint
, const GLfloat
*, GLfloat
*,
245 GLint
, GLint
, GLint
, GLint
);
247 static GLint
imageSize3D(GLint
, GLint
, GLint
, GLenum
,GLenum
);
248 static void fillImage3D(const PixelStorageModes
*, GLint
, GLint
, GLint
,GLenum
,
249 GLenum
, GLboolean
, const void *, GLushort
*);
250 static void emptyImage3D(const PixelStorageModes
*,
251 GLint
, GLint
, GLint
, GLenum
,
253 const GLushort
*, void *);
254 static void scaleInternal3D(GLint
, GLint
, GLint
, GLint
, const GLushort
*,
255 GLint
, GLint
, GLint
, GLushort
*);
257 static void retrieveStoreModes(PixelStorageModes
*psm
)
259 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
260 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
261 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
262 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
263 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
264 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
266 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
267 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
268 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
269 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
270 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
271 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
274 static void retrieveStoreModes3D(PixelStorageModes
*psm
)
276 glGetIntegerv(GL_UNPACK_ALIGNMENT
, &psm
->unpack_alignment
);
277 glGetIntegerv(GL_UNPACK_ROW_LENGTH
, &psm
->unpack_row_length
);
278 glGetIntegerv(GL_UNPACK_SKIP_ROWS
, &psm
->unpack_skip_rows
);
279 glGetIntegerv(GL_UNPACK_SKIP_PIXELS
, &psm
->unpack_skip_pixels
);
280 glGetIntegerv(GL_UNPACK_LSB_FIRST
, &psm
->unpack_lsb_first
);
281 glGetIntegerv(GL_UNPACK_SWAP_BYTES
, &psm
->unpack_swap_bytes
);
282 glGetIntegerv(GL_UNPACK_SKIP_IMAGES
, &psm
->unpack_skip_images
);
283 glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT
, &psm
->unpack_image_height
);
285 glGetIntegerv(GL_PACK_ALIGNMENT
, &psm
->pack_alignment
);
286 glGetIntegerv(GL_PACK_ROW_LENGTH
, &psm
->pack_row_length
);
287 glGetIntegerv(GL_PACK_SKIP_ROWS
, &psm
->pack_skip_rows
);
288 glGetIntegerv(GL_PACK_SKIP_PIXELS
, &psm
->pack_skip_pixels
);
289 glGetIntegerv(GL_PACK_LSB_FIRST
, &psm
->pack_lsb_first
);
290 glGetIntegerv(GL_PACK_SWAP_BYTES
, &psm
->pack_swap_bytes
);
291 glGetIntegerv(GL_PACK_SKIP_IMAGES
, &psm
->pack_skip_images
);
292 glGetIntegerv(GL_PACK_IMAGE_HEIGHT
, &psm
->pack_image_height
);
295 static int computeLog(GLuint value
)
302 if (value
== 0) return -1;
307 if (value
!= 1) return -1;
316 ** Compute the nearest power of 2 number. This algorithm is a little
317 ** strange, but it works quite well.
319 static int nearestPower(GLuint value
)
326 if (value
== 0) return -1;
331 } else if (value
== 3) {
339 #define __GLU_SWAP_2_BYTES(s)\
340 (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
342 #define __GLU_SWAP_4_BYTES(s)\
343 (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
344 ((GLuint)((const GLubyte*)(s))[2])<<16 | \
345 ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
347 static void halveImage(GLint components
, GLuint width
, GLuint height
,
348 const GLushort
*datain
, GLushort
*dataout
)
351 int newwidth
, newheight
;
356 newwidth
= width
/ 2;
357 newheight
= height
/ 2;
358 delta
= width
* components
;
363 for (i
= 0; i
< newheight
; i
++) {
364 for (j
= 0; j
< newwidth
; j
++) {
365 for (k
= 0; k
< components
; k
++) {
366 s
[0] = (t
[0] + t
[components
] + t
[delta
] +
367 t
[delta
+components
] + 2) / 4;
376 static void halveImage_ubyte(GLint components
, GLuint width
, GLuint height
,
377 const GLubyte
*datain
, GLubyte
*dataout
,
378 GLint element_size
, GLint ysize
, GLint group_size
)
381 int newwidth
, newheight
;
385 /* handle case where there is only 1 column/row */
386 if (width
== 1 || height
== 1) {
387 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
388 halve1Dimage_ubyte(components
,width
,height
,datain
,dataout
,
389 element_size
,ysize
,group_size
);
393 newwidth
= width
/ 2;
394 newheight
= height
/ 2;
396 t
= (const char *)datain
;
399 for (i
= 0; i
< newheight
; i
++) {
400 for (j
= 0; j
< newwidth
; j
++) {
401 for (k
= 0; k
< components
; k
++) {
402 s
[0] = (*(const GLubyte
*)t
+
403 *(const GLubyte
*)(t
+group_size
) +
404 *(const GLubyte
*)(t
+ysize
) +
405 *(const GLubyte
*)(t
+ysize
+group_size
) + 2) / 4;
406 s
++; t
+= element_size
;
415 static void halve1Dimage_ubyte(GLint components
, GLuint width
, GLuint height
,
416 const GLubyte
*dataIn
, GLubyte
*dataOut
,
417 GLint element_size
, GLint ysize
,
420 GLint halfWidth
= width
/ 2;
421 GLint halfHeight
= height
/ 2;
422 const char *src
= (const char *) dataIn
;
423 GLubyte
*dest
= dataOut
;
426 assert(width
== 1 || height
== 1); /* must be 1D */
427 assert(width
!= height
); /* can't be square */
429 if (height
== 1) { /* 1 row */
430 assert(width
!= 1); /* widthxheight can't be 1x1 */
433 for (jj
= 0; jj
< halfWidth
; jj
++) {
435 for (kk
= 0; kk
< components
; kk
++) {
436 *dest
= (*(const GLubyte
*)src
+
437 *(const GLubyte
*)(src
+group_size
)) / 2;
442 src
+= group_size
; /* skip to next 2 */
445 int padBytes
= ysize
- (width
*group_size
);
446 src
+= padBytes
; /* for assertion only */
449 else if (width
== 1) { /* 1 column */
450 int padBytes
= ysize
- (width
* group_size
);
451 assert(height
!= 1); /* widthxheight can't be 1x1 */
453 /* one vertical column with possible pad bytes per row */
454 /* average two at a time */
456 for (jj
= 0; jj
< halfHeight
; jj
++) {
458 for (kk
= 0; kk
< components
; kk
++) {
459 *dest
= (*(const GLubyte
*)src
+ *(const GLubyte
*)(src
+ysize
)) / 2;
464 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
469 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
470 assert((char *)dest
== &((char *)dataOut
)
471 [components
* element_size
* halfWidth
* halfHeight
]);
472 } /* halve1Dimage_ubyte() */
474 static void halveImage_byte(GLint components
, GLuint width
, GLuint height
,
475 const GLbyte
*datain
, GLbyte
*dataout
,
477 GLint ysize
, GLint group_size
)
480 int newwidth
, newheight
;
484 /* handle case where there is only 1 column/row */
485 if (width
== 1 || height
== 1) {
486 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
487 halve1Dimage_byte(components
,width
,height
,datain
,dataout
,
488 element_size
,ysize
,group_size
);
492 newwidth
= width
/ 2;
493 newheight
= height
/ 2;
495 t
= (const char *)datain
;
498 for (i
= 0; i
< newheight
; i
++) {
499 for (j
= 0; j
< newwidth
; j
++) {
500 for (k
= 0; k
< components
; k
++) {
501 s
[0] = (*(const GLbyte
*)t
+
502 *(const GLbyte
*)(t
+group_size
) +
503 *(const GLbyte
*)(t
+ysize
) +
504 *(const GLbyte
*)(t
+ysize
+group_size
) + 2) / 4;
505 s
++; t
+= element_size
;
513 static void halve1Dimage_byte(GLint components
, GLuint width
, GLuint height
,
514 const GLbyte
*dataIn
, GLbyte
*dataOut
,
515 GLint element_size
,GLint ysize
, GLint group_size
)
517 GLint halfWidth
= width
/ 2;
518 GLint halfHeight
= height
/ 2;
519 const char *src
= (const char *) dataIn
;
520 GLbyte
*dest
= dataOut
;
523 assert(width
== 1 || height
== 1); /* must be 1D */
524 assert(width
!= height
); /* can't be square */
526 if (height
== 1) { /* 1 row */
527 assert(width
!= 1); /* widthxheight can't be 1x1 */
530 for (jj
= 0; jj
< halfWidth
; jj
++) {
532 for (kk
= 0; kk
< components
; kk
++) {
533 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+group_size
)) / 2;
538 src
+= group_size
; /* skip to next 2 */
541 int padBytes
= ysize
- (width
*group_size
);
542 src
+= padBytes
; /* for assertion only */
545 else if (width
== 1) { /* 1 column */
546 int padBytes
= ysize
- (width
* group_size
);
547 assert(height
!= 1); /* widthxheight can't be 1x1 */
549 /* one vertical column with possible pad bytes per row */
550 /* average two at a time */
552 for (jj
= 0; jj
< halfHeight
; jj
++) {
554 for (kk
= 0; kk
< components
; kk
++) {
555 *dest
= (*(const GLbyte
*)src
+ *(const GLbyte
*)(src
+ysize
)) / 2;
560 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
564 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
567 assert((char *)dest
== &((char *)dataOut
)
568 [components
* element_size
* halfWidth
* halfHeight
]);
569 } /* halve1Dimage_byte() */
571 static void halveImage_ushort(GLint components
, GLuint width
, GLuint height
,
572 const GLushort
*datain
, GLushort
*dataout
,
573 GLint element_size
, GLint ysize
, GLint group_size
,
577 int newwidth
, newheight
;
581 /* handle case where there is only 1 column/row */
582 if (width
== 1 || height
== 1) {
583 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
584 halve1Dimage_ushort(components
,width
,height
,datain
,dataout
,
585 element_size
,ysize
,group_size
, myswap_bytes
);
589 newwidth
= width
/ 2;
590 newheight
= height
/ 2;
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
;
610 for (i
= 0; i
< newheight
; i
++) {
611 for (j
= 0; j
< newwidth
; j
++) {
612 for (k
= 0; k
< components
; k
++) {
613 s
[0] = (__GLU_SWAP_2_BYTES(t
) +
614 __GLU_SWAP_2_BYTES(t
+group_size
) +
615 __GLU_SWAP_2_BYTES(t
+ysize
) +
616 __GLU_SWAP_2_BYTES(t
+ysize
+group_size
)+ 2)/4;
617 s
++; t
+= element_size
;
625 static void halve1Dimage_ushort(GLint components
, GLuint width
, GLuint height
,
626 const GLushort
*dataIn
, GLushort
*dataOut
,
627 GLint element_size
, GLint ysize
,
628 GLint group_size
, GLint myswap_bytes
)
630 GLint halfWidth
= width
/ 2;
631 GLint halfHeight
= height
/ 2;
632 const char *src
= (const char *) dataIn
;
633 GLushort
*dest
= dataOut
;
636 assert(width
== 1 || height
== 1); /* must be 1D */
637 assert(width
!= height
); /* can't be square */
639 if (height
== 1) { /* 1 row */
640 assert(width
!= 1); /* widthxheight can't be 1x1 */
643 for (jj
= 0; jj
< halfWidth
; jj
++) {
645 for (kk
= 0; kk
< components
; kk
++) {
647 GLushort ushort
[BOX2
];
649 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
650 ushort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
653 ushort
[0]= *(const GLushort
*)src
;
654 ushort
[1]= *(const GLushort
*)(src
+group_size
);
657 *dest
= (ushort
[0] + ushort
[1]) / 2;
661 src
+= group_size
; /* skip to next 2 */
664 int padBytes
= ysize
- (width
*group_size
);
665 src
+= padBytes
; /* for assertion only */
668 else if (width
== 1) { /* 1 column */
669 int padBytes
= ysize
- (width
* group_size
);
670 assert(height
!= 1); /* widthxheight can't be 1x1 */
672 /* one vertical column with possible pad bytes per row */
673 /* average two at a time */
675 for (jj
= 0; jj
< halfHeight
; jj
++) {
677 for (kk
= 0; kk
< components
; kk
++) {
679 GLushort ushort
[BOX2
];
681 ushort
[0]= __GLU_SWAP_2_BYTES(src
);
682 ushort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
685 ushort
[0]= *(const GLushort
*)src
;
686 ushort
[1]= *(const GLushort
*)(src
+ysize
);
688 *dest
= (ushort
[0] + ushort
[1]) / 2;
693 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
697 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
700 assert((char *)dest
== &((char *)dataOut
)
701 [components
* element_size
* halfWidth
* halfHeight
]);
703 } /* halve1Dimage_ushort() */
706 static void halveImage_short(GLint components
, GLuint width
, GLuint height
,
707 const GLshort
*datain
, GLshort
*dataout
,
708 GLint element_size
, GLint ysize
, GLint group_size
,
712 int newwidth
, newheight
;
716 /* handle case where there is only 1 column/row */
717 if (width
== 1 || height
== 1) {
718 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
719 halve1Dimage_short(components
,width
,height
,datain
,dataout
,
720 element_size
,ysize
,group_size
, myswap_bytes
);
724 newwidth
= width
/ 2;
725 newheight
= height
/ 2;
727 t
= (const char *)datain
;
731 for (i
= 0; i
< newheight
; i
++) {
732 for (j
= 0; j
< newwidth
; j
++) {
733 for (k
= 0; k
< components
; k
++) {
734 s
[0] = (*(const GLshort
*)t
+
735 *(const GLshort
*)(t
+group_size
) +
736 *(const GLshort
*)(t
+ysize
) +
737 *(const GLshort
*)(t
+ysize
+group_size
) + 2) / 4;
738 s
++; t
+= element_size
;
745 for (i
= 0; i
< newheight
; i
++) {
746 for (j
= 0; j
< newwidth
; j
++) {
747 for (k
= 0; k
< components
; k
++) {
750 b
= __GLU_SWAP_2_BYTES(t
);
751 buf
= *(const GLshort
*)&b
;
752 b
= __GLU_SWAP_2_BYTES(t
+group_size
);
753 buf
+= *(const GLshort
*)&b
;
754 b
= __GLU_SWAP_2_BYTES(t
+ysize
);
755 buf
+= *(const GLshort
*)&b
;
756 b
= __GLU_SWAP_2_BYTES(t
+ysize
+group_size
);
757 buf
+= *(const GLshort
*)&b
;
758 s
[0] = (GLshort
)((buf
+2)/4);
759 s
++; t
+= element_size
;
767 static void halve1Dimage_short(GLint components
, GLuint width
, GLuint height
,
768 const GLshort
*dataIn
, GLshort
*dataOut
,
769 GLint element_size
, GLint ysize
,
770 GLint group_size
, GLint myswap_bytes
)
772 GLint halfWidth
= width
/ 2;
773 GLint halfHeight
= height
/ 2;
774 const char *src
= (const char *) dataIn
;
775 GLshort
*dest
= dataOut
;
778 assert(width
== 1 || height
== 1); /* must be 1D */
779 assert(width
!= height
); /* can't be square */
781 if (height
== 1) { /* 1 row */
782 assert(width
!= 1); /* widthxheight can't be 1x1 */
785 for (jj
= 0; jj
< halfWidth
; jj
++) {
787 for (kk
= 0; kk
< components
; kk
++) {
789 GLshort sshort
[BOX2
];
791 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
792 sshort
[1]= __GLU_SWAP_2_BYTES(src
+group_size
);
795 sshort
[0]= *(const GLshort
*)src
;
796 sshort
[1]= *(const GLshort
*)(src
+group_size
);
799 *dest
= (sshort
[0] + sshort
[1]) / 2;
803 src
+= group_size
; /* skip to next 2 */
806 int padBytes
= ysize
- (width
*group_size
);
807 src
+= padBytes
; /* for assertion only */
810 else if (width
== 1) { /* 1 column */
811 int padBytes
= ysize
- (width
* group_size
);
812 assert(height
!= 1); /* widthxheight can't be 1x1 */
814 /* one vertical column with possible pad bytes per row */
815 /* average two at a time */
817 for (jj
= 0; jj
< halfHeight
; jj
++) {
819 for (kk
= 0; kk
< components
; kk
++) {
821 GLshort sshort
[BOX2
];
823 sshort
[0]= __GLU_SWAP_2_BYTES(src
);
824 sshort
[1]= __GLU_SWAP_2_BYTES(src
+ysize
);
827 sshort
[0]= *(const GLshort
*)src
;
828 sshort
[1]= *(const GLshort
*)(src
+ysize
);
830 *dest
= (sshort
[0] + sshort
[1]) / 2;
835 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
839 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
842 assert((char *)dest
== &((char *)dataOut
)
843 [components
* element_size
* halfWidth
* halfHeight
]);
845 } /* halve1Dimage_short() */
848 static void halveImage_uint(GLint components
, GLuint width
, GLuint height
,
849 const GLuint
*datain
, GLuint
*dataout
,
850 GLint element_size
, GLint ysize
, GLint group_size
,
854 int newwidth
, newheight
;
858 /* handle case where there is only 1 column/row */
859 if (width
== 1 || height
== 1) {
860 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
861 halve1Dimage_uint(components
,width
,height
,datain
,dataout
,
862 element_size
,ysize
,group_size
, myswap_bytes
);
866 newwidth
= width
/ 2;
867 newheight
= height
/ 2;
869 t
= (const char *)datain
;
873 for (i
= 0; i
< newheight
; i
++) {
874 for (j
= 0; j
< newwidth
; j
++) {
875 for (k
= 0; k
< components
; k
++) {
876 /* need to cast to double to hold large unsigned ints */
877 s
[0] = ((double)*(const GLuint
*)t
+
878 (double)*(const GLuint
*)(t
+group_size
) +
879 (double)*(const GLuint
*)(t
+ysize
) +
880 (double)*(const GLuint
*)(t
+ysize
+group_size
))/4 + 0.5;
881 s
++; t
+= element_size
;
889 for (i
= 0; i
< newheight
; i
++) {
890 for (j
= 0; j
< newwidth
; j
++) {
891 for (k
= 0; k
< components
; k
++) {
892 /* need to cast to double to hold large unsigned ints */
894 buf
= (GLdouble
)__GLU_SWAP_4_BYTES(t
) +
895 (GLdouble
)__GLU_SWAP_4_BYTES(t
+group_size
) +
896 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
) +
897 (GLdouble
)__GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
898 s
[0] = (GLuint
)(buf
/4 + 0.5);
900 s
++; t
+= element_size
;
909 static void halve1Dimage_uint(GLint components
, GLuint width
, GLuint height
,
910 const GLuint
*dataIn
, GLuint
*dataOut
,
911 GLint element_size
, GLint ysize
,
912 GLint group_size
, GLint myswap_bytes
)
914 GLint halfWidth
= width
/ 2;
915 GLint halfHeight
= height
/ 2;
916 const char *src
= (const char *) dataIn
;
917 GLuint
*dest
= dataOut
;
920 assert(width
== 1 || height
== 1); /* must be 1D */
921 assert(width
!= height
); /* can't be square */
923 if (height
== 1) { /* 1 row */
924 assert(width
!= 1); /* widthxheight can't be 1x1 */
927 for (jj
= 0; jj
< halfWidth
; jj
++) {
929 for (kk
= 0; kk
< components
; kk
++) {
933 uint
[0]= __GLU_SWAP_4_BYTES(src
);
934 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
937 uint
[0]= *(const GLuint
*)src
;
938 uint
[1]= *(const GLuint
*)(src
+group_size
);
940 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
945 src
+= group_size
; /* skip to next 2 */
948 int padBytes
= ysize
- (width
*group_size
);
949 src
+= padBytes
; /* for assertion only */
952 else if (width
== 1) { /* 1 column */
953 int padBytes
= ysize
- (width
* group_size
);
954 assert(height
!= 1); /* widthxheight can't be 1x1 */
956 /* one vertical column with possible pad bytes per row */
957 /* average two at a time */
959 for (jj
= 0; jj
< halfHeight
; jj
++) {
961 for (kk
= 0; kk
< components
; kk
++) {
965 uint
[0]= __GLU_SWAP_4_BYTES(src
);
966 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
969 uint
[0]= *(const GLuint
*)src
;
970 uint
[1]= *(const GLuint
*)(src
+ysize
);
972 *dest
= ((double)uint
[0]+(double)uint
[1])/2.0;
977 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
981 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
984 assert((char *)dest
== &((char *)dataOut
)
985 [components
* element_size
* halfWidth
* halfHeight
]);
987 } /* halve1Dimage_uint() */
989 static void halveImage_int(GLint components
, GLuint width
, GLuint height
,
990 const GLint
*datain
, GLint
*dataout
, GLint element_size
,
991 GLint ysize
, GLint group_size
, GLint myswap_bytes
)
994 int newwidth
, newheight
;
998 /* handle case where there is only 1 column/row */
999 if (width
== 1 || height
== 1) {
1000 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1001 halve1Dimage_int(components
,width
,height
,datain
,dataout
,
1002 element_size
,ysize
,group_size
, myswap_bytes
);
1006 newwidth
= width
/ 2;
1007 newheight
= height
/ 2;
1009 t
= (const char *)datain
;
1011 /* Piece o' cake! */
1013 for (i
= 0; i
< newheight
; i
++) {
1014 for (j
= 0; j
< newwidth
; j
++) {
1015 for (k
= 0; k
< components
; k
++) {
1016 s
[0] = ((float)*(const GLint
*)t
+
1017 (float)*(const GLint
*)(t
+group_size
) +
1018 (float)*(const GLint
*)(t
+ysize
) +
1019 (float)*(const GLint
*)(t
+ysize
+group_size
))/4 + 0.5;
1020 s
++; t
+= element_size
;
1027 for (i
= 0; i
< newheight
; i
++) {
1028 for (j
= 0; j
< newwidth
; j
++) {
1029 for (k
= 0; k
< components
; k
++) {
1032 b
= __GLU_SWAP_4_BYTES(t
);
1034 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1036 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1038 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1040 s
[0] = (GLint
)(buf
/4 + 0.5);
1042 s
++; t
+= element_size
;
1051 static void halve1Dimage_int(GLint components
, GLuint width
, GLuint height
,
1052 const GLint
*dataIn
, GLint
*dataOut
,
1053 GLint element_size
, GLint ysize
,
1054 GLint group_size
, GLint myswap_bytes
)
1056 GLint halfWidth
= width
/ 2;
1057 GLint halfHeight
= height
/ 2;
1058 const char *src
= (const char *) dataIn
;
1059 GLint
*dest
= dataOut
;
1062 assert(width
== 1 || height
== 1); /* must be 1D */
1063 assert(width
!= height
); /* can't be square */
1065 if (height
== 1) { /* 1 row */
1066 assert(width
!= 1); /* widthxheight can't be 1x1 */
1069 for (jj
= 0; jj
< halfWidth
; jj
++) {
1071 for (kk
= 0; kk
< components
; kk
++) {
1075 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1076 uint
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1079 uint
[0]= *(const GLuint
*)src
;
1080 uint
[1]= *(const GLuint
*)(src
+group_size
);
1082 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1087 src
+= group_size
; /* skip to next 2 */
1090 int padBytes
= ysize
- (width
*group_size
);
1091 src
+= padBytes
; /* for assertion only */
1094 else if (width
== 1) { /* 1 column */
1095 int padBytes
= ysize
- (width
* group_size
);
1096 assert(height
!= 1); /* widthxheight can't be 1x1 */
1098 /* one vertical column with possible pad bytes per row */
1099 /* average two at a time */
1101 for (jj
= 0; jj
< halfHeight
; jj
++) {
1103 for (kk
= 0; kk
< components
; kk
++) {
1107 uint
[0]= __GLU_SWAP_4_BYTES(src
);
1108 uint
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1111 uint
[0]= *(const GLuint
*)src
;
1112 uint
[1]= *(const GLuint
*)(src
+ysize
);
1114 *dest
= ((float)uint
[0]+(float)uint
[1])/2.0;
1119 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1123 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1126 assert((char *)dest
== &((char *)dataOut
)
1127 [components
* element_size
* halfWidth
* halfHeight
]);
1129 } /* halve1Dimage_int() */
1132 static void halveImage_float(GLint components
, GLuint width
, GLuint height
,
1133 const GLfloat
*datain
, GLfloat
*dataout
,
1134 GLint element_size
, GLint ysize
, GLint group_size
,
1138 int newwidth
, newheight
;
1142 /* handle case where there is only 1 column/row */
1143 if (width
== 1 || height
== 1) {
1144 assert( !(width
== 1 && height
== 1) ); /* can't be 1x1 */
1145 halve1Dimage_float(components
,width
,height
,datain
,dataout
,
1146 element_size
,ysize
,group_size
, myswap_bytes
);
1150 newwidth
= width
/ 2;
1151 newheight
= height
/ 2;
1153 t
= (const char *)datain
;
1155 /* Piece o' cake! */
1157 for (i
= 0; i
< newheight
; i
++) {
1158 for (j
= 0; j
< newwidth
; j
++) {
1159 for (k
= 0; k
< components
; k
++) {
1160 s
[0] = (*(const GLfloat
*)t
+
1161 *(const GLfloat
*)(t
+group_size
) +
1162 *(const GLfloat
*)(t
+ysize
) +
1163 *(const GLfloat
*)(t
+ysize
+group_size
)) / 4;
1164 s
++; t
+= element_size
;
1171 for (i
= 0; i
< newheight
; i
++) {
1172 for (j
= 0; j
< newwidth
; j
++) {
1173 for (k
= 0; k
< components
; k
++) {
1175 b
= __GLU_SWAP_4_BYTES(t
);
1176 s
[0] = *(GLfloat
*)&b
;
1177 b
= __GLU_SWAP_4_BYTES(t
+group_size
);
1178 s
[0] += *(GLfloat
*)&b
;
1179 b
= __GLU_SWAP_4_BYTES(t
+ysize
);
1180 s
[0] += *(GLfloat
*)&b
;
1181 b
= __GLU_SWAP_4_BYTES(t
+ysize
+group_size
);
1182 s
[0] += *(GLfloat
*)&b
;
1184 s
++; t
+= element_size
;
1193 static void halve1Dimage_float(GLint components
, GLuint width
, GLuint height
,
1194 const GLfloat
*dataIn
, GLfloat
*dataOut
,
1195 GLint element_size
, GLint ysize
,
1196 GLint group_size
, GLint myswap_bytes
)
1198 GLint halfWidth
= width
/ 2;
1199 GLint halfHeight
= height
/ 2;
1200 const char *src
= (const char *) dataIn
;
1201 GLfloat
*dest
= dataOut
;
1204 assert(width
== 1 || height
== 1); /* must be 1D */
1205 assert(width
!= height
); /* can't be square */
1207 if (height
== 1) { /* 1 row */
1208 assert(width
!= 1); /* widthxheight can't be 1x1 */
1211 for (jj
= 0; jj
< halfWidth
; jj
++) {
1213 for (kk
= 0; kk
< components
; kk
++) {
1215 GLfloat sfloat
[BOX2
];
1217 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1218 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+group_size
);
1221 sfloat
[0]= *(const GLfloat
*)src
;
1222 sfloat
[1]= *(const GLfloat
*)(src
+group_size
);
1225 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1229 src
+= group_size
; /* skip to next 2 */
1232 int padBytes
= ysize
- (width
*group_size
);
1233 src
+= padBytes
; /* for assertion only */
1236 else if (width
== 1) { /* 1 column */
1237 int padBytes
= ysize
- (width
* group_size
);
1238 assert(height
!= 1); /* widthxheight can't be 1x1 */
1240 /* one vertical column with possible pad bytes per row */
1241 /* average two at a time */
1243 for (jj
= 0; jj
< halfHeight
; jj
++) {
1245 for (kk
= 0; kk
< components
; kk
++) {
1247 GLfloat sfloat
[BOX2
];
1249 sfloat
[0]= __GLU_SWAP_4_BYTES(src
);
1250 sfloat
[1]= __GLU_SWAP_4_BYTES(src
+ysize
);
1253 sfloat
[0]= *(const GLfloat
*)src
;
1254 sfloat
[1]= *(const GLfloat
*)(src
+ysize
);
1256 *dest
= (sfloat
[0] + sfloat
[1]) / 2.0;
1261 src
+= padBytes
; /* add pad bytes, if any, to get to end to row */
1262 src
+= ysize
; /* skip to odd row */
1266 assert(src
== &((const char *)dataIn
)[ysize
*height
]);
1267 assert((char *)dest
== &((char *)dataOut
)
1268 [components
* element_size
* halfWidth
* halfHeight
]);
1269 } /* halve1Dimage_float() */
1271 static void scale_internal(GLint components
, GLint widthin
, GLint heightin
,
1272 const GLushort
*datain
,
1273 GLint widthout
, GLint heightout
,
1276 float x
, lowx
, highx
, convx
, halfconvx
;
1277 float y
, lowy
, highy
, convy
, halfconvy
;
1278 float xpercent
,ypercent
;
1280 /* Max components in a format is 4, so... */
1283 int i
,j
,k
,yint
,xint
,xindex
,yindex
;
1286 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1287 halveImage(components
, widthin
, heightin
, datain
, dataout
);
1290 convy
= (float) heightin
/heightout
;
1291 convx
= (float) widthin
/widthout
;
1292 halfconvx
= convx
/2;
1293 halfconvy
= convy
/2;
1294 for (i
= 0; i
< heightout
; i
++) {
1295 y
= convy
* (i
+0.5);
1296 if (heightin
> heightout
) {
1297 highy
= y
+ halfconvy
;
1298 lowy
= y
- halfconvy
;
1303 for (j
= 0; j
< widthout
; j
++) {
1304 x
= convx
* (j
+0.5);
1305 if (widthin
> widthout
) {
1306 highx
= x
+ halfconvx
;
1307 lowx
= x
- halfconvx
;
1314 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1315 ** to (highx, highy) on input data into this pixel on output
1318 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1324 yindex
= (yint
+ heightin
) % heightin
;
1325 if (highy
< yint
+1) {
1326 ypercent
= highy
- y
;
1328 ypercent
= yint
+1 - y
;
1335 xindex
= (xint
+ widthin
) % widthin
;
1336 if (highx
< xint
+1) {
1337 xpercent
= highx
- x
;
1339 xpercent
= xint
+1 - x
;
1342 percent
= xpercent
* ypercent
;
1344 temp
= (xindex
+ (yindex
* widthin
)) * components
;
1345 for (k
= 0; k
< components
; k
++) {
1346 totals
[k
] += datain
[temp
+ k
] * percent
;
1356 temp
= (j
+ (i
* widthout
)) * components
;
1357 for (k
= 0; k
< components
; k
++) {
1358 /* totals[] should be rounded in the case of enlarging an RGB
1359 * ramp when the type is 332 or 4444
1361 dataout
[temp
+ k
] = (totals
[k
]+0.5)/area
;
1367 static void scale_internal_ubyte(GLint components
, GLint widthin
,
1368 GLint heightin
, const GLubyte
*datain
,
1369 GLint widthout
, GLint heightout
,
1370 GLubyte
*dataout
, GLint element_size
,
1371 GLint ysize
, GLint group_size
)
1376 /* Max components in a format is 4, so... */
1381 const char *temp
, *temp0
;
1382 const char *temp_index
;
1385 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1386 float x_percent
, y_percent
;
1387 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1388 float convy_float
, convx_float
;
1389 int convy_int
, convx_int
;
1391 const char *left
, *right
;
1393 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1394 halveImage_ubyte(components
, widthin
, heightin
,
1395 (const GLubyte
*)datain
, (GLubyte
*)dataout
,
1396 element_size
, ysize
, group_size
);
1399 convy
= (float) heightin
/heightout
;
1400 convx
= (float) widthin
/widthout
;
1401 convy_int
= floor(convy
);
1402 convy_float
= convy
- convy_int
;
1403 convx_int
= floor(convx
);
1404 convx_float
= convx
- convx_int
;
1406 area
= convx
* convy
;
1410 highy_int
= convy_int
;
1411 highy_float
= convy_float
;
1413 for (i
= 0; i
< heightout
; i
++) {
1416 highx_int
= convx_int
;
1417 highx_float
= convx_float
;
1419 for (j
= 0; j
< widthout
; j
++) {
1422 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1423 ** to (highx, highy) on input data into this pixel on output
1426 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1428 /* calculate the value for pixels in the 1st row */
1429 xindex
= lowx_int
*group_size
;
1430 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1432 y_percent
= 1-lowy_float
;
1433 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1434 percent
= y_percent
* (1-lowx_float
);
1435 for (k
= 0, temp_index
= temp
; k
< components
;
1436 k
++, temp_index
+= element_size
) {
1437 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1440 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1442 for (k
= 0, temp_index
= temp
; k
< components
;
1443 k
++, temp_index
+= element_size
) {
1444 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1449 percent
= y_percent
* highx_float
;
1450 for (k
= 0, temp_index
= temp
; k
< components
;
1451 k
++, temp_index
+= element_size
) {
1452 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1455 /* calculate the value for pixels in the last row */
1456 y_percent
= highy_float
;
1457 percent
= y_percent
* (1-lowx_float
);
1458 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1459 for (k
= 0, temp_index
= temp
; k
< components
;
1460 k
++, temp_index
+= element_size
) {
1461 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1463 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1465 for (k
= 0, temp_index
= temp
; k
< components
;
1466 k
++, temp_index
+= element_size
) {
1467 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1471 percent
= y_percent
* highx_float
;
1472 for (k
= 0, temp_index
= temp
; k
< components
;
1473 k
++, temp_index
+= element_size
) {
1474 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1478 /* calculate the value for pixels in the 1st and last column */
1479 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1482 for (k
= 0; k
< components
;
1483 k
++, left
+= element_size
, right
+= element_size
) {
1484 totals
[k
] += (GLubyte
)(*(left
))*(1-lowx_float
)
1485 +(GLubyte
)(*(right
))*highx_float
;
1488 } else if (highy_int
> lowy_int
) {
1489 x_percent
= highx_float
- lowx_float
;
1490 percent
= (1-lowy_float
)*x_percent
;
1491 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1492 for (k
= 0, temp_index
= temp
; k
< components
;
1493 k
++, temp_index
+= element_size
) {
1494 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1496 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1498 for (k
= 0, temp_index
= temp
; k
< components
;
1499 k
++, temp_index
+= element_size
) {
1500 totals
[k
] += (GLubyte
)(*(temp_index
)) * x_percent
;
1503 percent
= x_percent
* highy_float
;
1505 for (k
= 0, temp_index
= temp
; k
< components
;
1506 k
++, temp_index
+= element_size
) {
1507 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1509 } else if (highx_int
> lowx_int
) {
1510 y_percent
= highy_float
- lowy_float
;
1511 percent
= (1-lowx_float
)*y_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 (l
= lowx_int
+1; l
< highx_int
; l
++) {
1519 for (k
= 0, temp_index
= temp
; k
< components
;
1520 k
++, temp_index
+= element_size
) {
1521 totals
[k
] += (GLubyte
)(*(temp_index
)) * y_percent
;
1525 percent
= y_percent
* highx_float
;
1526 for (k
= 0, temp_index
= temp
; k
< components
;
1527 k
++, temp_index
+= element_size
) {
1528 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1531 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1532 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1533 for (k
= 0, temp_index
= temp
; k
< components
;
1534 k
++, temp_index
+= element_size
) {
1535 totals
[k
] += (GLubyte
)(*(temp_index
)) * percent
;
1541 /* this is for the pixels in the body */
1542 temp0
= (const char *)datain
+ xindex
+ group_size
+
1544 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1546 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1547 for (k
= 0, temp_index
= temp
; k
< components
;
1548 k
++, temp_index
+= element_size
) {
1549 totals
[k
] += (GLubyte
)(*(temp_index
));
1556 outindex
= (j
+ (i
* widthout
)) * components
;
1557 for (k
= 0; k
< components
; k
++) {
1558 dataout
[outindex
+ k
] = totals
[k
]/area
;
1559 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1561 lowx_int
= highx_int
;
1562 lowx_float
= highx_float
;
1563 highx_int
+= convx_int
;
1564 highx_float
+= convx_float
;
1565 if(highx_float
> 1) {
1570 lowy_int
= highy_int
;
1571 lowy_float
= highy_float
;
1572 highy_int
+= convy_int
;
1573 highy_float
+= convy_float
;
1574 if(highy_float
> 1) {
1581 static void scale_internal_byte(GLint components
, GLint widthin
,
1582 GLint heightin
, const GLbyte
*datain
,
1583 GLint widthout
, GLint heightout
,
1584 GLbyte
*dataout
, GLint element_size
,
1585 GLint ysize
, GLint group_size
)
1590 /* Max components in a format is 4, so... */
1595 const char *temp
, *temp0
;
1596 const char *temp_index
;
1599 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1600 float x_percent
, y_percent
;
1601 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1602 float convy_float
, convx_float
;
1603 int convy_int
, convx_int
;
1605 const char *left
, *right
;
1607 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1608 halveImage_byte(components
, widthin
, heightin
,
1609 (const GLbyte
*)datain
, (GLbyte
*)dataout
,
1610 element_size
, ysize
, group_size
);
1613 convy
= (float) heightin
/heightout
;
1614 convx
= (float) widthin
/widthout
;
1615 convy_int
= floor(convy
);
1616 convy_float
= convy
- convy_int
;
1617 convx_int
= floor(convx
);
1618 convx_float
= convx
- convx_int
;
1620 area
= convx
* convy
;
1624 highy_int
= convy_int
;
1625 highy_float
= convy_float
;
1627 for (i
= 0; i
< heightout
; i
++) {
1630 highx_int
= convx_int
;
1631 highx_float
= convx_float
;
1633 for (j
= 0; j
< widthout
; j
++) {
1636 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1637 ** to (highx, highy) on input data into this pixel on output
1640 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1642 /* calculate the value for pixels in the 1st row */
1643 xindex
= lowx_int
*group_size
;
1644 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1646 y_percent
= 1-lowy_float
;
1647 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1648 percent
= y_percent
* (1-lowx_float
);
1649 for (k
= 0, temp_index
= temp
; k
< components
;
1650 k
++, temp_index
+= element_size
) {
1651 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1654 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1656 for (k
= 0, temp_index
= temp
; k
< components
;
1657 k
++, temp_index
+= element_size
) {
1658 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1663 percent
= y_percent
* highx_float
;
1664 for (k
= 0, temp_index
= temp
; k
< components
;
1665 k
++, temp_index
+= element_size
) {
1666 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1669 /* calculate the value for pixels in the last row */
1670 y_percent
= highy_float
;
1671 percent
= y_percent
* (1-lowx_float
);
1672 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1673 for (k
= 0, temp_index
= temp
; k
< components
;
1674 k
++, temp_index
+= element_size
) {
1675 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1677 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1679 for (k
= 0, temp_index
= temp
; k
< components
;
1680 k
++, temp_index
+= element_size
) {
1681 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1685 percent
= y_percent
* highx_float
;
1686 for (k
= 0, temp_index
= temp
; k
< components
;
1687 k
++, temp_index
+= element_size
) {
1688 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1692 /* calculate the value for pixels in the 1st and last column */
1693 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1696 for (k
= 0; k
< components
;
1697 k
++, left
+= element_size
, right
+= element_size
) {
1698 totals
[k
] += (GLbyte
)(*(left
))*(1-lowx_float
)
1699 +(GLbyte
)(*(right
))*highx_float
;
1702 } else if (highy_int
> lowy_int
) {
1703 x_percent
= highx_float
- lowx_float
;
1704 percent
= (1-lowy_float
)*x_percent
;
1705 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1706 for (k
= 0, temp_index
= temp
; k
< components
;
1707 k
++, temp_index
+= element_size
) {
1708 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1710 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1712 for (k
= 0, temp_index
= temp
; k
< components
;
1713 k
++, temp_index
+= element_size
) {
1714 totals
[k
] += (GLbyte
)(*(temp_index
)) * x_percent
;
1717 percent
= x_percent
* highy_float
;
1719 for (k
= 0, temp_index
= temp
; k
< components
;
1720 k
++, temp_index
+= element_size
) {
1721 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1723 } else if (highx_int
> lowx_int
) {
1724 y_percent
= highy_float
- lowy_float
;
1725 percent
= (1-lowx_float
)*y_percent
;
1726 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1727 for (k
= 0, temp_index
= temp
; k
< components
;
1728 k
++, temp_index
+= element_size
) {
1729 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1731 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1733 for (k
= 0, temp_index
= temp
; k
< components
;
1734 k
++, temp_index
+= element_size
) {
1735 totals
[k
] += (GLbyte
)(*(temp_index
)) * y_percent
;
1739 percent
= y_percent
* highx_float
;
1740 for (k
= 0, temp_index
= temp
; k
< components
;
1741 k
++, temp_index
+= element_size
) {
1742 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1745 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
1746 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1747 for (k
= 0, temp_index
= temp
; k
< components
;
1748 k
++, temp_index
+= element_size
) {
1749 totals
[k
] += (GLbyte
)(*(temp_index
)) * percent
;
1755 /* this is for the pixels in the body */
1756 temp0
= (const char *)datain
+ xindex
+ group_size
+
1758 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
1760 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1761 for (k
= 0, temp_index
= temp
; k
< components
;
1762 k
++, temp_index
+= element_size
) {
1763 totals
[k
] += (GLbyte
)(*(temp_index
));
1770 outindex
= (j
+ (i
* widthout
)) * components
;
1771 for (k
= 0; k
< components
; k
++) {
1772 dataout
[outindex
+ k
] = totals
[k
]/area
;
1773 /*printf("totals[%d] = %f\n", k, totals[k]);*/
1775 lowx_int
= highx_int
;
1776 lowx_float
= highx_float
;
1777 highx_int
+= convx_int
;
1778 highx_float
+= convx_float
;
1779 if(highx_float
> 1) {
1784 lowy_int
= highy_int
;
1785 lowy_float
= highy_float
;
1786 highy_int
+= convy_int
;
1787 highy_float
+= convy_float
;
1788 if(highy_float
> 1) {
1795 static void scale_internal_ushort(GLint components
, GLint widthin
,
1796 GLint heightin
, const GLushort
*datain
,
1797 GLint widthout
, GLint heightout
,
1798 GLushort
*dataout
, GLint element_size
,
1799 GLint ysize
, GLint group_size
,
1805 /* Max components in a format is 4, so... */
1810 const char *temp
, *temp0
;
1811 const char *temp_index
;
1814 int lowx_int
, highx_int
, lowy_int
, highy_int
;
1815 float x_percent
, y_percent
;
1816 float lowx_float
, highx_float
, lowy_float
, highy_float
;
1817 float convy_float
, convx_float
;
1818 int convy_int
, convx_int
;
1820 const char *left
, *right
;
1822 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
1823 halveImage_ushort(components
, widthin
, heightin
,
1824 (const GLushort
*)datain
, (GLushort
*)dataout
,
1825 element_size
, ysize
, group_size
, myswap_bytes
);
1828 convy
= (float) heightin
/heightout
;
1829 convx
= (float) widthin
/widthout
;
1830 convy_int
= floor(convy
);
1831 convy_float
= convy
- convy_int
;
1832 convx_int
= floor(convx
);
1833 convx_float
= convx
- convx_int
;
1835 area
= convx
* convy
;
1839 highy_int
= convy_int
;
1840 highy_float
= convy_float
;
1842 for (i
= 0; i
< heightout
; i
++) {
1845 highx_int
= convx_int
;
1846 highx_float
= convx_float
;
1848 for (j
= 0; j
< widthout
; j
++) {
1850 ** Ok, now apply box filter to box that goes from (lowx, lowy)
1851 ** to (highx, highy) on input data into this pixel on output
1854 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
1856 /* calculate the value for pixels in the 1st row */
1857 xindex
= lowx_int
*group_size
;
1858 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
1860 y_percent
= 1-lowy_float
;
1861 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
1862 percent
= y_percent
* (1-lowx_float
);
1863 for (k
= 0, temp_index
= temp
; k
< components
;
1864 k
++, temp_index
+= element_size
) {
1866 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1868 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1872 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1874 for (k
= 0, temp_index
= temp
; k
< components
;
1875 k
++, temp_index
+= element_size
) {
1878 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1880 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1886 percent
= y_percent
* highx_float
;
1887 for (k
= 0, temp_index
= temp
; k
< components
;
1888 k
++, temp_index
+= element_size
) {
1890 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1892 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1896 /* calculate the value for pixels in the last row */
1897 y_percent
= highy_float
;
1898 percent
= y_percent
* (1-lowx_float
);
1899 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
1900 for (k
= 0, temp_index
= temp
; k
< components
;
1901 k
++, temp_index
+= element_size
) {
1903 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1905 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1908 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
1910 for (k
= 0, temp_index
= temp
; k
< components
;
1911 k
++, temp_index
+= element_size
) {
1914 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
1916 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
1921 percent
= y_percent
* highx_float
;
1922 for (k
= 0, temp_index
= temp
; k
< components
;
1923 k
++, temp_index
+= element_size
) {
1925 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1927 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1931 /* calculate the value for pixels in the 1st and last column */
1932 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1935 for (k
= 0; k
< components
;
1936 k
++, left
+= element_size
, right
+= element_size
) {
1939 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
1940 __GLU_SWAP_2_BYTES(right
) * highx_float
;
1942 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
1943 + *(const GLushort
*)right
* highx_float
;
1947 } else if (highy_int
> lowy_int
) {
1948 x_percent
= highx_float
- lowx_float
;
1949 percent
= (1-lowy_float
)*x_percent
;
1950 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1951 for (k
= 0, temp_index
= temp
; k
< components
;
1952 k
++, temp_index
+= element_size
) {
1954 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1956 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1959 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
1961 for (k
= 0, temp_index
= temp
; k
< components
;
1962 k
++, temp_index
+= element_size
) {
1965 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
1967 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
1971 percent
= x_percent
* highy_float
;
1973 for (k
= 0, temp_index
= temp
; k
< components
;
1974 k
++, temp_index
+= element_size
) {
1976 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1978 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1981 } else if (highx_int
> lowx_int
) {
1982 y_percent
= highy_float
- lowy_float
;
1983 percent
= (1-lowx_float
)*y_percent
;
1984 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
1985 for (k
= 0, temp_index
= temp
; k
< components
;
1986 k
++, temp_index
+= element_size
) {
1988 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
1990 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
1993 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
1995 for (k
= 0, temp_index
= temp
; k
< components
;
1996 k
++, temp_index
+= element_size
) {
1999 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
2001 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
2006 percent
= y_percent
* highx_float
;
2007 for (k
= 0, temp_index
= temp
; k
< components
;
2008 k
++, temp_index
+= element_size
) {
2010 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2012 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2016 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2017 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2018 for (k
= 0, temp_index
= temp
; k
< components
;
2019 k
++, temp_index
+= element_size
) {
2021 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
2023 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
2028 /* this is for the pixels in the body */
2029 temp0
= (const char *)datain
+ xindex
+ group_size
+
2031 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2033 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2034 for (k
= 0, temp_index
= temp
; k
< components
;
2035 k
++, temp_index
+= element_size
) {
2037 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
2039 totals
[k
] += *(const GLushort
*)temp_index
;
2047 outindex
= (j
+ (i
* widthout
)) * components
;
2048 for (k
= 0; k
< components
; k
++) {
2049 dataout
[outindex
+ k
] = totals
[k
]/area
;
2050 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2052 lowx_int
= highx_int
;
2053 lowx_float
= highx_float
;
2054 highx_int
+= convx_int
;
2055 highx_float
+= convx_float
;
2056 if(highx_float
> 1) {
2061 lowy_int
= highy_int
;
2062 lowy_float
= highy_float
;
2063 highy_int
+= convy_int
;
2064 highy_float
+= convy_float
;
2065 if(highy_float
> 1) {
2072 static void scale_internal_short(GLint components
, GLint widthin
,
2073 GLint heightin
, const GLshort
*datain
,
2074 GLint widthout
, GLint heightout
,
2075 GLshort
*dataout
, GLint element_size
,
2076 GLint ysize
, GLint group_size
,
2082 /* Max components in a format is 4, so... */
2087 const char *temp
, *temp0
;
2088 const char *temp_index
;
2091 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2092 float x_percent
, y_percent
;
2093 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2094 float convy_float
, convx_float
;
2095 int convy_int
, convx_int
;
2097 const char *left
, *right
;
2099 GLushort swapbuf
; /* unsigned buffer */
2101 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2102 halveImage_short(components
, widthin
, heightin
,
2103 (const GLshort
*)datain
, (GLshort
*)dataout
,
2104 element_size
, ysize
, group_size
, myswap_bytes
);
2107 convy
= (float) heightin
/heightout
;
2108 convx
= (float) widthin
/widthout
;
2109 convy_int
= floor(convy
);
2110 convy_float
= convy
- convy_int
;
2111 convx_int
= floor(convx
);
2112 convx_float
= convx
- convx_int
;
2114 area
= convx
* convy
;
2118 highy_int
= convy_int
;
2119 highy_float
= convy_float
;
2121 for (i
= 0; i
< heightout
; i
++) {
2124 highx_int
= convx_int
;
2125 highx_float
= convx_float
;
2127 for (j
= 0; j
< widthout
; j
++) {
2129 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2130 ** to (highx, highy) on input data into this pixel on output
2133 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2135 /* calculate the value for pixels in the 1st row */
2136 xindex
= lowx_int
*group_size
;
2137 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2139 y_percent
= 1-lowy_float
;
2140 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2141 percent
= y_percent
* (1-lowx_float
);
2142 for (k
= 0, temp_index
= temp
; k
< components
;
2143 k
++, temp_index
+= element_size
) {
2145 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2146 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2148 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2152 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2154 for (k
= 0, temp_index
= temp
; k
< components
;
2155 k
++, temp_index
+= element_size
) {
2157 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2158 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2160 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2166 percent
= y_percent
* highx_float
;
2167 for (k
= 0, temp_index
= temp
; k
< components
;
2168 k
++, temp_index
+= element_size
) {
2170 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2171 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2173 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2177 /* calculate the value for pixels in the last row */
2178 y_percent
= highy_float
;
2179 percent
= y_percent
* (1-lowx_float
);
2180 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2181 for (k
= 0, temp_index
= temp
; k
< components
;
2182 k
++, temp_index
+= element_size
) {
2184 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2185 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2187 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2190 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2192 for (k
= 0, temp_index
= temp
; k
< components
;
2193 k
++, temp_index
+= element_size
) {
2195 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2196 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2198 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2203 percent
= y_percent
* highx_float
;
2204 for (k
= 0, temp_index
= temp
; k
< components
;
2205 k
++, temp_index
+= element_size
) {
2207 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2208 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2210 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2214 /* calculate the value for pixels in the 1st and last column */
2215 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2218 for (k
= 0; k
< components
;
2219 k
++, left
+= element_size
, right
+= element_size
) {
2221 swapbuf
= __GLU_SWAP_2_BYTES(left
);
2222 totals
[k
] += *(const GLshort
*)&swapbuf
* (1-lowx_float
);
2223 swapbuf
= __GLU_SWAP_2_BYTES(right
);
2224 totals
[k
] += *(const GLshort
*)&swapbuf
* highx_float
;
2226 totals
[k
] += *(const GLshort
*)left
* (1-lowx_float
)
2227 + *(const GLshort
*)right
* highx_float
;
2231 } else if (highy_int
> lowy_int
) {
2232 x_percent
= highx_float
- lowx_float
;
2233 percent
= (1-lowy_float
)*x_percent
;
2234 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2235 for (k
= 0, temp_index
= temp
; k
< components
;
2236 k
++, temp_index
+= element_size
) {
2238 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2239 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2241 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2244 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2246 for (k
= 0, temp_index
= temp
; k
< components
;
2247 k
++, temp_index
+= element_size
) {
2249 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2250 totals
[k
] += *(const GLshort
*)&swapbuf
* x_percent
;
2252 totals
[k
] += *(const GLshort
*)temp_index
* x_percent
;
2256 percent
= x_percent
* highy_float
;
2258 for (k
= 0, temp_index
= temp
; k
< components
;
2259 k
++, temp_index
+= element_size
) {
2261 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2262 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2264 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2267 } else if (highx_int
> lowx_int
) {
2268 y_percent
= highy_float
- lowy_float
;
2269 percent
= (1-lowx_float
)*y_percent
;
2271 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2272 for (k
= 0, temp_index
= temp
; k
< components
;
2273 k
++, temp_index
+= element_size
) {
2275 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2276 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2278 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2281 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2283 for (k
= 0, temp_index
= temp
; k
< components
;
2284 k
++, temp_index
+= element_size
) {
2286 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2287 totals
[k
] += *(const GLshort
*)&swapbuf
* y_percent
;
2289 totals
[k
] += *(const GLshort
*)temp_index
* y_percent
;
2294 percent
= y_percent
* highx_float
;
2295 for (k
= 0, temp_index
= temp
; k
< components
;
2296 k
++, temp_index
+= element_size
) {
2298 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2299 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2301 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2305 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2306 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2307 for (k
= 0, temp_index
= temp
; k
< components
;
2308 k
++, temp_index
+= element_size
) {
2310 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2311 totals
[k
] += *(const GLshort
*)&swapbuf
* percent
;
2313 totals
[k
] += *(const GLshort
*)temp_index
* percent
;
2318 /* this is for the pixels in the body */
2319 temp0
= (const char *)datain
+ xindex
+ group_size
+
2321 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2323 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2324 for (k
= 0, temp_index
= temp
; k
< components
;
2325 k
++, temp_index
+= element_size
) {
2327 swapbuf
= __GLU_SWAP_2_BYTES(temp_index
);
2328 totals
[k
] += *(const GLshort
*)&swapbuf
;
2330 totals
[k
] += *(const GLshort
*)temp_index
;
2338 outindex
= (j
+ (i
* widthout
)) * components
;
2339 for (k
= 0; k
< components
; k
++) {
2340 dataout
[outindex
+ k
] = totals
[k
]/area
;
2341 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2343 lowx_int
= highx_int
;
2344 lowx_float
= highx_float
;
2345 highx_int
+= convx_int
;
2346 highx_float
+= convx_float
;
2347 if(highx_float
> 1) {
2352 lowy_int
= highy_int
;
2353 lowy_float
= highy_float
;
2354 highy_int
+= convy_int
;
2355 highy_float
+= convy_float
;
2356 if(highy_float
> 1) {
2363 static void scale_internal_uint(GLint components
, GLint widthin
,
2364 GLint heightin
, const GLuint
*datain
,
2365 GLint widthout
, GLint heightout
,
2366 GLuint
*dataout
, GLint element_size
,
2367 GLint ysize
, GLint group_size
,
2373 /* Max components in a format is 4, so... */
2378 const char *temp
, *temp0
;
2379 const char *temp_index
;
2382 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2383 float x_percent
, y_percent
;
2384 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2385 float convy_float
, convx_float
;
2386 int convy_int
, convx_int
;
2388 const char *left
, *right
;
2390 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2391 halveImage_uint(components
, widthin
, heightin
,
2392 (const GLuint
*)datain
, (GLuint
*)dataout
,
2393 element_size
, ysize
, group_size
, myswap_bytes
);
2396 convy
= (float) heightin
/heightout
;
2397 convx
= (float) widthin
/widthout
;
2398 convy_int
= floor(convy
);
2399 convy_float
= convy
- convy_int
;
2400 convx_int
= floor(convx
);
2401 convx_float
= convx
- convx_int
;
2403 area
= convx
* convy
;
2407 highy_int
= convy_int
;
2408 highy_float
= convy_float
;
2410 for (i
= 0; i
< heightout
; i
++) {
2413 highx_int
= convx_int
;
2414 highx_float
= convx_float
;
2416 for (j
= 0; j
< widthout
; j
++) {
2418 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2419 ** to (highx, highy) on input data into this pixel on output
2422 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2424 /* calculate the value for pixels in the 1st row */
2425 xindex
= lowx_int
*group_size
;
2426 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2428 y_percent
= 1-lowy_float
;
2429 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2430 percent
= y_percent
* (1-lowx_float
);
2431 for (k
= 0, temp_index
= temp
; k
< components
;
2432 k
++, temp_index
+= element_size
) {
2434 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2436 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2440 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2442 for (k
= 0, temp_index
= temp
; k
< components
;
2443 k
++, temp_index
+= element_size
) {
2446 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2448 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2454 percent
= y_percent
* highx_float
;
2455 for (k
= 0, temp_index
= temp
; k
< components
;
2456 k
++, temp_index
+= element_size
) {
2458 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2460 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2464 /* calculate the value for pixels in the last row */
2465 y_percent
= highy_float
;
2466 percent
= y_percent
* (1-lowx_float
);
2467 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2468 for (k
= 0, temp_index
= temp
; k
< components
;
2469 k
++, temp_index
+= element_size
) {
2471 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2473 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2476 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2478 for (k
= 0, temp_index
= temp
; k
< components
;
2479 k
++, temp_index
+= element_size
) {
2482 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2484 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2489 percent
= y_percent
* highx_float
;
2490 for (k
= 0, temp_index
= temp
; k
< components
;
2491 k
++, temp_index
+= element_size
) {
2493 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2495 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2499 /* calculate the value for pixels in the 1st and last column */
2500 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2503 for (k
= 0; k
< components
;
2504 k
++, left
+= element_size
, right
+= element_size
) {
2507 __GLU_SWAP_4_BYTES(left
) * (1-lowx_float
)
2508 + __GLU_SWAP_4_BYTES(right
) * highx_float
;
2510 totals
[k
] += *(const GLuint
*)left
* (1-lowx_float
)
2511 + *(const GLuint
*)right
* highx_float
;
2515 } else if (highy_int
> lowy_int
) {
2516 x_percent
= highx_float
- lowx_float
;
2517 percent
= (1-lowy_float
)*x_percent
;
2518 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2519 for (k
= 0, temp_index
= temp
; k
< components
;
2520 k
++, temp_index
+= element_size
) {
2522 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2524 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2527 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2529 for (k
= 0, temp_index
= temp
; k
< components
;
2530 k
++, temp_index
+= element_size
) {
2533 __GLU_SWAP_4_BYTES(temp_index
) * x_percent
;
2535 totals
[k
] += *(const GLuint
*)temp_index
* x_percent
;
2539 percent
= x_percent
* highy_float
;
2541 for (k
= 0, temp_index
= temp
; k
< components
;
2542 k
++, temp_index
+= element_size
) {
2544 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2546 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2549 } else if (highx_int
> lowx_int
) {
2550 y_percent
= highy_float
- lowy_float
;
2551 percent
= (1-lowx_float
)*y_percent
;
2553 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2554 for (k
= 0, temp_index
= temp
; k
< components
;
2555 k
++, temp_index
+= element_size
) {
2557 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2559 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2562 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2564 for (k
= 0, temp_index
= temp
; k
< components
;
2565 k
++, temp_index
+= element_size
) {
2568 __GLU_SWAP_4_BYTES(temp_index
) * y_percent
;
2570 totals
[k
] += *(const GLuint
*)temp_index
* y_percent
;
2575 percent
= y_percent
* highx_float
;
2576 for (k
= 0, temp_index
= temp
; k
< components
;
2577 k
++, temp_index
+= element_size
) {
2579 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
) * percent
;
2581 totals
[k
] += *(const GLuint
*)temp_index
* percent
;
2585 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
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
;
2597 /* this is for the pixels in the body */
2598 temp0
= (const char *)datain
+ xindex
+ group_size
+
2600 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2602 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2603 for (k
= 0, temp_index
= temp
; k
< components
;
2604 k
++, temp_index
+= element_size
) {
2606 totals
[k
] += __GLU_SWAP_4_BYTES(temp_index
);
2608 totals
[k
] += *(const GLuint
*)temp_index
;
2616 outindex
= (j
+ (i
* widthout
)) * components
;
2617 for (k
= 0; k
< components
; k
++) {
2618 /* clamp at UINT_MAX */
2619 float value
= totals
[k
]/area
;
2620 if (value
>= (float) UINT_MAX
) { /* need '=' */
2621 dataout
[outindex
+ k
] = UINT_MAX
;
2623 else dataout
[outindex
+ k
] = value
;
2625 lowx_int
= highx_int
;
2626 lowx_float
= highx_float
;
2627 highx_int
+= convx_int
;
2628 highx_float
+= convx_float
;
2629 if(highx_float
> 1) {
2634 lowy_int
= highy_int
;
2635 lowy_float
= highy_float
;
2636 highy_int
+= convy_int
;
2637 highy_float
+= convy_float
;
2638 if(highy_float
> 1) {
2647 static void scale_internal_int(GLint components
, GLint widthin
,
2648 GLint heightin
, const GLint
*datain
,
2649 GLint widthout
, GLint heightout
,
2650 GLint
*dataout
, GLint element_size
,
2651 GLint ysize
, GLint group_size
,
2657 /* Max components in a format is 4, so... */
2662 const char *temp
, *temp0
;
2663 const char *temp_index
;
2666 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2667 float x_percent
, y_percent
;
2668 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2669 float convy_float
, convx_float
;
2670 int convy_int
, convx_int
;
2672 const char *left
, *right
;
2674 GLuint swapbuf
; /* unsigned buffer */
2676 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2677 halveImage_int(components
, widthin
, heightin
,
2678 (const GLint
*)datain
, (GLint
*)dataout
,
2679 element_size
, ysize
, group_size
, myswap_bytes
);
2682 convy
= (float) heightin
/heightout
;
2683 convx
= (float) widthin
/widthout
;
2684 convy_int
= floor(convy
);
2685 convy_float
= convy
- convy_int
;
2686 convx_int
= floor(convx
);
2687 convx_float
= convx
- convx_int
;
2689 area
= convx
* convy
;
2693 highy_int
= convy_int
;
2694 highy_float
= convy_float
;
2696 for (i
= 0; i
< heightout
; i
++) {
2699 highx_int
= convx_int
;
2700 highx_float
= convx_float
;
2702 for (j
= 0; j
< widthout
; j
++) {
2704 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2705 ** to (highx, highy) on input data into this pixel on output
2708 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
2710 /* calculate the value for pixels in the 1st row */
2711 xindex
= lowx_int
*group_size
;
2712 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
2714 y_percent
= 1-lowy_float
;
2715 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2716 percent
= y_percent
* (1-lowx_float
);
2717 for (k
= 0, temp_index
= temp
; k
< components
;
2718 k
++, temp_index
+= element_size
) {
2720 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2721 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2723 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2727 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2729 for (k
= 0, temp_index
= temp
; k
< components
;
2730 k
++, temp_index
+= element_size
) {
2732 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2733 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2735 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2741 percent
= y_percent
* highx_float
;
2742 for (k
= 0, temp_index
= temp
; k
< components
;
2743 k
++, temp_index
+= element_size
) {
2745 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2746 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2748 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2752 /* calculate the value for pixels in the last row */
2753 y_percent
= highy_float
;
2754 percent
= y_percent
* (1-lowx_float
);
2755 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
2756 for (k
= 0, temp_index
= temp
; k
< components
;
2757 k
++, temp_index
+= element_size
) {
2759 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2760 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2762 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2765 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2767 for (k
= 0, temp_index
= temp
; k
< components
;
2768 k
++, temp_index
+= element_size
) {
2770 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2771 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2773 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2778 percent
= y_percent
* highx_float
;
2779 for (k
= 0, temp_index
= temp
; k
< components
;
2780 k
++, temp_index
+= element_size
) {
2782 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2783 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2785 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2789 /* calculate the value for pixels in the 1st and last column */
2790 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2793 for (k
= 0; k
< components
;
2794 k
++, left
+= element_size
, right
+= element_size
) {
2796 swapbuf
= __GLU_SWAP_4_BYTES(left
);
2797 totals
[k
] += *(const GLint
*)&swapbuf
* (1-lowx_float
);
2798 swapbuf
= __GLU_SWAP_4_BYTES(right
);
2799 totals
[k
] += *(const GLint
*)&swapbuf
* highx_float
;
2801 totals
[k
] += *(const GLint
*)left
* (1-lowx_float
)
2802 + *(const GLint
*)right
* highx_float
;
2806 } else if (highy_int
> lowy_int
) {
2807 x_percent
= highx_float
- lowx_float
;
2808 percent
= (1-lowy_float
)*x_percent
;
2809 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2810 for (k
= 0, temp_index
= temp
; k
< components
;
2811 k
++, temp_index
+= element_size
) {
2813 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2814 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2816 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2819 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
2821 for (k
= 0, temp_index
= temp
; k
< components
;
2822 k
++, temp_index
+= element_size
) {
2824 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2825 totals
[k
] += *(const GLint
*)&swapbuf
* x_percent
;
2827 totals
[k
] += *(const GLint
*)temp_index
* x_percent
;
2831 percent
= x_percent
* highy_float
;
2833 for (k
= 0, temp_index
= temp
; k
< components
;
2834 k
++, temp_index
+= element_size
) {
2836 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2837 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2839 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2842 } else if (highx_int
> lowx_int
) {
2843 y_percent
= highy_float
- lowy_float
;
2844 percent
= (1-lowx_float
)*y_percent
;
2846 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
2847 for (k
= 0, temp_index
= temp
; k
< components
;
2848 k
++, temp_index
+= element_size
) {
2850 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2851 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2853 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2856 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
2858 for (k
= 0, temp_index
= temp
; k
< components
;
2859 k
++, temp_index
+= element_size
) {
2861 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2862 totals
[k
] += *(const GLint
*)&swapbuf
* y_percent
;
2864 totals
[k
] += *(const GLint
*)temp_index
* y_percent
;
2869 percent
= y_percent
* highx_float
;
2870 for (k
= 0, temp_index
= temp
; k
< components
;
2871 k
++, temp_index
+= element_size
) {
2873 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2874 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2876 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2880 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
2881 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
2882 for (k
= 0, temp_index
= temp
; k
< components
;
2883 k
++, temp_index
+= element_size
) {
2885 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2886 totals
[k
] += *(const GLint
*)&swapbuf
* percent
;
2888 totals
[k
] += *(const GLint
*)temp_index
* percent
;
2893 /* this is for the pixels in the body */
2894 temp0
= (const char *)datain
+ xindex
+ group_size
+
2896 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
2898 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
2899 for (k
= 0, temp_index
= temp
; k
< components
;
2900 k
++, temp_index
+= element_size
) {
2902 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
2903 totals
[k
] += *(const GLint
*)&swapbuf
;
2905 totals
[k
] += *(const GLint
*)temp_index
;
2913 outindex
= (j
+ (i
* widthout
)) * components
;
2914 for (k
= 0; k
< components
; k
++) {
2915 dataout
[outindex
+ k
] = totals
[k
]/area
;
2916 /*printf("totals[%d] = %f\n", k, totals[k]);*/
2918 lowx_int
= highx_int
;
2919 lowx_float
= highx_float
;
2920 highx_int
+= convx_int
;
2921 highx_float
+= convx_float
;
2922 if(highx_float
> 1) {
2927 lowy_int
= highy_int
;
2928 lowy_float
= highy_float
;
2929 highy_int
+= convy_int
;
2930 highy_float
+= convy_float
;
2931 if(highy_float
> 1) {
2940 static void scale_internal_float(GLint components
, GLint widthin
,
2941 GLint heightin
, const GLfloat
*datain
,
2942 GLint widthout
, GLint heightout
,
2943 GLfloat
*dataout
, GLint element_size
,
2944 GLint ysize
, GLint group_size
,
2950 /* Max components in a format is 4, so... */
2955 const char *temp
, *temp0
;
2956 const char *temp_index
;
2959 int lowx_int
, highx_int
, lowy_int
, highy_int
;
2960 float x_percent
, y_percent
;
2961 float lowx_float
, highx_float
, lowy_float
, highy_float
;
2962 float convy_float
, convx_float
;
2963 int convy_int
, convx_int
;
2965 const char *left
, *right
;
2967 GLuint swapbuf
; /* unsigned buffer */
2969 if (widthin
== widthout
*2 && heightin
== heightout
*2) {
2970 halveImage_float(components
, widthin
, heightin
,
2971 (const GLfloat
*)datain
, (GLfloat
*)dataout
,
2972 element_size
, ysize
, group_size
, myswap_bytes
);
2975 convy
= (float) heightin
/heightout
;
2976 convx
= (float) widthin
/widthout
;
2977 convy_int
= floor(convy
);
2978 convy_float
= convy
- convy_int
;
2979 convx_int
= floor(convx
);
2980 convx_float
= convx
- convx_int
;
2982 area
= convx
* convy
;
2986 highy_int
= convy_int
;
2987 highy_float
= convy_float
;
2989 for (i
= 0; i
< heightout
; i
++) {
2992 highx_int
= convx_int
;
2993 highx_float
= convx_float
;
2995 for (j
= 0; j
< widthout
; j
++) {
2997 ** Ok, now apply box filter to box that goes from (lowx, lowy)
2998 ** to (highx, highy) on input data into this pixel on output
3001 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
3003 /* calculate the value for pixels in the 1st row */
3004 xindex
= lowx_int
*group_size
;
3005 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
3007 y_percent
= 1-lowy_float
;
3008 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3009 percent
= y_percent
* (1-lowx_float
);
3010 for (k
= 0, temp_index
= temp
; k
< components
;
3011 k
++, temp_index
+= element_size
) {
3013 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3014 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3016 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3020 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3022 for (k
= 0, temp_index
= temp
; k
< components
;
3023 k
++, temp_index
+= element_size
) {
3025 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3026 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3028 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3034 percent
= y_percent
* highx_float
;
3035 for (k
= 0, temp_index
= temp
; k
< components
;
3036 k
++, temp_index
+= element_size
) {
3038 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3039 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3041 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3045 /* calculate the value for pixels in the last row */
3046 y_percent
= highy_float
;
3047 percent
= y_percent
* (1-lowx_float
);
3048 temp
= (const char *)datain
+ xindex
+ highy_int
* ysize
;
3049 for (k
= 0, temp_index
= temp
; k
< components
;
3050 k
++, temp_index
+= element_size
) {
3052 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3053 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3055 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3058 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3060 for (k
= 0, temp_index
= temp
; k
< components
;
3061 k
++, temp_index
+= element_size
) {
3063 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3064 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3066 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3071 percent
= y_percent
* highx_float
;
3072 for (k
= 0, temp_index
= temp
; k
< components
;
3073 k
++, temp_index
+= element_size
) {
3075 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3076 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3078 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3082 /* calculate the value for pixels in the 1st and last column */
3083 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3086 for (k
= 0; k
< components
;
3087 k
++, left
+= element_size
, right
+= element_size
) {
3089 swapbuf
= __GLU_SWAP_4_BYTES(left
);
3090 totals
[k
] += *(const GLfloat
*)&swapbuf
* (1-lowx_float
);
3091 swapbuf
= __GLU_SWAP_4_BYTES(right
);
3092 totals
[k
] += *(const GLfloat
*)&swapbuf
* highx_float
;
3094 totals
[k
] += *(const GLfloat
*)left
* (1-lowx_float
)
3095 + *(const GLfloat
*)right
* highx_float
;
3099 } else if (highy_int
> lowy_int
) {
3100 x_percent
= highx_float
- lowx_float
;
3101 percent
= (1-lowy_float
)*x_percent
;
3102 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3103 for (k
= 0, temp_index
= temp
; k
< components
;
3104 k
++, temp_index
+= element_size
) {
3106 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3107 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3109 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3112 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
3114 for (k
= 0, temp_index
= temp
; k
< components
;
3115 k
++, temp_index
+= element_size
) {
3117 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3118 totals
[k
] += *(const GLfloat
*)&swapbuf
* x_percent
;
3120 totals
[k
] += *(const GLfloat
*)temp_index
* x_percent
;
3124 percent
= x_percent
* highy_float
;
3126 for (k
= 0, temp_index
= temp
; k
< components
;
3127 k
++, temp_index
+= element_size
) {
3129 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3130 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3132 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3135 } else if (highx_int
> lowx_int
) {
3136 y_percent
= highy_float
- lowy_float
;
3137 percent
= (1-lowx_float
)*y_percent
;
3139 temp
= (const char *)datain
+ xindex
+ lowy_int
*ysize
;
3140 for (k
= 0, temp_index
= temp
; k
< components
;
3141 k
++, temp_index
+= element_size
) {
3143 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3144 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3146 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3149 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
3151 for (k
= 0, temp_index
= temp
; k
< components
;
3152 k
++, temp_index
+= element_size
) {
3154 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3155 totals
[k
] += *(const GLfloat
*)&swapbuf
* y_percent
;
3157 totals
[k
] += *(const GLfloat
*)temp_index
* y_percent
;
3162 percent
= y_percent
* highx_float
;
3163 for (k
= 0, temp_index
= temp
; k
< components
;
3164 k
++, temp_index
+= element_size
) {
3166 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3167 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3169 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3173 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
3174 temp
= (const char *)datain
+ xindex
+ lowy_int
* ysize
;
3175 for (k
= 0, temp_index
= temp
; k
< components
;
3176 k
++, temp_index
+= element_size
) {
3178 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3179 totals
[k
] += *(const GLfloat
*)&swapbuf
* percent
;
3181 totals
[k
] += *(const GLfloat
*)temp_index
* percent
;
3186 /* this is for the pixels in the body */
3187 temp0
= (const char *)datain
+ xindex
+ group_size
+
3189 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
3191 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
3192 for (k
= 0, temp_index
= temp
; k
< components
;
3193 k
++, temp_index
+= element_size
) {
3195 swapbuf
= __GLU_SWAP_4_BYTES(temp_index
);
3196 totals
[k
] += *(const GLfloat
*)&swapbuf
;
3198 totals
[k
] += *(const GLfloat
*)temp_index
;
3206 outindex
= (j
+ (i
* widthout
)) * components
;
3207 for (k
= 0; k
< components
; k
++) {
3208 dataout
[outindex
+ k
] = totals
[k
]/area
;
3209 /*printf("totals[%d] = %f\n", k, totals[k]);*/
3211 lowx_int
= highx_int
;
3212 lowx_float
= highx_float
;
3213 highx_int
+= convx_int
;
3214 highx_float
+= convx_float
;
3215 if(highx_float
> 1) {
3220 lowy_int
= highy_int
;
3221 lowy_float
= highy_float
;
3222 highy_int
+= convy_int
;
3223 highy_float
+= convy_float
;
3224 if(highy_float
> 1) {
3231 static int checkMipmapArgs(GLenum internalFormat
, GLenum format
, GLenum type
)
3233 if (!legalFormat(format
) || !legalType(type
)) {
3234 return GLU_INVALID_ENUM
;
3236 if (format
== GL_STENCIL_INDEX
) {
3237 return GLU_INVALID_ENUM
;
3240 if (!isLegalFormatForPackedPixelType(format
, type
)) {
3241 return GLU_INVALID_OPERATION
;
3245 } /* checkMipmapArgs() */
3247 static GLboolean
legalFormat(GLenum format
)
3250 case GL_COLOR_INDEX
:
3251 case GL_STENCIL_INDEX
:
3252 case GL_DEPTH_COMPONENT
:
3260 case GL_LUMINANCE_ALPHA
:
3270 static GLboolean
legalType(GLenum type
)
3275 case GL_UNSIGNED_BYTE
:
3277 case GL_UNSIGNED_SHORT
:
3279 case GL_UNSIGNED_INT
:
3281 case GL_UNSIGNED_BYTE_3_3_2
:
3282 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3283 case GL_UNSIGNED_SHORT_5_6_5
:
3284 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3285 case GL_UNSIGNED_SHORT_4_4_4_4
:
3286 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3287 case GL_UNSIGNED_SHORT_5_5_5_1
:
3288 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3289 case GL_UNSIGNED_INT_8_8_8_8
:
3290 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3291 case GL_UNSIGNED_INT_10_10_10_2
:
3292 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3300 static GLboolean
isTypePackedPixel(GLenum type
)
3302 assert(legalType(type
));
3304 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
3305 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3306 type
== GL_UNSIGNED_SHORT_5_6_5
||
3307 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
3308 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3309 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3310 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3311 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3312 type
== GL_UNSIGNED_INT_8_8_8_8
||
3313 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3314 type
== GL_UNSIGNED_INT_10_10_10_2
||
3315 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
3319 } /* isTypePackedPixel() */
3321 /* Determines if the packed pixel type is compatible with the format */
3322 static GLboolean
isLegalFormatForPackedPixelType(GLenum format
, GLenum type
)
3324 /* if not a packed pixel type then return true */
3325 if (!isTypePackedPixel(type
)) {
3329 /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
3330 if ((type
== GL_UNSIGNED_BYTE_3_3_2
|| type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
3331 type
== GL_UNSIGNED_SHORT_5_6_5
|| type
== GL_UNSIGNED_SHORT_5_6_5_REV
)
3332 && format
!= GL_RGB
)
3335 /* 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 &
3336 * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
3338 if ((type
== GL_UNSIGNED_SHORT_4_4_4_4
||
3339 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
3340 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
3341 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
3342 type
== GL_UNSIGNED_INT_8_8_8_8
||
3343 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
3344 type
== GL_UNSIGNED_INT_10_10_10_2
||
3345 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) &&
3346 (format
!= GL_RGBA
&&
3347 format
!= GL_BGRA
)) {
3352 } /* isLegalFormatForPackedPixelType() */
3354 static GLboolean
isLegalLevels(GLint userLevel
,GLint baseLevel
,GLint maxLevel
,
3357 if (baseLevel
< 0 || baseLevel
< userLevel
|| maxLevel
< baseLevel
||
3358 totalLevels
< maxLevel
)
3360 else return GL_TRUE
;
3361 } /* isLegalLevels() */
3363 /* Given user requested texture size, determine if it fits. If it
3364 * doesn't then halve both sides and make the determination again
3365 * until it does fit (for IR only).
3366 * Note that proxy textures are not implemented in RE* even though
3367 * they advertise the texture extension.
3368 * Note that proxy textures are implemented but not according to spec in
3371 static void closestFit(GLenum target
, GLint width
, GLint height
,
3372 GLint internalFormat
, GLenum format
, GLenum type
,
3373 GLint
*newWidth
, GLint
*newHeight
)
3375 /* Use proxy textures if OpenGL version is >= 1.1 */
3376 if ( (strtod((const char *)glGetString(GL_VERSION
),NULL
) >= 1.1)
3378 GLint widthPowerOf2
= nearestPower(width
);
3379 GLint heightPowerOf2
= nearestPower(height
);
3383 /* compute level 1 width & height, clamping each at 1 */
3384 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
3385 widthPowerOf2
>> 1 :
3387 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
3388 heightPowerOf2
>> 1 :
3391 assert(widthAtLevelOne
> 0); assert(heightAtLevelOne
> 0);
3393 /* does width x height at level 1 & all their mipmaps fit? */
3394 if (target
== GL_TEXTURE_2D
|| target
== GL_PROXY_TEXTURE_2D
) {
3395 proxyTarget
= GL_PROXY_TEXTURE_2D
;
3396 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3398 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3400 #if defined(GL_ARB_texture_cube_map)
3401 if ((target
== GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
) ||
3402 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
) ||
3403 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
) ||
3404 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
) ||
3405 (target
== GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
) ||
3406 (target
== GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
)) {
3407 proxyTarget
= GL_PROXY_TEXTURE_CUBE_MAP_ARB
;
3408 glTexImage2D(proxyTarget
, 1, /* must be non-zero */
3410 widthAtLevelOne
,heightAtLevelOne
,0,format
,type
,NULL
);
3412 #endif /* GL_ARB_texture_cube_map */
3414 assert(target
== GL_TEXTURE_1D
|| target
== GL_PROXY_TEXTURE_1D
);
3415 proxyTarget
= GL_PROXY_TEXTURE_1D
;
3416 glTexImage1D(proxyTarget
, 1, /* must be non-zero */
3417 internalFormat
,widthAtLevelOne
,0,format
,type
,NULL
);
3419 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
3420 /* does it fit??? */
3421 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
3422 if (widthPowerOf2
== 1 && heightPowerOf2
== 1) {
3423 /* An 1x1 texture couldn't fit for some reason, so
3424 * break out. This should never happen. But things
3425 * happen. The disadvantage with this if-statement is
3426 * that we will never be aware of when this happens
3427 * since it will silently branch out.
3429 goto noProxyTextures
;
3431 widthPowerOf2
= widthAtLevelOne
;
3432 heightPowerOf2
= heightAtLevelOne
;
3434 /* else it does fit */
3435 } while (proxyWidth
== 0);
3436 /* loop must terminate! */
3438 /* return the width & height at level 0 that fits */
3439 *newWidth
= widthPowerOf2
;
3440 *newHeight
= heightPowerOf2
;
3441 /*printf("Proxy Textures\n");*/
3442 } /* if gluCheckExtension() */
3443 else { /* no texture extension, so do this instead */
3448 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3449 /* clamp user's texture sizes to maximum sizes, if necessary */
3450 *newWidth
= nearestPower(width
);
3451 if (*newWidth
> maxsize
) *newWidth
= maxsize
;
3452 *newHeight
= nearestPower(height
);
3453 if (*newHeight
> maxsize
) *newHeight
= maxsize
;
3454 /*printf("NO proxy textures\n");*/
3456 } /* closestFit() */
3459 gluScaleImage(GLenum format
, GLsizei widthin
, GLsizei heightin
,
3460 GLenum typein
, const void *datain
,
3461 GLsizei widthout
, GLsizei heightout
, GLenum typeout
,
3465 GLushort
*beforeImage
;
3466 GLushort
*afterImage
;
3467 PixelStorageModes psm
;
3469 if (widthin
== 0 || heightin
== 0 || widthout
== 0 || heightout
== 0) {
3472 if (widthin
< 0 || heightin
< 0 || widthout
< 0 || heightout
< 0) {
3473 return GLU_INVALID_VALUE
;
3475 if (!legalFormat(format
) || !legalType(typein
) || !legalType(typeout
)) {
3476 return GLU_INVALID_ENUM
;
3478 if (!isLegalFormatForPackedPixelType(format
, typein
)) {
3479 return GLU_INVALID_OPERATION
;
3481 if (!isLegalFormatForPackedPixelType(format
, typeout
)) {
3482 return GLU_INVALID_OPERATION
;
3485 malloc(image_size(widthin
, heightin
, format
, GL_UNSIGNED_SHORT
));
3487 malloc(image_size(widthout
, heightout
, format
, GL_UNSIGNED_SHORT
));
3488 if (beforeImage
== NULL
|| afterImage
== NULL
) {
3489 return GLU_OUT_OF_MEMORY
;
3492 retrieveStoreModes(&psm
);
3493 fill_image(&psm
,widthin
, heightin
, format
, typein
, is_index(format
),
3494 datain
, beforeImage
);
3495 components
= elements_per_group(format
, 0);
3496 scale_internal(components
, widthin
, heightin
, beforeImage
,
3497 widthout
, heightout
, afterImage
);
3498 empty_image(&psm
,widthout
, heightout
, format
, typeout
,
3499 is_index(format
), afterImage
, dataout
);
3500 free((GLbyte
*) beforeImage
);
3501 free((GLbyte
*) afterImage
);
3506 int gluBuild1DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3508 GLsizei widthPowerOf2
,
3509 GLenum format
, GLenum type
,
3510 GLint userLevel
, GLint baseLevel
,GLint maxLevel
,
3514 GLint level
, levels
;
3516 GLint newImage_width
;
3517 GLushort
*otherImage
;
3518 GLushort
*imageTemp
;
3521 PixelStorageModes psm
;
3523 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3528 newwidth
= widthPowerOf2
;
3529 levels
= computeLog(newwidth
);
3533 retrieveStoreModes(&psm
);
3534 newImage
= (GLushort
*)
3535 malloc(image_size(width
, 1, format
, GL_UNSIGNED_SHORT
));
3536 newImage_width
= width
;
3537 if (newImage
== NULL
) {
3538 return GLU_OUT_OF_MEMORY
;
3540 fill_image(&psm
,width
, 1, format
, type
, is_index(format
),
3542 cmpts
= elements_per_group(format
,type
);
3543 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3544 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3545 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3546 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3548 ** If swap_bytes was set, swapping occurred in fill_image.
3550 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3552 for (level
= userLevel
; level
<= levels
; level
++) {
3553 if (newImage_width
== newwidth
) {
3554 /* Use newImage for this level */
3555 if (baseLevel
<= level
&& level
<= maxLevel
) {
3556 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3557 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3560 if (otherImage
== NULL
) {
3561 memreq
= image_size(newwidth
, 1, format
, GL_UNSIGNED_SHORT
);
3562 otherImage
= (GLushort
*) malloc(memreq
);
3563 if (otherImage
== NULL
) {
3564 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3565 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3566 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3567 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3568 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3569 return GLU_OUT_OF_MEMORY
;
3572 scale_internal(cmpts
, newImage_width
, 1, newImage
,
3573 newwidth
, 1, otherImage
);
3574 /* Swap newImage and otherImage */
3575 imageTemp
= otherImage
;
3576 otherImage
= newImage
;
3577 newImage
= imageTemp
;
3579 newImage_width
= newwidth
;
3580 if (baseLevel
<= level
&& level
<= maxLevel
) {
3581 glTexImage1D(target
, level
, internalFormat
, newImage_width
,
3582 0, format
, GL_UNSIGNED_SHORT
, (void *) newImage
);
3585 if (newwidth
> 1) newwidth
/= 2;
3587 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3588 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3589 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3590 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3591 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3593 free((GLbyte
*) newImage
);
3595 free((GLbyte
*) otherImage
);
3601 gluBuild1DMipmapLevels(GLenum target
, GLint internalFormat
,
3603 GLenum format
, GLenum type
,
3604 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
3609 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3610 if (rc
!= 0) return rc
;
3613 return GLU_INVALID_VALUE
;
3616 levels
= computeLog(width
);
3619 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
3620 return GLU_INVALID_VALUE
;
3622 return gluBuild1DMipmapLevelsCore(target
, internalFormat
,
3625 userLevel
, baseLevel
, maxLevel
,
3627 } /* gluBuild1DMipmapLevels() */
3630 gluBuild1DMipmaps(GLenum target
, GLint internalFormat
, GLsizei width
,
3631 GLenum format
, GLenum type
,
3634 GLint widthPowerOf2
;
3638 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
3639 if (rc
!= 0) return rc
;
3642 return GLU_INVALID_VALUE
;
3645 closestFit(target
,width
,1,internalFormat
,format
,type
,&widthPowerOf2
,&dummy
);
3646 levels
= computeLog(widthPowerOf2
);
3648 return gluBuild1DMipmapLevelsCore(target
,internalFormat
,
3651 format
,type
,0,0,levels
,data
);
3654 static int bitmapBuild2DMipmaps(GLenum target
, GLint internalFormat
,
3655 GLint width
, GLint height
, GLenum format
,
3656 GLenum type
, const void *data
)
3658 GLint newwidth
, newheight
;
3659 GLint level
, levels
;
3661 GLint newImage_width
;
3662 GLint newImage_height
;
3663 GLushort
*otherImage
;
3664 GLushort
*imageTemp
;
3667 PixelStorageModes psm
;
3669 retrieveStoreModes(&psm
);
3672 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
3673 newwidth
= nearestPower(width
);
3674 if (newwidth
> maxsize
) newwidth
= maxsize
;
3675 newheight
= nearestPower(height
);
3676 if (newheight
> maxsize
) newheight
= maxsize
;
3678 closestFit(target
,width
,height
,internalFormat
,format
,type
,
3679 &newwidth
,&newheight
);
3681 levels
= computeLog(newwidth
);
3682 level
= computeLog(newheight
);
3683 if (level
> levels
) levels
=level
;
3686 newImage
= (GLushort
*)
3687 malloc(image_size(width
, height
, format
, GL_UNSIGNED_SHORT
));
3688 newImage_width
= width
;
3689 newImage_height
= height
;
3690 if (newImage
== NULL
) {
3691 return GLU_OUT_OF_MEMORY
;
3694 fill_image(&psm
,width
, height
, format
, type
, is_index(format
),
3697 cmpts
= elements_per_group(format
,type
);
3698 glPixelStorei(GL_UNPACK_ALIGNMENT
, 2);
3699 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3700 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3701 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3703 ** If swap_bytes was set, swapping occurred in fill_image.
3705 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
3707 for (level
= 0; level
<= levels
; level
++) {
3708 if (newImage_width
== newwidth
&& newImage_height
== newheight
) { /* Use newImage for this level */
3709 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3710 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3713 if (otherImage
== NULL
) {
3715 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_SHORT
);
3716 otherImage
= (GLushort
*) malloc(memreq
);
3717 if (otherImage
== NULL
) {
3718 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3719 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3720 glPixelStorei(GL_UNPACK_SKIP_PIXELS
,psm
.unpack_skip_pixels
);
3721 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3722 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3723 return GLU_OUT_OF_MEMORY
;
3726 scale_internal(cmpts
, newImage_width
, newImage_height
, newImage
,
3727 newwidth
, newheight
, otherImage
);
3728 /* Swap newImage and otherImage */
3729 imageTemp
= otherImage
;
3730 otherImage
= newImage
;
3731 newImage
= imageTemp
;
3733 newImage_width
= newwidth
;
3734 newImage_height
= newheight
;
3735 glTexImage2D(target
, level
, internalFormat
, newImage_width
,
3736 newImage_height
, 0, format
, GL_UNSIGNED_SHORT
,
3739 if (newwidth
> 1) newwidth
/= 2;
3740 if (newheight
> 1) newheight
/= 2;
3742 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3743 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3744 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3745 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3746 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3748 free((GLbyte
*) newImage
);
3750 free((GLbyte
*) otherImage
);
3755 /* To make swapping images less error prone */
3756 #define __GLU_INIT_SWAP_IMAGE void *tmpImage
3757 #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
3759 static int gluBuild2DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
3760 GLsizei width
, GLsizei height
,
3761 GLsizei widthPowerOf2
,
3762 GLsizei heightPowerOf2
,
3763 GLenum format
, GLenum type
,
3765 GLint baseLevel
,GLint maxLevel
,
3768 GLint newwidth
, newheight
;
3769 GLint level
, levels
;
3770 const void *usersImage
; /* passed from user. Don't touch! */
3771 void *srcImage
, *dstImage
; /* scratch area to build mipmapped images */
3772 __GLU_INIT_SWAP_IMAGE
;
3776 GLint myswap_bytes
, groups_per_line
, element_size
, group_size
;
3777 GLint rowsize
, padding
;
3778 PixelStorageModes psm
;
3780 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
3781 assert(width
>= 1 && height
>= 1);
3783 if(type
== GL_BITMAP
) {
3784 return bitmapBuild2DMipmaps(target
, internalFormat
, width
, height
,
3785 format
, type
, data
);
3788 srcImage
= dstImage
= NULL
;
3790 newwidth
= widthPowerOf2
;
3791 newheight
= heightPowerOf2
;
3792 levels
= computeLog(newwidth
);
3793 level
= computeLog(newheight
);
3794 if (level
> levels
) levels
=level
;
3798 retrieveStoreModes(&psm
);
3799 myswap_bytes
= psm
.unpack_swap_bytes
;
3800 cmpts
= elements_per_group(format
,type
);
3801 if (psm
.unpack_row_length
> 0) {
3802 groups_per_line
= psm
.unpack_row_length
;
3804 groups_per_line
= width
;
3807 element_size
= bytes_per_element(type
);
3808 group_size
= element_size
* cmpts
;
3809 if (element_size
== 1) myswap_bytes
= 0;
3811 rowsize
= groups_per_line
* group_size
;
3812 padding
= (rowsize
% psm
.unpack_alignment
);
3814 rowsize
+= psm
.unpack_alignment
- padding
;
3816 usersImage
= (const GLubyte
*) data
+ psm
.unpack_skip_rows
* rowsize
+
3817 psm
.unpack_skip_pixels
* group_size
;
3819 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
3820 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
3821 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
3825 /* already power-of-two square */
3826 if (width
== newwidth
&& height
== newheight
) {
3827 /* Use usersImage for level userLevel */
3828 if (baseLevel
<= level
&& level
<= maxLevel
) {
3829 glTexImage2D(target
, level
, internalFormat
, width
,
3830 height
, 0, format
, type
,
3833 if(levels
== 0) { /* we're done. clean up and return */
3834 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3835 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3836 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3837 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3838 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3842 int nextWidth
= newwidth
/2;
3843 int nextHeight
= newheight
/2;
3846 if (nextWidth
< 1) nextWidth
= 1;
3847 if (nextHeight
< 1) nextHeight
= 1;
3848 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
3852 case GL_UNSIGNED_BYTE
:
3853 dstImage
= (GLubyte
*)malloc(memreq
);
3856 dstImage
= (GLbyte
*)malloc(memreq
);
3858 case GL_UNSIGNED_SHORT
:
3859 dstImage
= (GLushort
*)malloc(memreq
);
3862 dstImage
= (GLshort
*)malloc(memreq
);
3864 case GL_UNSIGNED_INT
:
3865 dstImage
= (GLuint
*)malloc(memreq
);
3868 dstImage
= (GLint
*)malloc(memreq
);
3871 dstImage
= (GLfloat
*)malloc(memreq
);
3873 case GL_UNSIGNED_BYTE_3_3_2
:
3874 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3875 dstImage
= (GLubyte
*)malloc(memreq
);
3877 case GL_UNSIGNED_SHORT_5_6_5
:
3878 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3879 case GL_UNSIGNED_SHORT_4_4_4_4
:
3880 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3881 case GL_UNSIGNED_SHORT_5_5_5_1
:
3882 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3883 dstImage
= (GLushort
*)malloc(memreq
);
3885 case GL_UNSIGNED_INT_8_8_8_8
:
3886 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3887 case GL_UNSIGNED_INT_10_10_10_2
:
3888 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3889 dstImage
= (GLuint
*)malloc(memreq
);
3892 return GLU_INVALID_ENUM
;
3894 if (dstImage
== NULL
) {
3895 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
3896 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
3897 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
3898 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
3899 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
3900 return GLU_OUT_OF_MEMORY
;
3904 case GL_UNSIGNED_BYTE
:
3905 halveImage_ubyte(cmpts
, width
, height
,
3906 (const GLubyte
*)usersImage
, (GLubyte
*)dstImage
,
3907 element_size
, rowsize
, group_size
);
3910 halveImage_byte(cmpts
, width
, height
,
3911 (const GLbyte
*)usersImage
, (GLbyte
*)dstImage
,
3912 element_size
, rowsize
, group_size
);
3914 case GL_UNSIGNED_SHORT
:
3915 halveImage_ushort(cmpts
, width
, height
,
3916 (const GLushort
*)usersImage
, (GLushort
*)dstImage
,
3917 element_size
, rowsize
, group_size
, myswap_bytes
);
3920 halveImage_short(cmpts
, width
, height
,
3921 (const GLshort
*)usersImage
, (GLshort
*)dstImage
,
3922 element_size
, rowsize
, group_size
, myswap_bytes
);
3924 case GL_UNSIGNED_INT
:
3925 halveImage_uint(cmpts
, width
, height
,
3926 (const GLuint
*)usersImage
, (GLuint
*)dstImage
,
3927 element_size
, rowsize
, group_size
, myswap_bytes
);
3930 halveImage_int(cmpts
, width
, height
,
3931 (const GLint
*)usersImage
, (GLint
*)dstImage
,
3932 element_size
, rowsize
, group_size
, myswap_bytes
);
3935 halveImage_float(cmpts
, width
, height
,
3936 (const GLfloat
*)usersImage
, (GLfloat
*)dstImage
,
3937 element_size
, rowsize
, group_size
, myswap_bytes
);
3939 case GL_UNSIGNED_BYTE_3_3_2
:
3940 assert(format
== GL_RGB
);
3941 halveImagePackedPixel(3,extract332
,shove332
,
3942 width
,height
,usersImage
,dstImage
,
3943 element_size
,rowsize
,myswap_bytes
);
3945 case GL_UNSIGNED_BYTE_2_3_3_REV
:
3946 assert(format
== GL_RGB
);
3947 halveImagePackedPixel(3,extract233rev
,shove233rev
,
3948 width
,height
,usersImage
,dstImage
,
3949 element_size
,rowsize
,myswap_bytes
);
3951 case GL_UNSIGNED_SHORT_5_6_5
:
3952 halveImagePackedPixel(3,extract565
,shove565
,
3953 width
,height
,usersImage
,dstImage
,
3954 element_size
,rowsize
,myswap_bytes
);
3956 case GL_UNSIGNED_SHORT_5_6_5_REV
:
3957 halveImagePackedPixel(3,extract565rev
,shove565rev
,
3958 width
,height
,usersImage
,dstImage
,
3959 element_size
,rowsize
,myswap_bytes
);
3961 case GL_UNSIGNED_SHORT_4_4_4_4
:
3962 halveImagePackedPixel(4,extract4444
,shove4444
,
3963 width
,height
,usersImage
,dstImage
,
3964 element_size
,rowsize
,myswap_bytes
);
3966 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
3967 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
3968 width
,height
,usersImage
,dstImage
,
3969 element_size
,rowsize
,myswap_bytes
);
3971 case GL_UNSIGNED_SHORT_5_5_5_1
:
3972 halveImagePackedPixel(4,extract5551
,shove5551
,
3973 width
,height
,usersImage
,dstImage
,
3974 element_size
,rowsize
,myswap_bytes
);
3976 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
3977 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
3978 width
,height
,usersImage
,dstImage
,
3979 element_size
,rowsize
,myswap_bytes
);
3981 case GL_UNSIGNED_INT_8_8_8_8
:
3982 halveImagePackedPixel(4,extract8888
,shove8888
,
3983 width
,height
,usersImage
,dstImage
,
3984 element_size
,rowsize
,myswap_bytes
);
3986 case GL_UNSIGNED_INT_8_8_8_8_REV
:
3987 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
3988 width
,height
,usersImage
,dstImage
,
3989 element_size
,rowsize
,myswap_bytes
);
3991 case GL_UNSIGNED_INT_10_10_10_2
:
3992 halveImagePackedPixel(4,extract1010102
,shove1010102
,
3993 width
,height
,usersImage
,dstImage
,
3994 element_size
,rowsize
,myswap_bytes
);
3996 case GL_UNSIGNED_INT_2_10_10_10_REV
:
3997 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
3998 width
,height
,usersImage
,dstImage
,
3999 element_size
,rowsize
,myswap_bytes
);
4006 newheight
= height
/2;
4008 if (newwidth
< 1) newwidth
= 1;
4009 if (newheight
< 1) newheight
= 1;
4012 rowsize
= newwidth
* group_size
;
4013 memreq
= image_size(newwidth
, newheight
, format
, type
);
4014 /* Swap srcImage and dstImage */
4015 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4017 case GL_UNSIGNED_BYTE
:
4018 dstImage
= (GLubyte
*)malloc(memreq
);
4021 dstImage
= (GLbyte
*)malloc(memreq
);
4023 case GL_UNSIGNED_SHORT
:
4024 dstImage
= (GLushort
*)malloc(memreq
);
4027 dstImage
= (GLshort
*)malloc(memreq
);
4029 case GL_UNSIGNED_INT
:
4030 dstImage
= (GLuint
*)malloc(memreq
);
4033 dstImage
= (GLint
*)malloc(memreq
);
4036 dstImage
= (GLfloat
*)malloc(memreq
);
4038 case GL_UNSIGNED_BYTE_3_3_2
:
4039 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4040 dstImage
= (GLubyte
*)malloc(memreq
);
4042 case GL_UNSIGNED_SHORT_5_6_5
:
4043 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4044 case GL_UNSIGNED_SHORT_4_4_4_4
:
4045 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4046 case GL_UNSIGNED_SHORT_5_5_5_1
:
4047 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4048 dstImage
= (GLushort
*)malloc(memreq
);
4050 case GL_UNSIGNED_INT_8_8_8_8
:
4051 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4052 case GL_UNSIGNED_INT_10_10_10_2
:
4053 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4054 dstImage
= (GLuint
*)malloc(memreq
);
4057 return GLU_INVALID_ENUM
;
4059 if (dstImage
== NULL
) {
4060 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4061 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4062 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4063 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4064 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4065 return GLU_OUT_OF_MEMORY
;
4067 /* level userLevel+1 is in srcImage; level userLevel already saved */
4068 level
= userLevel
+1;
4069 } else { /* user's image is *not* nice power-of-2 sized square */
4070 memreq
= image_size(newwidth
, newheight
, format
, type
);
4072 case GL_UNSIGNED_BYTE
:
4073 dstImage
= (GLubyte
*)malloc(memreq
);
4076 dstImage
= (GLbyte
*)malloc(memreq
);
4078 case GL_UNSIGNED_SHORT
:
4079 dstImage
= (GLushort
*)malloc(memreq
);
4082 dstImage
= (GLshort
*)malloc(memreq
);
4084 case GL_UNSIGNED_INT
:
4085 dstImage
= (GLuint
*)malloc(memreq
);
4088 dstImage
= (GLint
*)malloc(memreq
);
4091 dstImage
= (GLfloat
*)malloc(memreq
);
4093 case GL_UNSIGNED_BYTE_3_3_2
:
4094 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4095 dstImage
= (GLubyte
*)malloc(memreq
);
4097 case GL_UNSIGNED_SHORT_5_6_5
:
4098 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4099 case GL_UNSIGNED_SHORT_4_4_4_4
:
4100 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4101 case GL_UNSIGNED_SHORT_5_5_5_1
:
4102 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4103 dstImage
= (GLushort
*)malloc(memreq
);
4105 case GL_UNSIGNED_INT_8_8_8_8
:
4106 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4107 case GL_UNSIGNED_INT_10_10_10_2
:
4108 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4109 dstImage
= (GLuint
*)malloc(memreq
);
4112 return GLU_INVALID_ENUM
;
4115 if (dstImage
== NULL
) {
4116 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4117 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4118 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4119 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4120 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4121 return GLU_OUT_OF_MEMORY
;
4125 case GL_UNSIGNED_BYTE
:
4126 scale_internal_ubyte(cmpts
, width
, height
,
4127 (const GLubyte
*)usersImage
, newwidth
, newheight
,
4128 (GLubyte
*)dstImage
, element_size
,
4129 rowsize
, group_size
);
4132 scale_internal_byte(cmpts
, width
, height
,
4133 (const GLbyte
*)usersImage
, newwidth
, newheight
,
4134 (GLbyte
*)dstImage
, element_size
,
4135 rowsize
, group_size
);
4137 case GL_UNSIGNED_SHORT
:
4138 scale_internal_ushort(cmpts
, width
, height
,
4139 (const GLushort
*)usersImage
, newwidth
, newheight
,
4140 (GLushort
*)dstImage
, element_size
,
4141 rowsize
, group_size
, myswap_bytes
);
4144 scale_internal_short(cmpts
, width
, height
,
4145 (const GLshort
*)usersImage
, newwidth
, newheight
,
4146 (GLshort
*)dstImage
, element_size
,
4147 rowsize
, group_size
, myswap_bytes
);
4149 case GL_UNSIGNED_INT
:
4150 scale_internal_uint(cmpts
, width
, height
,
4151 (const GLuint
*)usersImage
, newwidth
, newheight
,
4152 (GLuint
*)dstImage
, element_size
,
4153 rowsize
, group_size
, myswap_bytes
);
4156 scale_internal_int(cmpts
, width
, height
,
4157 (const GLint
*)usersImage
, newwidth
, newheight
,
4158 (GLint
*)dstImage
, element_size
,
4159 rowsize
, group_size
, myswap_bytes
);
4162 scale_internal_float(cmpts
, width
, height
,
4163 (const GLfloat
*)usersImage
, newwidth
, newheight
,
4164 (GLfloat
*)dstImage
, element_size
,
4165 rowsize
, group_size
, myswap_bytes
);
4167 case GL_UNSIGNED_BYTE_3_3_2
:
4168 scaleInternalPackedPixel(3,extract332
,shove332
,
4169 width
, height
,usersImage
,
4170 newwidth
,newheight
,(void *)dstImage
,
4171 element_size
,rowsize
,myswap_bytes
);
4173 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4174 scaleInternalPackedPixel(3,extract233rev
,shove233rev
,
4175 width
, height
,usersImage
,
4176 newwidth
,newheight
,(void *)dstImage
,
4177 element_size
,rowsize
,myswap_bytes
);
4179 case GL_UNSIGNED_SHORT_5_6_5
:
4180 scaleInternalPackedPixel(3,extract565
,shove565
,
4181 width
, height
,usersImage
,
4182 newwidth
,newheight
,(void *)dstImage
,
4183 element_size
,rowsize
,myswap_bytes
);
4185 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4186 scaleInternalPackedPixel(3,extract565rev
,shove565rev
,
4187 width
, height
,usersImage
,
4188 newwidth
,newheight
,(void *)dstImage
,
4189 element_size
,rowsize
,myswap_bytes
);
4191 case GL_UNSIGNED_SHORT_4_4_4_4
:
4192 scaleInternalPackedPixel(4,extract4444
,shove4444
,
4193 width
, height
,usersImage
,
4194 newwidth
,newheight
,(void *)dstImage
,
4195 element_size
,rowsize
,myswap_bytes
);
4197 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4198 scaleInternalPackedPixel(4,extract4444rev
,shove4444rev
,
4199 width
, height
,usersImage
,
4200 newwidth
,newheight
,(void *)dstImage
,
4201 element_size
,rowsize
,myswap_bytes
);
4203 case GL_UNSIGNED_SHORT_5_5_5_1
:
4204 scaleInternalPackedPixel(4,extract5551
,shove5551
,
4205 width
, height
,usersImage
,
4206 newwidth
,newheight
,(void *)dstImage
,
4207 element_size
,rowsize
,myswap_bytes
);
4209 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4210 scaleInternalPackedPixel(4,extract1555rev
,shove1555rev
,
4211 width
, height
,usersImage
,
4212 newwidth
,newheight
,(void *)dstImage
,
4213 element_size
,rowsize
,myswap_bytes
);
4215 case GL_UNSIGNED_INT_8_8_8_8
:
4216 scaleInternalPackedPixel(4,extract8888
,shove8888
,
4217 width
, height
,usersImage
,
4218 newwidth
,newheight
,(void *)dstImage
,
4219 element_size
,rowsize
,myswap_bytes
);
4221 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4222 scaleInternalPackedPixel(4,extract8888rev
,shove8888rev
,
4223 width
, height
,usersImage
,
4224 newwidth
,newheight
,(void *)dstImage
,
4225 element_size
,rowsize
,myswap_bytes
);
4227 case GL_UNSIGNED_INT_10_10_10_2
:
4228 scaleInternalPackedPixel(4,extract1010102
,shove1010102
,
4229 width
, height
,usersImage
,
4230 newwidth
,newheight
,(void *)dstImage
,
4231 element_size
,rowsize
,myswap_bytes
);
4233 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4234 scaleInternalPackedPixel(4,extract2101010rev
,shove2101010rev
,
4235 width
, height
,usersImage
,
4236 newwidth
,newheight
,(void *)dstImage
,
4237 element_size
,rowsize
,myswap_bytes
);
4244 rowsize
= newwidth
* group_size
;
4245 /* Swap dstImage and srcImage */
4246 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4248 if(levels
!= 0) { /* use as little memory as possible */
4250 int nextWidth
= newwidth
/2;
4251 int nextHeight
= newheight
/2;
4252 if (nextWidth
< 1) nextWidth
= 1;
4253 if (nextHeight
< 1) nextHeight
= 1;
4255 memreq
= image_size(nextWidth
, nextHeight
, format
, type
);
4259 case GL_UNSIGNED_BYTE
:
4260 dstImage
= (GLubyte
*)malloc(memreq
);
4263 dstImage
= (GLbyte
*)malloc(memreq
);
4265 case GL_UNSIGNED_SHORT
:
4266 dstImage
= (GLushort
*)malloc(memreq
);
4269 dstImage
= (GLshort
*)malloc(memreq
);
4271 case GL_UNSIGNED_INT
:
4272 dstImage
= (GLuint
*)malloc(memreq
);
4275 dstImage
= (GLint
*)malloc(memreq
);
4278 dstImage
= (GLfloat
*)malloc(memreq
);
4280 case GL_UNSIGNED_BYTE_3_3_2
:
4281 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4282 dstImage
= (GLubyte
*)malloc(memreq
);
4284 case GL_UNSIGNED_SHORT_5_6_5
:
4285 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4286 case GL_UNSIGNED_SHORT_4_4_4_4
:
4287 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4288 case GL_UNSIGNED_SHORT_5_5_5_1
:
4289 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4290 dstImage
= (GLushort
*)malloc(memreq
);
4292 case GL_UNSIGNED_INT_8_8_8_8
:
4293 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4294 case GL_UNSIGNED_INT_10_10_10_2
:
4295 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4296 dstImage
= (GLuint
*)malloc(memreq
);
4299 return GLU_INVALID_ENUM
;
4301 if (dstImage
== NULL
) {
4302 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4303 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4304 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4305 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4306 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4307 return GLU_OUT_OF_MEMORY
;
4310 /* level userLevel is in srcImage; nothing saved yet */
4314 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4315 if (baseLevel
<= level
&& level
<= maxLevel
) {
4316 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4317 format
, type
, (void *)srcImage
);
4320 level
++; /* update current level for the loop */
4321 for (; level
<= levels
; level
++) {
4323 case GL_UNSIGNED_BYTE
:
4324 halveImage_ubyte(cmpts
, newwidth
, newheight
,
4325 (GLubyte
*)srcImage
, (GLubyte
*)dstImage
, element_size
,
4326 rowsize
, group_size
);
4329 halveImage_byte(cmpts
, newwidth
, newheight
,
4330 (GLbyte
*)srcImage
, (GLbyte
*)dstImage
, element_size
,
4331 rowsize
, group_size
);
4333 case GL_UNSIGNED_SHORT
:
4334 halveImage_ushort(cmpts
, newwidth
, newheight
,
4335 (GLushort
*)srcImage
, (GLushort
*)dstImage
, element_size
,
4336 rowsize
, group_size
, myswap_bytes
);
4339 halveImage_short(cmpts
, newwidth
, newheight
,
4340 (GLshort
*)srcImage
, (GLshort
*)dstImage
, element_size
,
4341 rowsize
, group_size
, myswap_bytes
);
4343 case GL_UNSIGNED_INT
:
4344 halveImage_uint(cmpts
, newwidth
, newheight
,
4345 (GLuint
*)srcImage
, (GLuint
*)dstImage
, element_size
,
4346 rowsize
, group_size
, myswap_bytes
);
4349 halveImage_int(cmpts
, newwidth
, newheight
,
4350 (GLint
*)srcImage
, (GLint
*)dstImage
, element_size
,
4351 rowsize
, group_size
, myswap_bytes
);
4354 halveImage_float(cmpts
, newwidth
, newheight
,
4355 (GLfloat
*)srcImage
, (GLfloat
*)dstImage
, element_size
,
4356 rowsize
, group_size
, myswap_bytes
);
4358 case GL_UNSIGNED_BYTE_3_3_2
:
4359 halveImagePackedPixel(3,extract332
,shove332
,
4361 srcImage
,dstImage
,element_size
,rowsize
,
4364 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4365 halveImagePackedPixel(3,extract233rev
,shove233rev
,
4367 srcImage
,dstImage
,element_size
,rowsize
,
4370 case GL_UNSIGNED_SHORT_5_6_5
:
4371 halveImagePackedPixel(3,extract565
,shove565
,
4373 srcImage
,dstImage
,element_size
,rowsize
,
4376 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4377 halveImagePackedPixel(3,extract565rev
,shove565rev
,
4379 srcImage
,dstImage
,element_size
,rowsize
,
4382 case GL_UNSIGNED_SHORT_4_4_4_4
:
4383 halveImagePackedPixel(4,extract4444
,shove4444
,
4385 srcImage
,dstImage
,element_size
,rowsize
,
4388 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4389 halveImagePackedPixel(4,extract4444rev
,shove4444rev
,
4391 srcImage
,dstImage
,element_size
,rowsize
,
4394 case GL_UNSIGNED_SHORT_5_5_5_1
:
4395 halveImagePackedPixel(4,extract5551
,shove5551
,
4397 srcImage
,dstImage
,element_size
,rowsize
,
4400 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4401 halveImagePackedPixel(4,extract1555rev
,shove1555rev
,
4403 srcImage
,dstImage
,element_size
,rowsize
,
4406 case GL_UNSIGNED_INT_8_8_8_8
:
4407 halveImagePackedPixel(4,extract8888
,shove8888
,
4409 srcImage
,dstImage
,element_size
,rowsize
,
4412 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4413 halveImagePackedPixel(4,extract8888rev
,shove8888rev
,
4415 srcImage
,dstImage
,element_size
,rowsize
,
4418 case GL_UNSIGNED_INT_10_10_10_2
:
4419 halveImagePackedPixel(4,extract1010102
,shove1010102
,
4421 srcImage
,dstImage
,element_size
,rowsize
,
4424 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4425 halveImagePackedPixel(4,extract2101010rev
,shove2101010rev
,
4427 srcImage
,dstImage
,element_size
,rowsize
,
4435 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
4437 if (newwidth
> 1) { newwidth
/= 2; rowsize
/= 2;}
4438 if (newheight
> 1) newheight
/= 2;
4440 /* compute amount to pad per row, if any */
4441 int rowPad
= rowsize
% psm
.unpack_alignment
;
4443 /* should row be padded? */
4444 if (rowPad
== 0) { /* nope, row should not be padded */
4445 /* call tex image with srcImage untouched since it's not padded */
4446 if (baseLevel
<= level
&& level
<= maxLevel
) {
4447 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4448 format
, type
, (void *) srcImage
);
4451 else { /* yes, row should be padded */
4452 /* compute length of new row in bytes, including padding */
4453 int newRowLength
= rowsize
+ psm
.unpack_alignment
- rowPad
;
4454 int ii
; unsigned char *dstTrav
, *srcTrav
; /* indices for copying */
4456 /* allocate new image for mipmap of size newRowLength x newheight */
4457 void *newMipmapImage
= malloc((size_t) (newRowLength
*newheight
));
4458 if (newMipmapImage
== NULL
) {
4459 /* out of memory so return */
4460 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4461 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4462 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4463 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4464 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4465 return GLU_OUT_OF_MEMORY
;
4468 /* copy image from srcImage into newMipmapImage by rows */
4470 dstTrav
= (unsigned char *) newMipmapImage
,
4471 srcTrav
= (unsigned char *) srcImage
;
4474 dstTrav
+= newRowLength
, /* make sure the correct distance... */
4475 srcTrav
+= rowsize
) { /* ...is skipped */
4476 memcpy(dstTrav
,srcTrav
,rowsize
);
4477 /* note that the pad bytes are not visited and will contain
4478 * garbage, which is ok.
4482 /* ...and use this new image for mipmapping instead */
4483 if (baseLevel
<= level
&& level
<= maxLevel
) {
4484 glTexImage2D(target
, level
, internalFormat
, newwidth
, newheight
, 0,
4485 format
, type
, newMipmapImage
);
4487 free(newMipmapImage
); /* don't forget to free it! */
4491 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
4492 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
4493 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
4494 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
4495 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
4497 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
4498 if (dstImage
) { /* if it's non-rectangular and only 1 level */
4502 } /* gluBuild2DMipmapLevelsCore() */
4505 gluBuild2DMipmapLevels(GLenum target
, GLint internalFormat
,
4506 GLsizei width
, GLsizei height
,
4507 GLenum format
, GLenum type
,
4508 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
4513 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4514 if (rc
!= 0) return rc
;
4516 if (width
< 1 || height
< 1) {
4517 return GLU_INVALID_VALUE
;
4520 levels
= computeLog(width
);
4521 level
= computeLog(height
);
4522 if (level
> levels
) levels
=level
;
4525 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
4526 return GLU_INVALID_VALUE
;
4528 return gluBuild2DMipmapLevelsCore(target
, internalFormat
,
4532 userLevel
, baseLevel
, maxLevel
,
4534 } /* gluBuild2DMipmapLevels() */
4537 gluBuild2DMipmaps(GLenum target
, GLint internalFormat
,
4538 GLsizei width
, GLsizei height
,
4539 GLenum format
, GLenum type
,
4542 GLint widthPowerOf2
, heightPowerOf2
;
4545 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
4546 if (rc
!= 0) return rc
;
4548 if (width
< 1 || height
< 1) {
4549 return GLU_INVALID_VALUE
;
4552 closestFit(target
,width
,height
,internalFormat
,format
,type
,
4553 &widthPowerOf2
,&heightPowerOf2
);
4555 levels
= computeLog(widthPowerOf2
);
4556 level
= computeLog(heightPowerOf2
);
4557 if (level
> levels
) levels
=level
;
4559 return gluBuild2DMipmapLevelsCore(target
,internalFormat
,
4561 widthPowerOf2
,heightPowerOf2
,
4564 } /* gluBuild2DMipmaps() */
4567 ** This routine is for the limited case in which
4568 ** type == GL_UNSIGNED_BYTE && format != index &&
4569 ** unpack_alignment = 1 && unpack_swap_bytes == false
4571 ** so all of the work data can be kept as ubytes instead of shorts.
4573 static int fastBuild2DMipmaps(const PixelStorageModes
*psm
,
4574 GLenum target
, GLint components
, GLint width
,
4575 GLint height
, GLenum format
,
4576 GLenum type
, void *data
)
4578 GLint newwidth
, newheight
;
4579 GLint level
, levels
;
4581 GLint newImage_width
;
4582 GLint newImage_height
;
4583 GLubyte
*otherImage
;
4590 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxsize
);
4591 newwidth
= nearestPower(width
);
4592 if (newwidth
> maxsize
) newwidth
= maxsize
;
4593 newheight
= nearestPower(height
);
4594 if (newheight
> maxsize
) newheight
= maxsize
;
4596 closestFit(target
,width
,height
,components
,format
,type
,
4597 &newwidth
,&newheight
);
4599 levels
= computeLog(newwidth
);
4600 level
= computeLog(newheight
);
4601 if (level
> levels
) levels
=level
;
4603 cmpts
= elements_per_group(format
,type
);
4607 ** No need to copy the user data if its in the packed correctly.
4608 ** Make sure that later routines don't change that data.
4610 if (psm
->unpack_skip_rows
== 0 && psm
->unpack_skip_pixels
== 0) {
4611 newImage
= (GLubyte
*)data
;
4612 newImage_width
= width
;
4613 newImage_height
= height
;
4616 GLint groups_per_line
;
4617 GLint elements_per_line
;
4618 const GLubyte
*start
;
4619 const GLubyte
*iter
;
4623 newImage
= (GLubyte
*)
4624 malloc(image_size(width
, height
, format
, GL_UNSIGNED_BYTE
));
4625 newImage_width
= width
;
4626 newImage_height
= height
;
4627 if (newImage
== NULL
) {
4628 return GLU_OUT_OF_MEMORY
;
4632 ** Abbreviated version of fill_image for this restricted case.
4634 if (psm
->unpack_row_length
> 0) {
4635 groups_per_line
= psm
->unpack_row_length
;
4637 groups_per_line
= width
;
4639 rowsize
= groups_per_line
* cmpts
;
4640 elements_per_line
= width
* cmpts
;
4641 start
= (const GLubyte
*) data
+ psm
->unpack_skip_rows
* rowsize
+
4642 psm
->unpack_skip_pixels
* cmpts
;
4645 for (i
= 0; i
< height
; i
++) {
4647 for (j
= 0; j
< elements_per_line
; j
++) {
4657 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
4658 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
4659 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
4660 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
4661 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
4663 for (level
= 0; level
<= levels
; level
++) {
4664 if (newImage_width
== newwidth
&& newImage_height
== newheight
) {
4665 /* Use newImage for this level */
4666 glTexImage2D(target
, level
, components
, newImage_width
,
4667 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4670 if (otherImage
== NULL
) {
4672 image_size(newwidth
, newheight
, format
, GL_UNSIGNED_BYTE
);
4673 otherImage
= (GLubyte
*) malloc(memreq
);
4674 if (otherImage
== NULL
) {
4675 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4676 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4677 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4678 glPixelStorei(GL_UNPACK_ROW_LENGTH
,psm
->unpack_row_length
);
4679 glPixelStorei(GL_UNPACK_SWAP_BYTES
,psm
->unpack_swap_bytes
);
4680 return GLU_OUT_OF_MEMORY
;
4684 scale_internal_ubyte(cmpts, newImage_width, newImage_height,
4685 newImage, newwidth, newheight, otherImage);
4687 /* Swap newImage and otherImage */
4688 imageTemp
= otherImage
;
4689 otherImage
= newImage
;
4690 newImage
= imageTemp
;
4692 newImage_width
= newwidth
;
4693 newImage_height
= newheight
;
4694 glTexImage2D(target
, level
, components
, newImage_width
,
4695 newImage_height
, 0, format
, GL_UNSIGNED_BYTE
,
4698 if (newwidth
> 1) newwidth
/= 2;
4699 if (newheight
> 1) newheight
/= 2;
4701 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
->unpack_alignment
);
4702 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
->unpack_skip_rows
);
4703 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
->unpack_skip_pixels
);
4704 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
->unpack_row_length
);
4705 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
->unpack_swap_bytes
);
4707 if (newImage
!= (const GLubyte
*)data
) {
4708 free((GLbyte
*) newImage
);
4710 if (otherImage
&& otherImage
!= (const GLubyte
*)data
) {
4711 free((GLbyte
*) otherImage
);
4719 static GLint
elements_per_group(GLenum format
, GLenum type
)
4722 * Return the number of elements per group of a specified format
4725 /* If the type is packedpixels then answer is 1 (ignore format) */
4726 if (type
== GL_UNSIGNED_BYTE_3_3_2
||
4727 type
== GL_UNSIGNED_BYTE_2_3_3_REV
||
4728 type
== GL_UNSIGNED_SHORT_5_6_5
||
4729 type
== GL_UNSIGNED_SHORT_5_6_5_REV
||
4730 type
== GL_UNSIGNED_SHORT_4_4_4_4
||
4731 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
4732 type
== GL_UNSIGNED_SHORT_5_5_5_1
||
4733 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
||
4734 type
== GL_UNSIGNED_INT_8_8_8_8
||
4735 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
4736 type
== GL_UNSIGNED_INT_10_10_10_2
||
4737 type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
4741 /* Types are not packed pixels, so get elements per group */
4746 case GL_LUMINANCE_ALPHA
:
4756 static GLfloat
bytes_per_element(GLenum type
)
4759 * Return the number of bytes per element, based on the element type
4764 case GL_UNSIGNED_SHORT
:
4765 return(sizeof(GLushort
));
4767 return(sizeof(GLshort
));
4768 case GL_UNSIGNED_BYTE
:
4769 return(sizeof(GLubyte
));
4771 return(sizeof(GLbyte
));
4773 return(sizeof(GLint
));
4774 case GL_UNSIGNED_INT
:
4775 return(sizeof(GLuint
));
4777 return(sizeof(GLfloat
));
4778 case GL_UNSIGNED_BYTE_3_3_2
:
4779 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4780 return(sizeof(GLubyte
));
4781 case GL_UNSIGNED_SHORT_5_6_5
:
4782 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4783 case GL_UNSIGNED_SHORT_4_4_4_4
:
4784 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4785 case GL_UNSIGNED_SHORT_5_5_5_1
:
4786 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4787 return(sizeof(GLushort
));
4788 case GL_UNSIGNED_INT_8_8_8_8
:
4789 case GL_UNSIGNED_INT_8_8_8_8_REV
:
4790 case GL_UNSIGNED_INT_10_10_10_2
:
4791 case GL_UNSIGNED_INT_2_10_10_10_REV
:
4792 return(sizeof(GLuint
));
4798 static GLint
is_index(GLenum format
)
4800 return format
== GL_COLOR_INDEX
|| format
== GL_STENCIL_INDEX
;
4804 ** Compute memory required for internal packed array of data of given type
4807 static GLint
image_size(GLint width
, GLint height
, GLenum format
, GLenum type
)
4814 components
= elements_per_group(format
,type
);
4815 if (type
== GL_BITMAP
) {
4816 bytes_per_row
= (width
+ 7) / 8;
4818 bytes_per_row
= bytes_per_element(type
) * width
;
4820 return bytes_per_row
* height
* components
;
4824 ** Extract array from user's data applying all pixel store modes.
4825 ** The internal format used is an array of unsigned shorts.
4827 static void fill_image(const PixelStorageModes
*psm
,
4828 GLint width
, GLint height
, GLenum format
,
4829 GLenum type
, GLboolean index_format
,
4830 const void *userdata
, GLushort
*newimage
)
4836 GLint groups_per_line
;
4838 GLint elements_per_line
;
4839 const GLubyte
*start
;
4840 const GLubyte
*iter
;
4845 myswap_bytes
= psm
->unpack_swap_bytes
;
4846 components
= elements_per_group(format
,type
);
4847 if (psm
->unpack_row_length
> 0) {
4848 groups_per_line
= psm
->unpack_row_length
;
4850 groups_per_line
= width
;
4853 /* All formats except GL_BITMAP fall out trivially */
4854 if (type
== GL_BITMAP
) {
4858 rowsize
= (groups_per_line
* components
+ 7) / 8;
4859 padding
= (rowsize
% psm
->unpack_alignment
);
4861 rowsize
+= psm
->unpack_alignment
- padding
;
4863 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4864 (psm
->unpack_skip_pixels
* components
/ 8);
4865 elements_per_line
= width
* components
;
4867 for (i
= 0; i
< height
; i
++) {
4869 bit_offset
= (psm
->unpack_skip_pixels
* components
) % 8;
4870 for (j
= 0; j
< elements_per_line
; j
++) {
4872 if (psm
->unpack_lsb_first
) {
4873 current_bit
= iter
[0] & (1 << bit_offset
);
4875 current_bit
= iter
[0] & (1 << (7 - bit_offset
));
4887 if (bit_offset
== 8) {
4896 element_size
= bytes_per_element(type
);
4897 group_size
= element_size
* components
;
4898 if (element_size
== 1) myswap_bytes
= 0;
4900 rowsize
= groups_per_line
* group_size
;
4901 padding
= (rowsize
% psm
->unpack_alignment
);
4903 rowsize
+= psm
->unpack_alignment
- padding
;
4905 start
= (const GLubyte
*) userdata
+ psm
->unpack_skip_rows
* rowsize
+
4906 psm
->unpack_skip_pixels
* group_size
;
4907 elements_per_line
= width
* components
;
4910 for (i
= 0; i
< height
; i
++) {
4912 for (j
= 0; j
< elements_per_line
; j
++) {
4914 float extractComponents
[4];
4917 case GL_UNSIGNED_BYTE_3_3_2
:
4918 extract332(0,iter
,extractComponents
);
4919 for (k
= 0; k
< 3; k
++) {
4920 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4923 case GL_UNSIGNED_BYTE_2_3_3_REV
:
4924 extract233rev(0,iter
,extractComponents
);
4925 for (k
= 0; k
< 3; k
++) {
4926 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4929 case GL_UNSIGNED_BYTE
:
4933 *iter2
++ = (*iter
) * 257;
4938 *iter2
++ = *((const GLbyte
*) iter
);
4941 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
4944 case GL_UNSIGNED_SHORT_5_6_5
:
4945 extract565(myswap_bytes
,iter
,extractComponents
);
4946 for (k
= 0; k
< 3; k
++) {
4947 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4950 case GL_UNSIGNED_SHORT_5_6_5_REV
:
4951 extract565rev(myswap_bytes
,iter
,extractComponents
);
4952 for (k
= 0; k
< 3; k
++) {
4953 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4956 case GL_UNSIGNED_SHORT_4_4_4_4
:
4957 extract4444(myswap_bytes
,iter
,extractComponents
);
4958 for (k
= 0; k
< 4; k
++) {
4959 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4962 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
4963 extract4444rev(myswap_bytes
,iter
,extractComponents
);
4964 for (k
= 0; k
< 4; k
++) {
4965 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4968 case GL_UNSIGNED_SHORT_5_5_5_1
:
4969 extract5551(myswap_bytes
,iter
,extractComponents
);
4970 for (k
= 0; k
< 4; k
++) {
4971 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4974 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
4975 extract1555rev(myswap_bytes
,iter
,extractComponents
);
4976 for (k
= 0; k
< 4; k
++) {
4977 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
4980 case GL_UNSIGNED_SHORT
:
4983 widget
.ub
[0] = iter
[1];
4984 widget
.ub
[1] = iter
[0];
4986 widget
.ub
[0] = iter
[0];
4987 widget
.ub
[1] = iter
[1];
4989 if (type
== GL_SHORT
) {
4991 *iter2
++ = widget
.s
[0];
4994 *iter2
++ = widget
.s
[0]*2;
4997 *iter2
++ = widget
.us
[0];
5000 case GL_UNSIGNED_INT_8_8_8_8
:
5001 extract8888(myswap_bytes
,iter
,extractComponents
);
5002 for (k
= 0; k
< 4; k
++) {
5003 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5006 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5007 extract8888rev(myswap_bytes
,iter
,extractComponents
);
5008 for (k
= 0; k
< 4; k
++) {
5009 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5012 case GL_UNSIGNED_INT_10_10_10_2
:
5013 extract1010102(myswap_bytes
,iter
,extractComponents
);
5014 for (k
= 0; k
< 4; k
++) {
5015 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5018 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5019 extract2101010rev(myswap_bytes
,iter
,extractComponents
);
5020 for (k
= 0; k
< 4; k
++) {
5021 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
5025 case GL_UNSIGNED_INT
:
5028 widget
.ub
[0] = iter
[3];
5029 widget
.ub
[1] = iter
[2];
5030 widget
.ub
[2] = iter
[1];
5031 widget
.ub
[3] = iter
[0];
5033 widget
.ub
[0] = iter
[0];
5034 widget
.ub
[1] = iter
[1];
5035 widget
.ub
[2] = iter
[2];
5036 widget
.ub
[3] = iter
[3];
5038 if (type
== GL_FLOAT
) {
5040 *iter2
++ = widget
.f
;
5042 *iter2
++ = 65535 * widget
.f
;
5044 } else if (type
== GL_UNSIGNED_INT
) {
5046 *iter2
++ = widget
.ui
;
5048 *iter2
++ = widget
.ui
>> 16;
5052 *iter2
++ = widget
.i
;
5054 *iter2
++ = widget
.i
>> 15;
5059 iter
+= element_size
;
5063 /* want 'iter' pointing at start, not within, row for assertion
5070 /* iterators should be one byte past end */
5071 if (!isTypePackedPixel(type
)) {
5072 assert(iter2
== &newimage
[width
*height
*components
]);
5075 assert(iter2
== &newimage
[width
*height
*
5076 elements_per_group(format
,0)]);
5078 assert( iter
== &((const GLubyte
*)userdata
)[rowsize
*height
+
5079 psm
->unpack_skip_rows
* rowsize
+
5080 psm
->unpack_skip_pixels
* group_size
] );
5083 } /* fill_image() */
5086 ** Insert array into user's data applying all pixel store modes.
5087 ** The internal format is an array of unsigned shorts.
5088 ** empty_image() because it is the opposite of fill_image().
5090 static void empty_image(const PixelStorageModes
*psm
,
5091 GLint width
, GLint height
, GLenum format
,
5092 GLenum type
, GLboolean index_format
,
5093 const GLushort
*oldimage
, void *userdata
)
5099 GLint groups_per_line
;
5101 GLint elements_per_line
;
5104 const GLushort
*iter2
;
5108 myswap_bytes
= psm
->pack_swap_bytes
;
5109 components
= elements_per_group(format
,type
);
5110 if (psm
->pack_row_length
> 0) {
5111 groups_per_line
= psm
->pack_row_length
;
5113 groups_per_line
= width
;
5116 /* All formats except GL_BITMAP fall out trivially */
5117 if (type
== GL_BITMAP
) {
5121 rowsize
= (groups_per_line
* components
+ 7) / 8;
5122 padding
= (rowsize
% psm
->pack_alignment
);
5124 rowsize
+= psm
->pack_alignment
- padding
;
5126 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5127 (psm
->pack_skip_pixels
* components
/ 8);
5128 elements_per_line
= width
* components
;
5130 for (i
= 0; i
< height
; i
++) {
5132 bit_offset
= (psm
->pack_skip_pixels
* components
) % 8;
5133 for (j
= 0; j
< elements_per_line
; j
++) {
5135 current_bit
= iter2
[0] & 1;
5137 if (iter2
[0] > 32767) {
5145 if (psm
->pack_lsb_first
) {
5146 *iter
|= (1 << bit_offset
);
5148 *iter
|= (1 << (7 - bit_offset
));
5151 if (psm
->pack_lsb_first
) {
5152 *iter
&= ~(1 << bit_offset
);
5154 *iter
&= ~(1 << (7 - bit_offset
));
5159 if (bit_offset
== 8) {
5168 float shoveComponents
[4];
5170 element_size
= bytes_per_element(type
);
5171 group_size
= element_size
* components
;
5172 if (element_size
== 1) myswap_bytes
= 0;
5174 rowsize
= groups_per_line
* group_size
;
5175 padding
= (rowsize
% psm
->pack_alignment
);
5177 rowsize
+= psm
->pack_alignment
- padding
;
5179 start
= (GLubyte
*) userdata
+ psm
->pack_skip_rows
* rowsize
+
5180 psm
->pack_skip_pixels
* group_size
;
5181 elements_per_line
= width
* components
;
5184 for (i
= 0; i
< height
; i
++) {
5186 for (j
= 0; j
< elements_per_line
; j
++) {
5190 case GL_UNSIGNED_BYTE_3_3_2
:
5191 for (k
= 0; k
< 3; k
++) {
5192 shoveComponents
[k
]= *iter2
++ / 65535.0;
5194 shove332(shoveComponents
,0,(void *)iter
);
5196 case GL_UNSIGNED_BYTE_2_3_3_REV
:
5197 for (k
= 0; k
< 3; k
++) {
5198 shoveComponents
[k
]= *iter2
++ / 65535.0;
5200 shove233rev(shoveComponents
,0,(void *)iter
);
5202 case GL_UNSIGNED_BYTE
:
5206 *iter
= *iter2
++ >> 8;
5211 *((GLbyte
*) iter
) = *iter2
++;
5213 *((GLbyte
*) iter
) = *iter2
++ >> 9;
5216 case GL_UNSIGNED_SHORT_5_6_5
:
5217 for (k
= 0; k
< 3; k
++) {
5218 shoveComponents
[k
]= *iter2
++ / 65535.0;
5220 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
5222 iter
[0] = widget
.ub
[1];
5223 iter
[1] = widget
.ub
[0];
5226 *(GLushort
*)iter
= widget
.us
[0];
5229 case GL_UNSIGNED_SHORT_5_6_5_REV
:
5230 for (k
= 0; k
< 3; k
++) {
5231 shoveComponents
[k
]= *iter2
++ / 65535.0;
5233 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5235 iter
[0] = widget
.ub
[1];
5236 iter
[1] = widget
.ub
[0];
5239 *(GLushort
*)iter
= widget
.us
[0];
5242 case GL_UNSIGNED_SHORT_4_4_4_4
:
5243 for (k
= 0; k
< 4; k
++) {
5244 shoveComponents
[k
]= *iter2
++ / 65535.0;
5246 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
5248 iter
[0] = widget
.ub
[1];
5249 iter
[1] = widget
.ub
[0];
5251 *(GLushort
*)iter
= widget
.us
[0];
5254 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
5255 for (k
= 0; k
< 4; k
++) {
5256 shoveComponents
[k
]= *iter2
++ / 65535.0;
5258 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5260 iter
[0] = widget
.ub
[1];
5261 iter
[1] = widget
.ub
[0];
5263 *(GLushort
*)iter
= widget
.us
[0];
5266 case GL_UNSIGNED_SHORT_5_5_5_1
:
5267 for (k
= 0; k
< 4; k
++) {
5268 shoveComponents
[k
]= *iter2
++ / 65535.0;
5270 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
5272 iter
[0] = widget
.ub
[1];
5273 iter
[1] = widget
.ub
[0];
5275 *(GLushort
*)iter
= widget
.us
[0];
5278 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
5279 for (k
= 0; k
< 4; k
++) {
5280 shoveComponents
[k
]= *iter2
++ / 65535.0;
5282 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
5284 iter
[0] = widget
.ub
[1];
5285 iter
[1] = widget
.ub
[0];
5287 *(GLushort
*)iter
= widget
.us
[0];
5290 case GL_UNSIGNED_SHORT
:
5292 if (type
== GL_SHORT
) {
5294 widget
.s
[0] = *iter2
++;
5296 widget
.s
[0] = *iter2
++ >> 1;
5299 widget
.us
[0] = *iter2
++;
5302 iter
[0] = widget
.ub
[1];
5303 iter
[1] = widget
.ub
[0];
5305 iter
[0] = widget
.ub
[0];
5306 iter
[1] = widget
.ub
[1];
5309 case GL_UNSIGNED_INT_8_8_8_8
:
5310 for (k
= 0; k
< 4; k
++) {
5311 shoveComponents
[k
]= *iter2
++ / 65535.0;
5313 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
5315 iter
[3] = widget
.ub
[0];
5316 iter
[2] = widget
.ub
[1];
5317 iter
[1] = widget
.ub
[2];
5318 iter
[0] = widget
.ub
[3];
5320 *(GLuint
*)iter
= widget
.ui
;
5324 case GL_UNSIGNED_INT_8_8_8_8_REV
:
5325 for (k
= 0; k
< 4; k
++) {
5326 shoveComponents
[k
]= *iter2
++ / 65535.0;
5328 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
5330 iter
[3] = widget
.ub
[0];
5331 iter
[2] = widget
.ub
[1];
5332 iter
[1] = widget
.ub
[2];
5333 iter
[0] = widget
.ub
[3];
5335 *(GLuint
*)iter
= widget
.ui
;
5338 case GL_UNSIGNED_INT_10_10_10_2
:
5339 for (k
= 0; k
< 4; k
++) {
5340 shoveComponents
[k
]= *iter2
++ / 65535.0;
5342 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
5344 iter
[3] = widget
.ub
[0];
5345 iter
[2] = widget
.ub
[1];
5346 iter
[1] = widget
.ub
[2];
5347 iter
[0] = widget
.ub
[3];
5349 *(GLuint
*)iter
= widget
.ui
;
5352 case GL_UNSIGNED_INT_2_10_10_10_REV
:
5353 for (k
= 0; k
< 4; k
++) {
5354 shoveComponents
[k
]= *iter2
++ / 65535.0;
5356 shove2101010rev(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
:
5369 if (type
== GL_FLOAT
) {
5371 widget
.f
= *iter2
++;
5373 widget
.f
= *iter2
++ / (float) 65535.0;
5375 } else if (type
== GL_UNSIGNED_INT
) {
5377 widget
.ui
= *iter2
++;
5379 widget
.ui
= (unsigned int) *iter2
++ * 65537;
5383 widget
.i
= *iter2
++;
5385 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
5389 iter
[3] = widget
.ub
[0];
5390 iter
[2] = widget
.ub
[1];
5391 iter
[1] = widget
.ub
[2];
5392 iter
[0] = widget
.ub
[3];
5394 iter
[0] = widget
.ub
[0];
5395 iter
[1] = widget
.ub
[1];
5396 iter
[2] = widget
.ub
[2];
5397 iter
[3] = widget
.ub
[3];
5401 iter
+= element_size
;
5405 /* want 'iter' pointing at start, not within, row for assertion
5412 /* iterators should be one byte past end */
5413 if (!isTypePackedPixel(type
)) {
5414 assert(iter2
== &oldimage
[width
*height
*components
]);
5417 assert(iter2
== &oldimage
[width
*height
*
5418 elements_per_group(format
,0)]);
5420 assert( iter
== &((GLubyte
*)userdata
)[rowsize
*height
+
5421 psm
->pack_skip_rows
* rowsize
+
5422 psm
->pack_skip_pixels
* group_size
] );
5425 } /* empty_image() */
5427 /*--------------------------------------------------------------------------
5428 * Decimation of packed pixel types
5429 *--------------------------------------------------------------------------
5431 static void extract332(int isSwap
,
5432 const void *packedPixel
, GLfloat extractComponents
[])
5434 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5436 isSwap
= isSwap
; /* turn off warnings */
5438 /* 11100000 == 0xe0 */
5439 /* 00011100 == 0x1c */
5440 /* 00000011 == 0x03 */
5442 extractComponents
[0]= (float)((ubyte
& 0xe0) >> 5) / 7.0;
5443 extractComponents
[1]= (float)((ubyte
& 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
5444 extractComponents
[2]= (float)((ubyte
& 0x03) ) / 3.0; /* 3 = 2^2-1 */
5445 } /* extract332() */
5447 static void shove332(const GLfloat shoveComponents
[],
5448 int index
, void *packedPixel
)
5450 /* 11100000 == 0xe0 */
5451 /* 00011100 == 0x1c */
5452 /* 00000011 == 0x03 */
5454 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5455 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5456 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5458 /* due to limited precision, need to round before shoving */
5459 ((GLubyte
*)packedPixel
)[index
] =
5460 ((GLubyte
)((shoveComponents
[0] * 7)+0.5) << 5) & 0xe0;
5461 ((GLubyte
*)packedPixel
)[index
] |=
5462 ((GLubyte
)((shoveComponents
[1] * 7)+0.5) << 2) & 0x1c;
5463 ((GLubyte
*)packedPixel
)[index
] |=
5464 ((GLubyte
)((shoveComponents
[2] * 3)+0.5) ) & 0x03;
5467 static void extract233rev(int isSwap
,
5468 const void *packedPixel
, GLfloat extractComponents
[])
5470 GLubyte ubyte
= *(const GLubyte
*)packedPixel
;
5472 isSwap
= isSwap
; /* turn off warnings */
5474 /* 0000,0111 == 0x07 */
5475 /* 0011,1000 == 0x38 */
5476 /* 1100,0000 == 0xC0 */
5478 extractComponents
[0]= (float)((ubyte
& 0x07) ) / 7.0;
5479 extractComponents
[1]= (float)((ubyte
& 0x38) >> 3) / 7.0;
5480 extractComponents
[2]= (float)((ubyte
& 0xC0) >> 6) / 3.0;
5481 } /* extract233rev() */
5483 static void shove233rev(const GLfloat shoveComponents
[],
5484 int index
, void *packedPixel
)
5486 /* 0000,0111 == 0x07 */
5487 /* 0011,1000 == 0x38 */
5488 /* 1100,0000 == 0xC0 */
5490 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5491 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5492 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5494 /* due to limited precision, need to round before shoving */
5495 ((GLubyte
*)packedPixel
)[index
] =
5496 ((GLubyte
)((shoveComponents
[0] * 7.0)+0.5) ) & 0x07;
5497 ((GLubyte
*)packedPixel
)[index
]|=
5498 ((GLubyte
)((shoveComponents
[1] * 7.0)+0.5) << 3) & 0x38;
5499 ((GLubyte
*)packedPixel
)[index
]|=
5500 ((GLubyte
)((shoveComponents
[2] * 3.0)+0.5) << 6) & 0xC0;
5501 } /* shove233rev() */
5503 static void extract565(int isSwap
,
5504 const void *packedPixel
, GLfloat extractComponents
[])
5506 GLushort ushort
= *(const GLushort
*)packedPixel
;
5509 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5512 ushort
= *(const GLushort
*)packedPixel
;
5515 /* 11111000,00000000 == 0xf800 */
5516 /* 00000111,11100000 == 0x07e0 */
5517 /* 00000000,00011111 == 0x001f */
5519 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5520 extractComponents
[1]=(float)((ushort
& 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
5521 extractComponents
[2]=(float)((ushort
& 0x001f) ) / 31.0;
5522 } /* extract565() */
5524 static void shove565(const GLfloat shoveComponents
[],
5525 int index
,void *packedPixel
)
5527 /* 11111000,00000000 == 0xf800 */
5528 /* 00000111,11100000 == 0x07e0 */
5529 /* 00000000,00011111 == 0x001f */
5531 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5532 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5533 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5535 /* due to limited precision, need to round before shoving */
5536 ((GLushort
*)packedPixel
)[index
] =
5537 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5538 ((GLushort
*)packedPixel
)[index
]|=
5539 ((GLushort
)((shoveComponents
[1] * 63)+0.5) << 5) & 0x07e0;
5540 ((GLushort
*)packedPixel
)[index
]|=
5541 ((GLushort
)((shoveComponents
[2] * 31)+0.5) ) & 0x001f;
5544 static void extract565rev(int isSwap
,
5545 const void *packedPixel
, GLfloat extractComponents
[])
5547 GLushort ushort
= *(const GLushort
*)packedPixel
;
5550 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5553 ushort
= *(const GLushort
*)packedPixel
;
5556 /* 00000000,00011111 == 0x001f */
5557 /* 00000111,11100000 == 0x07e0 */
5558 /* 11111000,00000000 == 0xf800 */
5560 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5561 extractComponents
[1]= (float)((ushort
& 0x07E0) >> 5) / 63.0;
5562 extractComponents
[2]= (float)((ushort
& 0xF800) >> 11) / 31.0;
5563 } /* extract565rev() */
5565 static void shove565rev(const GLfloat shoveComponents
[],
5566 int index
,void *packedPixel
)
5568 /* 00000000,00011111 == 0x001f */
5569 /* 00000111,11100000 == 0x07e0 */
5570 /* 11111000,00000000 == 0xf800 */
5572 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5573 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5574 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5576 /* due to limited precision, need to round before shoving */
5577 ((GLushort
*)packedPixel
)[index
] =
5578 ((GLushort
)((shoveComponents
[0] * 31.0)+0.5) ) & 0x001F;
5579 ((GLushort
*)packedPixel
)[index
]|=
5580 ((GLushort
)((shoveComponents
[1] * 63.0)+0.5) << 5) & 0x07E0;
5581 ((GLushort
*)packedPixel
)[index
]|=
5582 ((GLushort
)((shoveComponents
[2] * 31.0)+0.5) << 11) & 0xF800;
5583 } /* shove565rev() */
5585 static void extract4444(int isSwap
,const void *packedPixel
,
5586 GLfloat extractComponents
[])
5591 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5594 ushort
= *(const GLushort
*)packedPixel
;
5597 /* 11110000,00000000 == 0xf000 */
5598 /* 00001111,00000000 == 0x0f00 */
5599 /* 00000000,11110000 == 0x00f0 */
5600 /* 00000000,00001111 == 0x000f */
5602 extractComponents
[0]= (float)((ushort
& 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
5603 extractComponents
[1]= (float)((ushort
& 0x0f00) >> 8) / 15.0;
5604 extractComponents
[2]= (float)((ushort
& 0x00f0) >> 4) / 15.0;
5605 extractComponents
[3]= (float)((ushort
& 0x000f) ) / 15.0;
5606 } /* extract4444() */
5608 static void shove4444(const GLfloat shoveComponents
[],
5609 int index
,void *packedPixel
)
5611 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5612 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5613 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5614 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5616 /* due to limited precision, need to round before shoving */
5617 ((GLushort
*)packedPixel
)[index
] =
5618 ((GLushort
)((shoveComponents
[0] * 15)+0.5) << 12) & 0xf000;
5619 ((GLushort
*)packedPixel
)[index
]|=
5620 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 8) & 0x0f00;
5621 ((GLushort
*)packedPixel
)[index
]|=
5622 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 4) & 0x00f0;
5623 ((GLushort
*)packedPixel
)[index
]|=
5624 ((GLushort
)((shoveComponents
[3] * 15)+0.5) ) & 0x000f;
5627 static void extract4444rev(int isSwap
,const void *packedPixel
,
5628 GLfloat extractComponents
[])
5633 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5636 ushort
= *(const GLushort
*)packedPixel
;
5639 /* 00000000,00001111 == 0x000f */
5640 /* 00000000,11110000 == 0x00f0 */
5641 /* 00001111,00000000 == 0x0f00 */
5642 /* 11110000,00000000 == 0xf000 */
5645 extractComponents
[0]= (float)((ushort
& 0x000F) ) / 15.0;
5646 extractComponents
[1]= (float)((ushort
& 0x00F0) >> 4) / 15.0;
5647 extractComponents
[2]= (float)((ushort
& 0x0F00) >> 8) / 15.0;
5648 extractComponents
[3]= (float)((ushort
& 0xF000) >> 12) / 15.0;
5649 } /* extract4444rev() */
5651 static void shove4444rev(const GLfloat shoveComponents
[],
5652 int index
,void *packedPixel
)
5654 /* 00000000,00001111 == 0x000f */
5655 /* 00000000,11110000 == 0x00f0 */
5656 /* 00001111,00000000 == 0x0f00 */
5657 /* 11110000,00000000 == 0xf000 */
5659 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5660 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5661 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5662 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5664 /* due to limited precision, need to round before shoving */
5665 ((GLushort
*)packedPixel
)[index
] =
5666 ((GLushort
)((shoveComponents
[0] * 15)+0.5) ) & 0x000F;
5667 ((GLushort
*)packedPixel
)[index
]|=
5668 ((GLushort
)((shoveComponents
[1] * 15)+0.5) << 4) & 0x00F0;
5669 ((GLushort
*)packedPixel
)[index
]|=
5670 ((GLushort
)((shoveComponents
[2] * 15)+0.5) << 8) & 0x0F00;
5671 ((GLushort
*)packedPixel
)[index
]|=
5672 ((GLushort
)((shoveComponents
[3] * 15)+0.5) << 12) & 0xF000;
5673 } /* shove4444rev() */
5675 static void extract5551(int isSwap
,const void *packedPixel
,
5676 GLfloat extractComponents
[])
5681 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5684 ushort
= *(const GLushort
*)packedPixel
;
5687 /* 11111000,00000000 == 0xf800 */
5688 /* 00000111,11000000 == 0x07c0 */
5689 /* 00000000,00111110 == 0x003e */
5690 /* 00000000,00000001 == 0x0001 */
5692 extractComponents
[0]=(float)((ushort
& 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
5693 extractComponents
[1]=(float)((ushort
& 0x07c0) >> 6) / 31.0;
5694 extractComponents
[2]=(float)((ushort
& 0x003e) >> 1) / 31.0;
5695 extractComponents
[3]=(float)((ushort
& 0x0001) );
5696 } /* extract5551() */
5698 static void shove5551(const GLfloat shoveComponents
[],
5699 int index
,void *packedPixel
)
5701 /* 11111000,00000000 == 0xf800 */
5702 /* 00000111,11000000 == 0x07c0 */
5703 /* 00000000,00111110 == 0x003e */
5704 /* 00000000,00000001 == 0x0001 */
5706 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5707 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5708 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5709 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5711 /* due to limited precision, need to round before shoving */
5712 ((GLushort
*)packedPixel
)[index
] =
5713 ((GLushort
)((shoveComponents
[0] * 31)+0.5) << 11) & 0xf800;
5714 ((GLushort
*)packedPixel
)[index
]|=
5715 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 6) & 0x07c0;
5716 ((GLushort
*)packedPixel
)[index
]|=
5717 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 1) & 0x003e;
5718 ((GLushort
*)packedPixel
)[index
]|=
5719 ((GLushort
)((shoveComponents
[3])+0.5) ) & 0x0001;
5722 static void extract1555rev(int isSwap
,const void *packedPixel
,
5723 GLfloat extractComponents
[])
5728 ushort
= __GLU_SWAP_2_BYTES(packedPixel
);
5731 ushort
= *(const GLushort
*)packedPixel
;
5734 /* 00000000,00011111 == 0x001F */
5735 /* 00000011,11100000 == 0x03E0 */
5736 /* 01111100,00000000 == 0x7C00 */
5737 /* 10000000,00000000 == 0x8000 */
5740 extractComponents
[0]= (float)((ushort
& 0x001F) ) / 31.0;
5741 extractComponents
[1]= (float)((ushort
& 0x03E0) >> 5) / 31.0;
5742 extractComponents
[2]= (float)((ushort
& 0x7C00) >> 10) / 31.0;
5743 extractComponents
[3]= (float)((ushort
& 0x8000) >> 15);
5744 } /* extract1555rev() */
5746 static void shove1555rev(const GLfloat shoveComponents
[],
5747 int index
,void *packedPixel
)
5749 /* 00000000,00011111 == 0x001F */
5750 /* 00000011,11100000 == 0x03E0 */
5751 /* 01111100,00000000 == 0x7C00 */
5752 /* 10000000,00000000 == 0x8000 */
5754 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5755 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5756 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5757 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5759 /* due to limited precision, need to round before shoving */
5760 ((GLushort
*)packedPixel
)[index
] =
5761 ((GLushort
)((shoveComponents
[0] * 31)+0.5) ) & 0x001F;
5762 ((GLushort
*)packedPixel
)[index
]|=
5763 ((GLushort
)((shoveComponents
[1] * 31)+0.5) << 5) & 0x03E0;
5764 ((GLushort
*)packedPixel
)[index
]|=
5765 ((GLushort
)((shoveComponents
[2] * 31)+0.5) << 10) & 0x7C00;
5766 ((GLushort
*)packedPixel
)[index
]|=
5767 ((GLushort
)((shoveComponents
[3])+0.5) << 15) & 0x8000;
5768 } /* shove1555rev() */
5770 static void extract8888(int isSwap
,
5771 const void *packedPixel
, GLfloat extractComponents
[])
5776 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5779 uint
= *(const GLuint
*)packedPixel
;
5782 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5783 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5784 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5785 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5788 extractComponents
[0]= (float)((uint
& 0xff000000) >> 24) / 255.0;
5789 extractComponents
[1]= (float)((uint
& 0x00ff0000) >> 16) / 255.0;
5790 extractComponents
[2]= (float)((uint
& 0x0000ff00) >> 8) / 255.0;
5791 extractComponents
[3]= (float)((uint
& 0x000000ff) ) / 255.0;
5792 } /* extract8888() */
5794 static void shove8888(const GLfloat shoveComponents
[],
5795 int index
,void *packedPixel
)
5797 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5798 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5799 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5800 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5802 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5803 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5804 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5805 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5807 /* due to limited precision, need to round before shoving */
5808 ((GLuint
*)packedPixel
)[index
] =
5809 ((GLuint
)((shoveComponents
[0] * 255)+0.5) << 24) & 0xff000000;
5810 ((GLuint
*)packedPixel
)[index
]|=
5811 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 16) & 0x00ff0000;
5812 ((GLuint
*)packedPixel
)[index
]|=
5813 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 8) & 0x0000ff00;
5814 ((GLuint
*)packedPixel
)[index
]|=
5815 ((GLuint
)((shoveComponents
[3] * 255)+0.5) ) & 0x000000ff;
5818 static void extract8888rev(int isSwap
,
5819 const void *packedPixel
,GLfloat extractComponents
[])
5824 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5827 uint
= *(const GLuint
*)packedPixel
;
5830 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5831 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5832 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5833 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5836 extractComponents
[0]= (float)((uint
& 0x000000FF) ) / 255.0;
5837 extractComponents
[1]= (float)((uint
& 0x0000FF00) >> 8) / 255.0;
5838 extractComponents
[2]= (float)((uint
& 0x00FF0000) >> 16) / 255.0;
5839 extractComponents
[3]= (float)((uint
& 0xFF000000) >> 24) / 255.0;
5840 } /* extract8888rev() */
5842 static void shove8888rev(const GLfloat shoveComponents
[],
5843 int index
,void *packedPixel
)
5845 /* 00000000,00000000,00000000,11111111 == 0x000000ff */
5846 /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
5847 /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
5848 /* 11111111,00000000,00000000,00000000 == 0xff000000 */
5850 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5851 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5852 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5853 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5855 /* due to limited precision, need to round before shoving */
5856 ((GLuint
*)packedPixel
)[index
] =
5857 ((GLuint
)((shoveComponents
[0] * 255)+0.5) ) & 0x000000FF;
5858 ((GLuint
*)packedPixel
)[index
]|=
5859 ((GLuint
)((shoveComponents
[1] * 255)+0.5) << 8) & 0x0000FF00;
5860 ((GLuint
*)packedPixel
)[index
]|=
5861 ((GLuint
)((shoveComponents
[2] * 255)+0.5) << 16) & 0x00FF0000;
5862 ((GLuint
*)packedPixel
)[index
]|=
5863 ((GLuint
)((shoveComponents
[3] * 255)+0.5) << 24) & 0xFF000000;
5864 } /* shove8888rev() */
5866 static void extract1010102(int isSwap
,
5867 const void *packedPixel
,GLfloat extractComponents
[])
5872 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5875 uint
= *(const GLuint
*)packedPixel
;
5878 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5879 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5880 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5881 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5884 extractComponents
[0]= (float)((uint
& 0xffc00000) >> 22) / 1023.0;
5885 extractComponents
[1]= (float)((uint
& 0x003ff000) >> 12) / 1023.0;
5886 extractComponents
[2]= (float)((uint
& 0x00000ffc) >> 2) / 1023.0;
5887 extractComponents
[3]= (float)((uint
& 0x00000003) ) / 3.0;
5888 } /* extract1010102() */
5890 static void shove1010102(const GLfloat shoveComponents
[],
5891 int index
,void *packedPixel
)
5893 /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
5894 /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
5895 /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
5896 /* 00000000,00000000,00000000,00000011 == 0x00000003 */
5898 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5899 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5900 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5901 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5903 /* due to limited precision, need to round before shoving */
5904 ((GLuint
*)packedPixel
)[index
] =
5905 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) << 22) & 0xffc00000;
5906 ((GLuint
*)packedPixel
)[index
]|=
5907 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 12) & 0x003ff000;
5908 ((GLuint
*)packedPixel
)[index
]|=
5909 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 2) & 0x00000ffc;
5910 ((GLuint
*)packedPixel
)[index
]|=
5911 ((GLuint
)((shoveComponents
[3] * 3)+0.5) ) & 0x00000003;
5912 } /* shove1010102() */
5914 static void extract2101010rev(int isSwap
,
5915 const void *packedPixel
,
5916 GLfloat extractComponents
[])
5921 uint
= __GLU_SWAP_4_BYTES(packedPixel
);
5924 uint
= *(const GLuint
*)packedPixel
;
5927 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5928 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5929 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5930 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5933 extractComponents
[0]= (float)((uint
& 0x000003FF) ) / 1023.0;
5934 extractComponents
[1]= (float)((uint
& 0x000FFC00) >> 10) / 1023.0;
5935 extractComponents
[2]= (float)((uint
& 0x3FF00000) >> 20) / 1023.0;
5936 extractComponents
[3]= (float)((uint
& 0xC0000000) >> 30) / 3.0;
5938 } /* extract2101010rev() */
5940 static void shove2101010rev(const GLfloat shoveComponents
[],
5941 int index
,void *packedPixel
)
5943 /* 00000000,00000000,00000011,11111111 == 0x000003FF */
5944 /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
5945 /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
5946 /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
5948 assert(0.0 <= shoveComponents
[0] && shoveComponents
[0] <= 1.0);
5949 assert(0.0 <= shoveComponents
[1] && shoveComponents
[1] <= 1.0);
5950 assert(0.0 <= shoveComponents
[2] && shoveComponents
[2] <= 1.0);
5951 assert(0.0 <= shoveComponents
[3] && shoveComponents
[3] <= 1.0);
5953 /* due to limited precision, need to round before shoving */
5954 ((GLuint
*)packedPixel
)[index
] =
5955 ((GLuint
)((shoveComponents
[0] * 1023)+0.5) ) & 0x000003FF;
5956 ((GLuint
*)packedPixel
)[index
]|=
5957 ((GLuint
)((shoveComponents
[1] * 1023)+0.5) << 10) & 0x000FFC00;
5958 ((GLuint
*)packedPixel
)[index
]|=
5959 ((GLuint
)((shoveComponents
[2] * 1023)+0.5) << 20) & 0x3FF00000;
5960 ((GLuint
*)packedPixel
)[index
]|=
5961 ((GLuint
)((shoveComponents
[3] * 3)+0.5) << 30) & 0xC0000000;
5962 } /* shove2101010rev() */
5964 static void scaleInternalPackedPixel(int components
,
5965 void (*extractPackedPixel
)
5966 (int, const void *,GLfloat
[]),
5967 void (*shovePackedPixel
)
5968 (const GLfloat
[], int, void *),
5969 GLint widthIn
,GLint heightIn
,
5971 GLint widthOut
,GLint heightOut
,
5973 GLint pixelSizeInBytes
,
5974 GLint rowSizeInBytes
,GLint isSwap
)
5980 /* Max components in a format is 4, so... */
5982 float extractTotals
[4], extractMoreTotals
[4], shoveTotals
[4];
5987 const char *temp
, *temp0
;
5990 int lowx_int
, highx_int
, lowy_int
, highy_int
;
5991 float x_percent
, y_percent
;
5992 float lowx_float
, highx_float
, lowy_float
, highy_float
;
5993 float convy_float
, convx_float
;
5994 int convy_int
, convx_int
;
5996 const char *left
, *right
;
5998 if (widthIn
== widthOut
*2 && heightIn
== heightOut
*2) {
5999 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6000 widthIn
, heightIn
, dataIn
, dataOut
,
6001 pixelSizeInBytes
,rowSizeInBytes
,isSwap
);
6004 convy
= (float) heightIn
/heightOut
;
6005 convx
= (float) widthIn
/widthOut
;
6006 convy_int
= floor(convy
);
6007 convy_float
= convy
- convy_int
;
6008 convx_int
= floor(convx
);
6009 convx_float
= convx
- convx_int
;
6011 area
= convx
* convy
;
6015 highy_int
= convy_int
;
6016 highy_float
= convy_float
;
6018 for (i
= 0; i
< heightOut
; i
++) {
6021 highx_int
= convx_int
;
6022 highx_float
= convx_float
;
6024 for (j
= 0; j
< widthOut
; j
++) {
6026 ** Ok, now apply box filter to box that goes from (lowx, lowy)
6027 ** to (highx, highy) on input data into this pixel on output
6030 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6032 /* calculate the value for pixels in the 1st row */
6033 xindex
= lowx_int
*pixelSizeInBytes
;
6034 if((highy_int
>lowy_int
) && (highx_int
>lowx_int
)) {
6036 y_percent
= 1-lowy_float
;
6037 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6038 percent
= y_percent
* (1-lowx_float
);
6040 for (k
= 0, temp_index
= temp
; k
< components
;
6041 k
++, temp_index
+= element_size
) {
6043 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6045 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6049 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6050 for (k
= 0; k
< components
; k
++) {
6051 totals
[k
]+= extractTotals
[k
] * percent
;
6055 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6056 temp
+= pixelSizeInBytes
;
6058 for (k
= 0, temp_index
= temp
; k
< components
;
6059 k
++, temp_index
+= element_size
) {
6062 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6064 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6068 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6069 for (k
= 0; k
< components
; k
++) {
6070 totals
[k
]+= extractTotals
[k
] * y_percent
;
6074 temp
+= pixelSizeInBytes
;
6076 percent
= y_percent
* highx_float
;
6078 for (k
= 0, temp_index
= temp
; k
< components
;
6079 k
++, temp_index
+= element_size
) {
6081 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6083 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6087 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6088 for (k
= 0; k
< components
; k
++) {
6089 totals
[k
]+= extractTotals
[k
] * percent
;
6093 /* calculate the value for pixels in the last row */
6095 y_percent
= highy_float
;
6096 percent
= y_percent
* (1-lowx_float
);
6097 temp
= (const char *)dataIn
+ xindex
+ highy_int
* rowSizeInBytes
;
6099 for (k
= 0, temp_index
= temp
; k
< components
;
6100 k
++, temp_index
+= element_size
) {
6102 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6104 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6108 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6109 for (k
= 0; k
< components
; k
++) {
6110 totals
[k
]+= extractTotals
[k
] * percent
;
6113 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6114 temp
+= pixelSizeInBytes
;
6116 for (k
= 0, temp_index
= temp
; k
< components
;
6117 k
++, temp_index
+= element_size
) {
6120 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6122 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6126 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6127 for (k
= 0; k
< components
; k
++) {
6128 totals
[k
]+= extractTotals
[k
] * y_percent
;
6133 temp
+= pixelSizeInBytes
;
6134 percent
= y_percent
* highx_float
;
6136 for (k
= 0, temp_index
= temp
; k
< components
;
6137 k
++, temp_index
+= element_size
) {
6139 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6141 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6145 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6146 for (k
= 0; k
< components
; k
++) {
6147 totals
[k
]+= extractTotals
[k
] * percent
;
6151 /* calculate the value for pixels in the 1st and last column */
6152 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6153 left
+= rowSizeInBytes
;
6154 right
+= rowSizeInBytes
;
6156 for (k
= 0; k
< components
;
6157 k
++, left
+= element_size
, right
+= element_size
) {
6160 __GLU_SWAP_2_BYTES(left
) * (1-lowx_float
) +
6161 __GLU_SWAP_2_BYTES(right
) * highx_float
;
6163 totals
[k
] += *(const GLushort
*)left
* (1-lowx_float
)
6164 + *(const GLushort
*)right
* highx_float
;
6168 (*extractPackedPixel
)(isSwap
,left
,extractTotals
);
6169 (*extractPackedPixel
)(isSwap
,right
,extractMoreTotals
);
6170 for (k
= 0; k
< components
; k
++) {
6171 totals
[k
]+= (extractTotals
[k
]*(1-lowx_float
) +
6172 extractMoreTotals
[k
]*highx_float
);
6176 } else if (highy_int
> lowy_int
) {
6177 x_percent
= highx_float
- lowx_float
;
6178 percent
= (1-lowy_float
)*x_percent
;
6179 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6181 for (k
= 0, temp_index
= temp
; k
< components
;
6182 k
++, temp_index
+= element_size
) {
6184 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6186 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6190 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6191 for (k
= 0; k
< components
; k
++) {
6192 totals
[k
]+= extractTotals
[k
] * percent
;
6195 for(m
= lowy_int
+1; m
< highy_int
; m
++) {
6196 temp
+= rowSizeInBytes
;
6198 for (k
= 0, temp_index
= temp
; k
< components
;
6199 k
++, temp_index
+= element_size
) {
6202 __GLU_SWAP_2_BYTES(temp_index
) * x_percent
;
6204 totals
[k
] += *(const GLushort
*)temp_index
* x_percent
;
6208 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6209 for (k
= 0; k
< components
; k
++) {
6210 totals
[k
]+= extractTotals
[k
] * x_percent
;
6214 percent
= x_percent
* highy_float
;
6215 temp
+= rowSizeInBytes
;
6217 for (k
= 0, temp_index
= temp
; k
< components
;
6218 k
++, temp_index
+= element_size
) {
6220 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6222 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6226 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6227 for (k
= 0; k
< components
; k
++) {
6228 totals
[k
]+= extractTotals
[k
] * percent
;
6231 } else if (highx_int
> lowx_int
) {
6232 y_percent
= highy_float
- lowy_float
;
6233 percent
= (1-lowx_float
)*y_percent
;
6234 temp
= (const char *)dataIn
+ xindex
+ lowy_int
*rowSizeInBytes
;
6236 for (k
= 0, temp_index
= temp
; k
< components
;
6237 k
++, temp_index
+= element_size
) {
6239 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6241 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6245 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6246 for (k
= 0; k
< components
; k
++) {
6247 totals
[k
]+= extractTotals
[k
] * percent
;
6250 for (l
= lowx_int
+1; l
< highx_int
; l
++) {
6251 temp
+= pixelSizeInBytes
;
6253 for (k
= 0, temp_index
= temp
; k
< components
;
6254 k
++, temp_index
+= element_size
) {
6257 __GLU_SWAP_2_BYTES(temp_index
) * y_percent
;
6259 totals
[k
] += *(const GLushort
*)temp_index
* y_percent
;
6263 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6264 for (k
= 0; k
< components
; k
++) {
6265 totals
[k
]+= extractTotals
[k
] * y_percent
;
6269 temp
+= pixelSizeInBytes
;
6270 percent
= y_percent
* highx_float
;
6272 for (k
= 0, temp_index
= temp
; k
< components
;
6273 k
++, temp_index
+= element_size
) {
6275 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6277 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6281 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6282 for (k
= 0; k
< components
; k
++) {
6283 totals
[k
]+= extractTotals
[k
] * percent
;
6287 percent
= (highy_float
-lowy_float
)*(highx_float
-lowx_float
);
6288 temp
= (const char *)dataIn
+ xindex
+ lowy_int
* rowSizeInBytes
;
6290 for (k
= 0, temp_index
= temp
; k
< components
;
6291 k
++, temp_index
+= element_size
) {
6293 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
) * percent
;
6295 totals
[k
] += *(const GLushort
*)temp_index
* percent
;
6299 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6300 for (k
= 0; k
< components
; k
++) {
6301 totals
[k
]+= extractTotals
[k
] * percent
;
6306 /* this is for the pixels in the body */
6307 temp0
= (const char *)dataIn
+ xindex
+ pixelSizeInBytes
+ (lowy_int
+1)*rowSizeInBytes
;
6308 for (m
= lowy_int
+1; m
< highy_int
; m
++) {
6310 for(l
= lowx_int
+1; l
< highx_int
; l
++) {
6312 for (k
= 0, temp_index
= temp
; k
< components
;
6313 k
++, temp_index
+= element_size
) {
6315 totals
[k
] += __GLU_SWAP_2_BYTES(temp_index
);
6317 totals
[k
] += *(const GLushort
*)temp_index
;
6321 (*extractPackedPixel
)(isSwap
,temp
,extractTotals
);
6322 for (k
= 0; k
< components
; k
++) {
6323 totals
[k
]+= extractTotals
[k
];
6326 temp
+= pixelSizeInBytes
;
6328 temp0
+= rowSizeInBytes
;
6331 outindex
= (j
+ (i
* widthOut
)); /* * (components == 1) */
6333 for (k
= 0; k
< components
; k
++) {
6334 dataout
[outindex
+ k
] = totals
[k
]/area
;
6335 /*printf("totals[%d] = %f\n", k, totals[k]);*/
6338 for (k
= 0; k
< components
; k
++) {
6339 shoveTotals
[k
]= totals
[k
]/area
;
6341 (*shovePackedPixel
)(shoveTotals
,outindex
,(void *)dataOut
);
6343 lowx_int
= highx_int
;
6344 lowx_float
= highx_float
;
6345 highx_int
+= convx_int
;
6346 highx_float
+= convx_float
;
6347 if(highx_float
> 1) {
6352 lowy_int
= highy_int
;
6353 lowy_float
= highy_float
;
6354 highy_int
+= convy_int
;
6355 highy_float
+= convy_float
;
6356 if(highy_float
> 1) {
6362 assert(outindex
== (widthOut
*heightOut
- 1));
6363 } /* scaleInternalPackedPixel() */
6365 /* rowSizeInBytes is at least the width (in bytes) due to padding on
6366 * inputs; not always equal. Output NEVER has row padding.
6368 static void halveImagePackedPixel(int components
,
6369 void (*extractPackedPixel
)
6370 (int, const void *,GLfloat
[]),
6371 void (*shovePackedPixel
)
6372 (const GLfloat
[],int, void *),
6373 GLint width
, GLint height
,
6374 const void *dataIn
, void *dataOut
,
6375 GLint pixelSizeInBytes
,
6376 GLint rowSizeInBytes
, GLint isSwap
)
6378 /* handle case where there is only 1 column/row */
6379 if (width
== 1 || height
== 1) {
6380 assert(!(width
== 1 && height
== 1)); /* can't be 1x1 */
6381 halve1DimagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
6382 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
6383 rowSizeInBytes
,isSwap
);
6390 int halfWidth
= width
/ 2;
6391 int halfHeight
= height
/ 2;
6392 const char *src
= (const char *) dataIn
;
6393 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6396 for (ii
= 0; ii
< halfHeight
; ii
++) {
6397 for (jj
= 0; jj
< halfWidth
; jj
++) {
6399 float totals
[4]; /* 4 is maximum components */
6400 float extractTotals
[BOX4
][4]; /* 4 is maximum components */
6403 (*extractPackedPixel
)(isSwap
,src
,
6404 &extractTotals
[0][0]);
6405 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6406 &extractTotals
[1][0]);
6407 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6408 &extractTotals
[2][0]);
6409 (*extractPackedPixel
)(isSwap
,
6410 (src
+rowSizeInBytes
+pixelSizeInBytes
),
6411 &extractTotals
[3][0]);
6412 for (cc
= 0; cc
< components
; cc
++) {
6415 /* grab 4 pixels to average */
6417 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
6418 * extractTotals[2][RED]+extractTotals[3][RED];
6419 * totals[RED]/= 4.0;
6421 for (kk
= 0; kk
< BOX4
; kk
++) {
6422 totals
[cc
]+= extractTotals
[kk
][cc
];
6424 totals
[cc
]/= (float)BOX4
;
6426 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6429 /* skip over to next square of 4 */
6430 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6432 /* skip past pad bytes, if any, to get to next row */
6435 /* src is at beginning of a row here, but it's the second row of
6436 * the square block of 4 pixels that we just worked on so we
6437 * need to go one more row.
6445 src
+= rowSizeInBytes
;
6448 /* both pointers must reach one byte after the end */
6449 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6450 assert(outIndex
== halfWidth
* halfHeight
);
6452 } /* halveImagePackedPixel() */
6454 static void halve1DimagePackedPixel(int components
,
6455 void (*extractPackedPixel
)
6456 (int, const void *,GLfloat
[]),
6457 void (*shovePackedPixel
)
6458 (const GLfloat
[],int, void *),
6459 GLint width
, GLint height
,
6460 const void *dataIn
, void *dataOut
,
6461 GLint pixelSizeInBytes
,
6462 GLint rowSizeInBytes
, GLint isSwap
)
6464 int halfWidth
= width
/ 2;
6465 int halfHeight
= height
/ 2;
6466 const char *src
= (const char *) dataIn
;
6469 assert(width
== 1 || height
== 1); /* must be 1D */
6470 assert(width
!= height
); /* can't be square */
6472 if (height
== 1) { /* 1 row */
6475 assert(width
!= 1); /* widthxheight can't be 1x1 */
6478 /* one horizontal row with possible pad bytes */
6480 for (jj
= 0; jj
< halfWidth
; jj
++) {
6482 float totals
[4]; /* 4 is maximum components */
6483 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6486 /* average two at a time, instead of four */
6487 (*extractPackedPixel
)(isSwap
,src
,
6488 &extractTotals
[0][0]);
6489 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
6490 &extractTotals
[1][0]);
6491 for (cc
= 0; cc
< components
; cc
++) {
6494 /* grab 2 pixels to average */
6496 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6497 * totals[RED]/= 2.0;
6499 for (kk
= 0; kk
< BOX2
; kk
++) {
6500 totals
[cc
]+= extractTotals
[kk
][cc
];
6502 totals
[cc
]/= (float)BOX2
;
6504 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6507 /* skip over to next group of 2 */
6508 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
6512 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
6513 src
+= padBytes
; /* for assertion only */
6515 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
]);
6516 assert(outIndex
== halfWidth
* halfHeight
);
6518 else if (width
== 1) { /* 1 column */
6521 assert(height
!= 1); /* widthxheight can't be 1x1 */
6523 /* one vertical column with possible pad bytes per row */
6524 /* average two at a time */
6526 for (jj
= 0; jj
< halfHeight
; jj
++) {
6528 float totals
[4]; /* 4 is maximum components */
6529 float extractTotals
[BOX2
][4]; /* 4 is maximum components */
6532 /* average two at a time, instead of four */
6533 (*extractPackedPixel
)(isSwap
,src
,
6534 &extractTotals
[0][0]);
6535 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
6536 &extractTotals
[1][0]);
6537 for (cc
= 0; cc
< components
; cc
++) {
6540 /* grab 2 pixels to average */
6542 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
6543 * totals[RED]/= 2.0;
6545 for (kk
= 0; kk
< BOX2
; kk
++) {
6546 totals
[cc
]+= extractTotals
[kk
][cc
];
6548 totals
[cc
]/= (float)BOX2
;
6550 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
6553 src
+= rowSizeInBytes
+ rowSizeInBytes
; /* go to row after next */
6556 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
]);
6557 assert(outIndex
== halfWidth
* halfHeight
);
6559 } /* halve1DimagePackedPixel() */
6561 /*===========================================================================*/
6563 #ifdef RESOLVE_3D_TEXTURE_SUPPORT
6565 * This section ensures that GLU 1.3 will load and run on
6566 * a GL 1.1 implementation. It dynamically resolves the
6567 * call to glTexImage3D() which might not be available.
6568 * Or is it might be supported as an extension.
6569 * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
6572 typedef GLAPI
void (GLAPIENTRY
*TexImage3Dproc
)( GLenum target
, GLint level
,
6573 GLenum internalFormat
,
6574 GLsizei width
, GLsizei height
,
6575 GLsizei depth
, GLint border
,
6576 GLenum format
, GLenum type
,
6577 const GLvoid
*pixels
);
6579 static TexImage3Dproc pTexImage3D
;
6583 # include <sys/types.h>
6585 WINGDIAPI PROC WINAPI
wglGetProcAddress(LPCSTR
);
6588 static void gluTexImage3D( GLenum target
, GLint level
,
6589 GLenum internalFormat
,
6590 GLsizei width
, GLsizei height
,
6591 GLsizei depth
, GLint border
,
6592 GLenum format
, GLenum type
,
6593 const GLvoid
*pixels
)
6597 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3D");
6599 pTexImage3D
= (TexImage3Dproc
) wglGetProcAddress("glTexImage3DEXT");
6601 void *libHandle
= dlopen("libgl.so", RTLD_LAZY
);
6602 pTexImage3D
= TexImage3Dproc
) dlsym(libHandle
, "glTexImage3D" );
6604 pTexImage3D
= (TexImage3Dproc
) dlsym(libHandle
,"glTexImage3DEXT");
6609 /* Now call glTexImage3D */
6611 pTexImage3D(target
, level
, internalFormat
, width
, height
,
6612 depth
, border
, format
, type
, pixels
);
6617 /* Only bind to a GL 1.2 implementation: */
6618 #define gluTexImage3D glTexImage3D
6622 static GLint
imageSize3D(GLint width
, GLint height
, GLint depth
,
6623 GLenum format
, GLenum type
)
6625 int components
= elements_per_group(format
,type
);
6626 int bytes_per_row
= bytes_per_element(type
) * width
;
6628 assert(width
> 0 && height
> 0 && depth
> 0);
6629 assert(type
!= GL_BITMAP
);
6631 return bytes_per_row
* height
* depth
* components
;
6632 } /* imageSize3D() */
6634 static void fillImage3D(const PixelStorageModes
*psm
,
6635 GLint width
, GLint height
, GLint depth
, GLenum format
,
6636 GLenum type
, GLboolean indexFormat
,
6637 const void *userImage
, GLushort
*newImage
)
6646 int elementsPerLine
;
6649 const GLubyte
*start
, *rowStart
, *iter
;
6653 myswapBytes
= psm
->unpack_swap_bytes
;
6654 components
= elements_per_group(format
,type
);
6655 if (psm
->unpack_row_length
> 0) {
6656 groupsPerLine
= psm
->unpack_row_length
;
6659 groupsPerLine
= width
;
6661 elementSize
= bytes_per_element(type
);
6662 groupSize
= elementSize
* components
;
6663 if (elementSize
== 1) myswapBytes
= 0;
6666 if (psm
->unpack_image_height
> 0) {
6667 rowsPerImage
= psm
->unpack_image_height
;
6670 rowsPerImage
= height
;
6674 rowSize
= groupsPerLine
* groupSize
;
6675 padding
= rowSize
% psm
->unpack_alignment
;
6677 rowSize
+= psm
->unpack_alignment
- padding
;
6680 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
6682 start
= (const GLubyte
*)userImage
+ psm
->unpack_skip_rows
* rowSize
+
6683 psm
->unpack_skip_pixels
* groupSize
+
6685 psm
->unpack_skip_images
* imageSize
;
6686 elementsPerLine
= width
* components
;
6689 for (dd
= 0; dd
< depth
; dd
++) {
6692 for (hh
= 0; hh
< height
; hh
++) {
6695 for (ww
= 0; ww
< elementsPerLine
; ww
++) {
6697 float extractComponents
[4];
6700 case GL_UNSIGNED_BYTE
:
6704 *iter2
++ = (*iter
) * 257;
6709 *iter2
++ = *((const GLbyte
*) iter
);
6712 *iter2
++ = (*((const GLbyte
*) iter
)) * 516;
6715 case GL_UNSIGNED_BYTE_3_3_2
:
6716 extract332(0,iter
,extractComponents
);
6717 for (k
= 0; k
< 3; k
++) {
6718 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6721 case GL_UNSIGNED_BYTE_2_3_3_REV
:
6722 extract233rev(0,iter
,extractComponents
);
6723 for (k
= 0; k
< 3; k
++) {
6724 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6727 case GL_UNSIGNED_SHORT_5_6_5
:
6728 extract565(myswapBytes
,iter
,extractComponents
);
6729 for (k
= 0; k
< 3; k
++) {
6730 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6733 case GL_UNSIGNED_SHORT_5_6_5_REV
:
6734 extract565rev(myswapBytes
,iter
,extractComponents
);
6735 for (k
= 0; k
< 3; k
++) {
6736 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6739 case GL_UNSIGNED_SHORT_4_4_4_4
:
6740 extract4444(myswapBytes
,iter
,extractComponents
);
6741 for (k
= 0; k
< 4; k
++) {
6742 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6745 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
6746 extract4444rev(myswapBytes
,iter
,extractComponents
);
6747 for (k
= 0; k
< 4; k
++) {
6748 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6751 case GL_UNSIGNED_SHORT_5_5_5_1
:
6752 extract5551(myswapBytes
,iter
,extractComponents
);
6753 for (k
= 0; k
< 4; k
++) {
6754 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6757 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
6758 extract1555rev(myswapBytes
,iter
,extractComponents
);
6759 for (k
= 0; k
< 4; k
++) {
6760 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6763 case GL_UNSIGNED_SHORT
:
6766 widget
.ub
[0] = iter
[1];
6767 widget
.ub
[1] = iter
[0];
6769 widget
.ub
[0] = iter
[0];
6770 widget
.ub
[1] = iter
[1];
6772 if (type
== GL_SHORT
) {
6774 *iter2
++ = widget
.s
[0];
6777 *iter2
++ = widget
.s
[0]*2;
6780 *iter2
++ = widget
.us
[0];
6783 case GL_UNSIGNED_INT_8_8_8_8
:
6784 extract8888(myswapBytes
,iter
,extractComponents
);
6785 for (k
= 0; k
< 4; k
++) {
6786 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6789 case GL_UNSIGNED_INT_8_8_8_8_REV
:
6790 extract8888rev(myswapBytes
,iter
,extractComponents
);
6791 for (k
= 0; k
< 4; k
++) {
6792 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6795 case GL_UNSIGNED_INT_10_10_10_2
:
6796 extract1010102(myswapBytes
,iter
,extractComponents
);
6797 for (k
= 0; k
< 4; k
++) {
6798 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6801 case GL_UNSIGNED_INT_2_10_10_10_REV
:
6802 extract2101010rev(myswapBytes
,iter
,extractComponents
);
6803 for (k
= 0; k
< 4; k
++) {
6804 *iter2
++ = (GLushort
)(extractComponents
[k
]*65535);
6808 case GL_UNSIGNED_INT
:
6811 widget
.ub
[0] = iter
[3];
6812 widget
.ub
[1] = iter
[2];
6813 widget
.ub
[2] = iter
[1];
6814 widget
.ub
[3] = iter
[0];
6816 widget
.ub
[0] = iter
[0];
6817 widget
.ub
[1] = iter
[1];
6818 widget
.ub
[2] = iter
[2];
6819 widget
.ub
[3] = iter
[3];
6821 if (type
== GL_FLOAT
) {
6823 *iter2
++ = widget
.f
;
6825 *iter2
++ = 65535 * widget
.f
;
6827 } else if (type
== GL_UNSIGNED_INT
) {
6829 *iter2
++ = widget
.ui
;
6831 *iter2
++ = widget
.ui
>> 16;
6835 *iter2
++ = widget
.i
;
6837 *iter2
++ = widget
.i
>> 15;
6849 iter
= rowStart
; /* for assertion purposes */
6855 /* iterators should be one byte past end */
6856 if (!isTypePackedPixel(type
)) {
6857 assert(iter2
== &newImage
[width
*height
*depth
*components
]);
6860 assert(iter2
== &newImage
[width
*height
*depth
*
6861 elements_per_group(format
,0)]);
6863 assert( iter
== &((const GLubyte
*)userImage
)[rowSize
*height
*depth
+
6864 psm
->unpack_skip_rows
* rowSize
+
6865 psm
->unpack_skip_pixels
* groupSize
+
6867 psm
->unpack_skip_images
* imageSize
] );
6868 } /* fillImage3D () */
6870 static void scaleInternal3D(GLint components
,
6871 GLint widthIn
, GLint heightIn
, GLint depthIn
,
6872 const GLushort
*dataIn
,
6873 GLint widthOut
, GLint heightOut
, GLint depthOut
,
6876 float x
, lowx
, highx
, convx
, halfconvx
;
6877 float y
, lowy
, highy
, convy
, halfconvy
;
6878 float z
, lowz
, highz
, convz
, halfconvz
;
6879 float xpercent
,ypercent
,zpercent
;
6881 /* Max components in a format is 4, so... */
6884 int i
,j
,d
,k
,zint
,yint
,xint
,xindex
,yindex
,zindex
;
6887 convz
= (float) depthIn
/depthOut
;
6888 convy
= (float) heightIn
/heightOut
;
6889 convx
= (float) widthIn
/widthOut
;
6890 halfconvx
= convx
/2;
6891 halfconvy
= convy
/2;
6892 halfconvz
= convz
/2;
6893 for (d
= 0; d
< depthOut
; d
++) {
6894 z
= convz
* (d
+0.5);
6895 if (depthIn
> depthOut
) {
6896 highz
= z
+ halfconvz
;
6897 lowz
= z
- halfconvz
;
6902 for (i
= 0; i
< heightOut
; i
++) {
6903 y
= convy
* (i
+0.5);
6904 if (heightIn
> heightOut
) {
6905 highy
= y
+ halfconvy
;
6906 lowy
= y
- halfconvy
;
6911 for (j
= 0; j
< widthOut
; j
++) {
6912 x
= convx
* (j
+0.5);
6913 if (widthIn
> widthOut
) {
6914 highx
= x
+ halfconvx
;
6915 lowx
= x
- halfconvx
;
6922 ** Ok, now apply box filter to box that goes from (lowx, lowy,
6923 ** lowz) to (highx, highy, highz) on input data into this pixel
6926 totals
[0] = totals
[1] = totals
[2] = totals
[3] = 0.0;
6932 zindex
= (zint
+ depthIn
) % depthIn
;
6933 if (highz
< zint
+1) {
6934 zpercent
= highz
- z
;
6936 zpercent
= zint
+1 - z
;
6942 yindex
= (yint
+ heightIn
) % heightIn
;
6943 if (highy
< yint
+1) {
6944 ypercent
= highy
- y
;
6946 ypercent
= yint
+1 - y
;
6953 xindex
= (xint
+ widthIn
) % widthIn
;
6954 if (highx
< xint
+1) {
6955 xpercent
= highx
- x
;
6957 xpercent
= xint
+1 - x
;
6960 percent
= xpercent
* ypercent
* zpercent
;
6963 temp
= (xindex
+ (yindex
*widthIn
) +
6964 (zindex
*widthIn
*heightIn
)) * components
;
6965 for (k
= 0; k
< components
; k
++) {
6966 assert(0 <= (temp
+k
) &&
6968 (widthIn
*heightIn
*depthIn
*components
));
6969 totals
[k
] += dataIn
[temp
+ k
] * percent
;
6984 temp
= (j
+ (i
* widthOut
) +
6985 (d
*widthOut
*heightOut
)) * components
;
6986 for (k
= 0; k
< components
; k
++) {
6987 /* totals[] should be rounded in the case of enlarging an
6988 * RGB ramp when the type is 332 or 4444
6990 assert(0 <= (temp
+k
) &&
6991 (temp
+k
) < (widthOut
*heightOut
*depthOut
*components
));
6992 dataOut
[temp
+ k
] = (totals
[k
]+0.5)/volume
;
6997 } /* scaleInternal3D() */
6999 static void emptyImage3D(const PixelStorageModes
*psm
,
7000 GLint width
, GLint height
, GLint depth
,
7001 GLenum format
, GLenum type
, GLboolean indexFormat
,
7002 const GLushort
*oldImage
, void *userImage
)
7011 GLubyte
*start
, *rowStart
, *iter
;
7012 int elementsPerLine
;
7013 const GLushort
*iter2
;
7018 myswapBytes
= psm
->pack_swap_bytes
;
7019 components
= elements_per_group(format
,type
);
7020 if (psm
->pack_row_length
> 0) {
7021 groupsPerLine
= psm
->pack_row_length
;
7024 groupsPerLine
= width
;
7027 elementSize
= bytes_per_element(type
);
7028 groupSize
= elementSize
* components
;
7029 if (elementSize
== 1) myswapBytes
= 0;
7032 if (psm
->pack_image_height
> 0) {
7033 rowsPerImage
= psm
->pack_image_height
;
7036 rowsPerImage
= height
;
7041 rowSize
= groupsPerLine
* groupSize
;
7042 padding
= rowSize
% psm
->pack_alignment
;
7044 rowSize
+= psm
->pack_alignment
- padding
;
7047 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7049 start
= (GLubyte
*)userImage
+ psm
->pack_skip_rows
* rowSize
+
7050 psm
->pack_skip_pixels
* groupSize
+
7052 psm
->pack_skip_images
* imageSize
;
7053 elementsPerLine
= width
* components
;
7056 for (dd
= 0; dd
< depth
; dd
++) {
7059 for (ii
= 0; ii
< height
; ii
++) {
7062 for (jj
= 0; jj
< elementsPerLine
; jj
++) {
7064 float shoveComponents
[4];
7067 case GL_UNSIGNED_BYTE
:
7071 *iter
= *iter2
++ >> 8;
7076 *((GLbyte
*) iter
) = *iter2
++;
7078 *((GLbyte
*) iter
) = *iter2
++ >> 9;
7081 case GL_UNSIGNED_BYTE_3_3_2
:
7082 for (k
= 0; k
< 3; k
++) {
7083 shoveComponents
[k
]= *iter2
++ / 65535.0;
7085 shove332(shoveComponents
,0,(void *)iter
);
7087 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7088 for (k
= 0; k
< 3; k
++) {
7089 shoveComponents
[k
]= *iter2
++ / 65535.0;
7091 shove233rev(shoveComponents
,0,(void *)iter
);
7093 case GL_UNSIGNED_SHORT_5_6_5
:
7094 for (k
= 0; k
< 3; k
++) {
7095 shoveComponents
[k
]= *iter2
++ / 65535.0;
7097 shove565(shoveComponents
,0,(void *)&widget
.us
[0]);
7099 iter
[0] = widget
.ub
[1];
7100 iter
[1] = widget
.ub
[0];
7103 *(GLushort
*)iter
= widget
.us
[0];
7106 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7107 for (k
= 0; k
< 3; k
++) {
7108 shoveComponents
[k
]= *iter2
++ / 65535.0;
7110 shove565rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7112 iter
[0] = widget
.ub
[1];
7113 iter
[1] = widget
.ub
[0];
7116 *(GLushort
*)iter
= widget
.us
[0];
7119 case GL_UNSIGNED_SHORT_4_4_4_4
:
7120 for (k
= 0; k
< 4; k
++) {
7121 shoveComponents
[k
]= *iter2
++ / 65535.0;
7123 shove4444(shoveComponents
,0,(void *)&widget
.us
[0]);
7125 iter
[0] = widget
.ub
[1];
7126 iter
[1] = widget
.ub
[0];
7128 *(GLushort
*)iter
= widget
.us
[0];
7131 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7132 for (k
= 0; k
< 4; k
++) {
7133 shoveComponents
[k
]= *iter2
++ / 65535.0;
7135 shove4444rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7137 iter
[0] = widget
.ub
[1];
7138 iter
[1] = widget
.ub
[0];
7140 *(GLushort
*)iter
= widget
.us
[0];
7143 case GL_UNSIGNED_SHORT_5_5_5_1
:
7144 for (k
= 0; k
< 4; k
++) {
7145 shoveComponents
[k
]= *iter2
++ / 65535.0;
7147 shove5551(shoveComponents
,0,(void *)&widget
.us
[0]);
7149 iter
[0] = widget
.ub
[1];
7150 iter
[1] = widget
.ub
[0];
7152 *(GLushort
*)iter
= widget
.us
[0];
7155 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7156 for (k
= 0; k
< 4; k
++) {
7157 shoveComponents
[k
]= *iter2
++ / 65535.0;
7159 shove1555rev(shoveComponents
,0,(void *)&widget
.us
[0]);
7161 iter
[0] = widget
.ub
[1];
7162 iter
[1] = widget
.ub
[0];
7164 *(GLushort
*)iter
= widget
.us
[0];
7167 case GL_UNSIGNED_SHORT
:
7169 if (type
== GL_SHORT
) {
7171 widget
.s
[0] = *iter2
++;
7173 widget
.s
[0] = *iter2
++ >> 1;
7176 widget
.us
[0] = *iter2
++;
7179 iter
[0] = widget
.ub
[1];
7180 iter
[1] = widget
.ub
[0];
7182 iter
[0] = widget
.ub
[0];
7183 iter
[1] = widget
.ub
[1];
7186 case GL_UNSIGNED_INT_8_8_8_8
:
7187 for (k
= 0; k
< 4; k
++) {
7188 shoveComponents
[k
]= *iter2
++ / 65535.0;
7190 shove8888(shoveComponents
,0,(void *)&widget
.ui
);
7192 iter
[3] = widget
.ub
[0];
7193 iter
[2] = widget
.ub
[1];
7194 iter
[1] = widget
.ub
[2];
7195 iter
[0] = widget
.ub
[3];
7197 *(GLuint
*)iter
= widget
.ui
;
7200 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7201 for (k
= 0; k
< 4; k
++) {
7202 shoveComponents
[k
]= *iter2
++ / 65535.0;
7204 shove8888rev(shoveComponents
,0,(void *)&widget
.ui
);
7206 iter
[3] = widget
.ub
[0];
7207 iter
[2] = widget
.ub
[1];
7208 iter
[1] = widget
.ub
[2];
7209 iter
[0] = widget
.ub
[3];
7211 *(GLuint
*)iter
= widget
.ui
;
7214 case GL_UNSIGNED_INT_10_10_10_2
:
7215 for (k
= 0; k
< 4; k
++) {
7216 shoveComponents
[k
]= *iter2
++ / 65535.0;
7218 shove1010102(shoveComponents
,0,(void *)&widget
.ui
);
7220 iter
[3] = widget
.ub
[0];
7221 iter
[2] = widget
.ub
[1];
7222 iter
[1] = widget
.ub
[2];
7223 iter
[0] = widget
.ub
[3];
7225 *(GLuint
*)iter
= widget
.ui
;
7228 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7229 for (k
= 0; k
< 4; k
++) {
7230 shoveComponents
[k
]= *iter2
++ / 65535.0;
7232 shove2101010rev(shoveComponents
,0,(void *)&widget
.ui
);
7234 iter
[3] = widget
.ub
[0];
7235 iter
[2] = widget
.ub
[1];
7236 iter
[1] = widget
.ub
[2];
7237 iter
[0] = widget
.ub
[3];
7239 *(GLuint
*)iter
= widget
.ui
;
7243 case GL_UNSIGNED_INT
:
7245 if (type
== GL_FLOAT
) {
7247 widget
.f
= *iter2
++;
7249 widget
.f
= *iter2
++ / (float) 65535.0;
7251 } else if (type
== GL_UNSIGNED_INT
) {
7253 widget
.ui
= *iter2
++;
7255 widget
.ui
= (unsigned int) *iter2
++ * 65537;
7259 widget
.i
= *iter2
++;
7261 widget
.i
= ((unsigned int) *iter2
++ * 65537)/2;
7265 iter
[3] = widget
.ub
[0];
7266 iter
[2] = widget
.ub
[1];
7267 iter
[1] = widget
.ub
[2];
7268 iter
[0] = widget
.ub
[3];
7270 iter
[0] = widget
.ub
[0];
7271 iter
[1] = widget
.ub
[1];
7272 iter
[2] = widget
.ub
[2];
7273 iter
[3] = widget
.ub
[3];
7289 /* iterators should be one byte past end */
7290 if (!isTypePackedPixel(type
)) {
7291 assert(iter2
== &oldImage
[width
*height
*depth
*components
]);
7294 assert(iter2
== &oldImage
[width
*height
*depth
*
7295 elements_per_group(format
,0)]);
7297 assert( iter
== &((GLubyte
*)userImage
)[rowSize
*height
*depth
+
7298 psm
->unpack_skip_rows
* rowSize
+
7299 psm
->unpack_skip_pixels
* groupSize
+
7301 psm
->unpack_skip_images
* imageSize
] );
7302 } /* emptyImage3D() */
7305 int gluScaleImage3D(GLenum format
,
7306 GLint widthIn
, GLint heightIn
, GLint depthIn
,
7307 GLenum typeIn
, const void *dataIn
,
7308 GLint widthOut
, GLint heightOut
, GLint depthOut
,
7309 GLenum typeOut
, void *dataOut
)
7312 GLushort
*beforeImage
, *afterImage
;
7313 PixelStorageModes psm
;
7315 if (widthIn
== 0 || heightIn
== 0 || depthIn
== 0 ||
7316 widthOut
== 0 || heightOut
== 0 || depthOut
== 0) {
7320 if (widthIn
< 0 || heightIn
< 0 || depthIn
< 0 ||
7321 widthOut
< 0 || heightOut
< 0 || depthOut
< 0) {
7322 return GLU_INVALID_VALUE
;
7325 if (!legalFormat(format
) || !legalType(typeIn
) || !legalType(typeOut
) ||
7326 typeIn
== GL_BITMAP
|| typeOut
== GL_BITMAP
) {
7327 return GLU_INVALID_ENUM
;
7329 if (!isLegalFormatForPackedPixelType(format
, typeIn
)) {
7330 return GLU_INVALID_OPERATION
;
7332 if (!isLegalFormatForPackedPixelType(format
, typeOut
)) {
7333 return GLU_INVALID_OPERATION
;
7336 beforeImage
= malloc(imageSize3D(widthIn
, heightIn
, depthIn
, format
,
7337 GL_UNSIGNED_SHORT
));
7338 afterImage
= malloc(imageSize3D(widthOut
, heightOut
, depthOut
, format
,
7339 GL_UNSIGNED_SHORT
));
7340 if (beforeImage
== NULL
|| afterImage
== NULL
) {
7341 return GLU_OUT_OF_MEMORY
;
7343 retrieveStoreModes3D(&psm
);
7345 fillImage3D(&psm
,widthIn
,heightIn
,depthIn
,format
,typeIn
, is_index(format
),
7346 dataIn
, beforeImage
);
7347 components
= elements_per_group(format
,0);
7348 scaleInternal3D(components
,widthIn
,heightIn
,depthIn
,beforeImage
,
7349 widthOut
,heightOut
,depthOut
,afterImage
);
7350 emptyImage3D(&psm
,widthOut
,heightOut
,depthOut
,format
,typeOut
,
7351 is_index(format
),afterImage
, dataOut
);
7352 free((void *) beforeImage
);
7353 free((void *) afterImage
);
7356 } /* gluScaleImage3D() */
7359 static void closestFit3D(GLenum target
, GLint width
, GLint height
, GLint depth
,
7360 GLint internalFormat
, GLenum format
, GLenum type
,
7361 GLint
*newWidth
, GLint
*newHeight
, GLint
*newDepth
)
7363 GLint widthPowerOf2
= nearestPower(width
);
7364 GLint heightPowerOf2
= nearestPower(height
);
7365 GLint depthPowerOf2
= nearestPower(depth
);
7369 /* compute level 1 width & height & depth, clamping each at 1 */
7370 GLint widthAtLevelOne
= (widthPowerOf2
> 1) ?
7371 widthPowerOf2
>> 1 :
7373 GLint heightAtLevelOne
= (heightPowerOf2
> 1) ?
7374 heightPowerOf2
>> 1 :
7376 GLint depthAtLevelOne
= (depthPowerOf2
> 1) ?
7377 depthPowerOf2
>> 1 :
7380 assert(widthAtLevelOne
> 0);
7381 assert(heightAtLevelOne
> 0);
7382 assert(depthAtLevelOne
> 0);
7384 /* does width x height x depth at level 1 & all their mipmaps fit? */
7385 if (target
== GL_TEXTURE_3D
|| target
== GL_PROXY_TEXTURE_3D
) {
7386 proxyTarget
= GL_PROXY_TEXTURE_3D
;
7387 gluTexImage3D(proxyTarget
, 1, /* must be non-zero */
7389 widthAtLevelOne
,heightAtLevelOne
,depthAtLevelOne
,
7390 0,format
,type
,NULL
);
7392 glGetTexLevelParameteriv(proxyTarget
, 1,GL_TEXTURE_WIDTH
,&proxyWidth
);
7393 /* does it fit??? */
7394 if (proxyWidth
== 0) { /* nope, so try again with these sizes */
7395 if (widthPowerOf2
== 1 && heightPowerOf2
== 1 &&
7396 depthPowerOf2
== 1) {
7397 *newWidth
= *newHeight
= *newDepth
= 1; /* must fit 1x1x1 texture */
7400 widthPowerOf2
= widthAtLevelOne
;
7401 heightPowerOf2
= heightAtLevelOne
;
7402 depthPowerOf2
= depthAtLevelOne
;
7404 /* else it does fit */
7405 } while (proxyWidth
== 0);
7406 /* loop must terminate! */
7408 /* return the width & height at level 0 that fits */
7409 *newWidth
= widthPowerOf2
;
7410 *newHeight
= heightPowerOf2
;
7411 *newDepth
= depthPowerOf2
;
7412 /*printf("Proxy Textures\n");*/
7413 } /* closestFit3D() */
7415 static void halveImagePackedPixelSlice(int components
,
7416 void (*extractPackedPixel
)
7417 (int, const void *,GLfloat
[]),
7418 void (*shovePackedPixel
)
7419 (const GLfloat
[],int, void *),
7420 GLint width
, GLint height
, GLint depth
,
7421 const void *dataIn
, void *dataOut
,
7422 GLint pixelSizeInBytes
,
7423 GLint rowSizeInBytes
,
7424 GLint imageSizeInBytes
,
7428 int halfWidth
= width
/ 2;
7429 int halfHeight
= height
/ 2;
7430 int halfDepth
= depth
/ 2;
7431 const char *src
= (const char *)dataIn
;
7434 assert((width
== 1 || height
== 1) && depth
>= 2);
7436 if (width
== height
) { /* a 1-pixel column viewed from top */
7437 assert(width
== 1 && height
== 1);
7440 for (ii
= 0; ii
< halfDepth
; ii
++) {
7442 float extractTotals
[BOX2
][4];
7445 (*extractPackedPixel
)(isSwap
,src
,&extractTotals
[0][0]);
7446 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7447 &extractTotals
[1][0]);
7448 for (cc
= 0; cc
< components
; cc
++) {
7451 /* average 2 pixels since only a column */
7453 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
7454 * totals[RED]/= 2.0;
7456 for (kk
= 0; kk
< BOX2
; kk
++) {
7457 totals
[cc
]+= extractTotals
[kk
][cc
];
7459 totals
[cc
]/= (float)BOX2
;
7462 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7464 /* skip over to next group of 2 */
7465 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7468 else if (height
== 1) { /* horizontal slice viewed from top */
7471 for (ii
= 0; ii
< halfDepth
; ii
++) {
7472 for (jj
= 0; jj
< halfWidth
; jj
++) {
7474 float extractTotals
[BOX4
][4];
7477 (*extractPackedPixel
)(isSwap
,src
,
7478 &extractTotals
[0][0]);
7479 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7480 &extractTotals
[1][0]);
7481 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7482 &extractTotals
[2][0]);
7483 (*extractPackedPixel
)(isSwap
,
7484 (src
+imageSizeInBytes
+pixelSizeInBytes
),
7485 &extractTotals
[3][0]);
7486 for (cc
= 0; cc
< components
; cc
++) {
7489 /* grab 4 pixels to average */
7491 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7492 * extractTotals[2][RED]+extractTotals[3][RED];
7493 * totals[RED]/= 4.0;
7495 for (kk
= 0; kk
< BOX4
; kk
++) {
7496 totals
[cc
]+= extractTotals
[kk
][cc
];
7498 totals
[cc
]/= (float)BOX4
;
7500 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7503 /* skip over to next horizontal square of 4 */
7504 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7510 else if (width
== 1) { /* vertical slice viewed from top */
7511 assert(height
!= 1);
7513 for (ii
= 0; ii
< halfDepth
; ii
++) {
7514 for (jj
= 0; jj
< halfHeight
; jj
++) {
7516 float extractTotals
[BOX4
][4];
7519 (*extractPackedPixel
)(isSwap
,src
,
7520 &extractTotals
[0][0]);
7521 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7522 &extractTotals
[1][0]);
7523 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7524 &extractTotals
[2][0]);
7525 (*extractPackedPixel
)(isSwap
,
7526 (src
+imageSizeInBytes
+rowSizeInBytes
),
7527 &extractTotals
[3][0]);
7528 for (cc
= 0; cc
< components
; cc
++) {
7531 /* grab 4 pixels to average */
7533 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7534 * extractTotals[2][RED]+extractTotals[3][RED];
7535 * totals[RED]/= 4.0;
7537 for (kk
= 0; kk
< BOX4
; kk
++) {
7538 totals
[cc
]+= extractTotals
[kk
][cc
];
7540 totals
[cc
]/= (float)BOX4
;
7542 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7546 /* skip over to next vertical square of 4 */
7547 src
+= imageSizeInBytes
+ imageSizeInBytes
;
7553 } /* halveImagePackedPixelSlice() */
7555 static void halveImagePackedPixel3D(int components
,
7556 void (*extractPackedPixel
)
7557 (int, const void *,GLfloat
[]),
7558 void (*shovePackedPixel
)
7559 (const GLfloat
[],int, void *),
7560 GLint width
, GLint height
, GLint depth
,
7561 const void *dataIn
, void *dataOut
,
7562 GLint pixelSizeInBytes
,
7563 GLint rowSizeInBytes
,
7564 GLint imageSizeInBytes
,
7568 assert(1 <= width
&& 1 <= height
);
7570 halveImagePackedPixel(components
,extractPackedPixel
,shovePackedPixel
,
7571 width
,height
,dataIn
,dataOut
,pixelSizeInBytes
,
7572 rowSizeInBytes
,isSwap
);
7575 /* a horizontal or vertical slice viewed from top */
7576 else if (width
== 1 || height
== 1) {
7579 halveImagePackedPixelSlice(components
,
7580 extractPackedPixel
,shovePackedPixel
,
7581 width
, height
, depth
, dataIn
, dataOut
,
7582 pixelSizeInBytes
, rowSizeInBytes
,
7583 imageSizeInBytes
, isSwap
);
7589 int halfWidth
= width
/ 2;
7590 int halfHeight
= height
/ 2;
7591 int halfDepth
= depth
/ 2;
7592 const char *src
= (const char *) dataIn
;
7593 int padBytes
= rowSizeInBytes
- (width
*pixelSizeInBytes
);
7596 for (dd
= 0; dd
< halfDepth
; dd
++) {
7597 for (ii
= 0; ii
< halfHeight
; ii
++) {
7598 for (jj
= 0; jj
< halfWidth
; jj
++) {
7600 float totals
[4]; /* 4 is maximum components */
7601 float extractTotals
[BOX8
][4]; /* 4 is maximum components */
7604 (*extractPackedPixel
)(isSwap
,src
,
7605 &extractTotals
[0][0]);
7606 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
),
7607 &extractTotals
[1][0]);
7608 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
),
7609 &extractTotals
[2][0]);
7610 (*extractPackedPixel
)(isSwap
,
7611 (src
+rowSizeInBytes
+pixelSizeInBytes
),
7612 &extractTotals
[3][0]);
7614 (*extractPackedPixel
)(isSwap
,(src
+imageSizeInBytes
),
7615 &extractTotals
[4][0]);
7616 (*extractPackedPixel
)(isSwap
,(src
+pixelSizeInBytes
+imageSizeInBytes
),
7617 &extractTotals
[5][0]);
7618 (*extractPackedPixel
)(isSwap
,(src
+rowSizeInBytes
+imageSizeInBytes
),
7619 &extractTotals
[6][0]);
7620 (*extractPackedPixel
)(isSwap
,
7621 (src
+rowSizeInBytes
+pixelSizeInBytes
+imageSizeInBytes
),
7622 &extractTotals
[7][0]);
7623 for (cc
= 0; cc
< components
; cc
++) {
7626 /* grab 8 pixels to average */
7628 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
7629 * extractTotals[2][RED]+extractTotals[3][RED]+
7630 * extractTotals[4][RED]+extractTotals[5][RED]+
7631 * extractTotals[6][RED]+extractTotals[7][RED];
7632 * totals[RED]/= 8.0;
7634 for (kk
= 0; kk
< BOX8
; kk
++) {
7635 totals
[cc
]+= extractTotals
[kk
][cc
];
7637 totals
[cc
]/= (float)BOX8
;
7639 (*shovePackedPixel
)(totals
,outIndex
,dataOut
);
7642 /* skip over to next square of 4 */
7643 src
+= pixelSizeInBytes
+ pixelSizeInBytes
;
7645 /* skip past pad bytes, if any, to get to next row */
7648 /* src is at beginning of a row here, but it's the second row of
7649 * the square block of 4 pixels that we just worked on so we
7650 * need to go one more row.
7658 src
+= rowSizeInBytes
;
7661 src
+= imageSizeInBytes
;
7664 /* both pointers must reach one byte after the end */
7665 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
7666 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
);
7669 } /* halveImagePackedPixel3D() */
7671 static int gluBuild3DMipmapLevelsCore(GLenum target
, GLint internalFormat
,
7675 GLsizei widthPowerOf2
,
7676 GLsizei heightPowerOf2
,
7677 GLsizei depthPowerOf2
,
7678 GLenum format
, GLenum type
,
7680 GLint baseLevel
,GLint maxLevel
,
7683 GLint newWidth
, newHeight
, newDepth
;
7684 GLint level
, levels
;
7685 const void *usersImage
;
7686 void *srcImage
, *dstImage
;
7687 __GLU_INIT_SWAP_IMAGE
;
7691 GLint myswapBytes
, groupsPerLine
, elementSize
, groupSize
;
7692 GLint rowsPerImage
, imageSize
;
7693 GLint rowSize
, padding
;
7694 PixelStorageModes psm
;
7696 assert(checkMipmapArgs(internalFormat
,format
,type
) == 0);
7697 assert(width
>= 1 && height
>= 1 && depth
>= 1);
7698 assert(type
!= GL_BITMAP
);
7700 srcImage
= dstImage
= NULL
;
7702 newWidth
= widthPowerOf2
;
7703 newHeight
= heightPowerOf2
;
7704 newDepth
= depthPowerOf2
;
7705 levels
= computeLog(newWidth
);
7706 level
= computeLog(newHeight
);
7707 if (level
> levels
) levels
=level
;
7708 level
= computeLog(newDepth
);
7709 if (level
> levels
) levels
=level
;
7713 retrieveStoreModes3D(&psm
);
7714 myswapBytes
= psm
.unpack_swap_bytes
;
7715 cmpts
= elements_per_group(format
,type
);
7716 if (psm
.unpack_row_length
> 0) {
7717 groupsPerLine
= psm
.unpack_row_length
;
7719 groupsPerLine
= width
;
7722 elementSize
= bytes_per_element(type
);
7723 groupSize
= elementSize
* cmpts
;
7724 if (elementSize
== 1) myswapBytes
= 0;
7727 if (psm
.unpack_image_height
> 0) {
7728 rowsPerImage
= psm
.unpack_image_height
;
7731 rowsPerImage
= height
;
7735 rowSize
= groupsPerLine
* groupSize
;
7736 padding
= (rowSize
% psm
.unpack_alignment
);
7738 rowSize
+= psm
.unpack_alignment
- padding
;
7741 imageSize
= rowsPerImage
* rowSize
; /* 3dstuff */
7743 usersImage
= (const GLubyte
*)data
+ psm
.unpack_skip_rows
* rowSize
+
7744 psm
.unpack_skip_pixels
* groupSize
+
7746 psm
.unpack_skip_images
* imageSize
;
7748 glPixelStorei(GL_UNPACK_SKIP_ROWS
, 0);
7749 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, 0);
7750 glPixelStorei(GL_UNPACK_ROW_LENGTH
, 0);
7751 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, 0);
7752 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, 0);
7756 if (width
== newWidth
&& height
== newHeight
&& depth
== newDepth
) {
7757 /* Use usersImage for level userLevel */
7758 if (baseLevel
<= level
&& level
<= maxLevel
) {
7759 gluTexImage3D(target
, level
, internalFormat
, width
,
7760 height
, depth
, 0, format
, type
,
7763 if(levels
== 0) { /* we're done. clean up and return */
7764 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7765 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7766 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7767 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7768 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7769 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7770 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7774 int nextWidth
= newWidth
/2;
7775 int nextHeight
= newHeight
/2;
7776 int nextDepth
= newDepth
/2;
7779 if (nextWidth
< 1) nextWidth
= 1;
7780 if (nextHeight
< 1) nextHeight
= 1;
7781 if (nextDepth
< 1) nextDepth
= 1;
7782 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
7785 case GL_UNSIGNED_BYTE
:
7786 dstImage
= (GLubyte
*)malloc(memReq
);
7789 dstImage
= (GLbyte
*)malloc(memReq
);
7791 case GL_UNSIGNED_SHORT
:
7792 dstImage
= (GLushort
*)malloc(memReq
);
7795 dstImage
= (GLshort
*)malloc(memReq
);
7797 case GL_UNSIGNED_INT
:
7798 dstImage
= (GLuint
*)malloc(memReq
);
7801 dstImage
= (GLint
*)malloc(memReq
);
7804 dstImage
= (GLfloat
*)malloc(memReq
);
7806 case GL_UNSIGNED_BYTE_3_3_2
:
7807 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7808 dstImage
= (GLubyte
*)malloc(memReq
);
7810 case GL_UNSIGNED_SHORT_5_6_5
:
7811 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7812 case GL_UNSIGNED_SHORT_4_4_4_4
:
7813 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7814 case GL_UNSIGNED_SHORT_5_5_5_1
:
7815 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7816 dstImage
= (GLushort
*)malloc(memReq
);
7818 case GL_UNSIGNED_INT_8_8_8_8
:
7819 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7820 case GL_UNSIGNED_INT_10_10_10_2
:
7821 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7822 dstImage
= (GLuint
*)malloc(memReq
);
7825 return GLU_INVALID_ENUM
; /* assertion */
7827 if (dstImage
== NULL
) {
7828 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
7829 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
7830 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
7831 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
7832 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
7833 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
7834 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
7835 return GLU_OUT_OF_MEMORY
;
7839 case GL_UNSIGNED_BYTE
:
7841 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
7843 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7844 imageSize
,myswapBytes
);
7847 halveImage_ubyte(cmpts
,width
,height
,usersImage
,dstImage
,
7848 elementSize
,rowSize
,groupSize
);
7853 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
7855 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7856 imageSize
,myswapBytes
);
7859 halveImage_byte(cmpts
,width
,height
,usersImage
,dstImage
,
7860 elementSize
,rowSize
,groupSize
);
7863 case GL_UNSIGNED_SHORT
:
7865 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
7867 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7868 imageSize
,myswapBytes
);
7871 halveImage_ushort(cmpts
,width
,height
,usersImage
,dstImage
,
7872 elementSize
,rowSize
,groupSize
,myswapBytes
);
7877 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
7879 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7880 imageSize
,myswapBytes
);
7883 halveImage_short(cmpts
,width
,height
,usersImage
,dstImage
,
7884 elementSize
,rowSize
,groupSize
,myswapBytes
);
7887 case GL_UNSIGNED_INT
:
7889 halveImage3D(cmpts
,extractUint
,shoveUint
,
7891 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7892 imageSize
,myswapBytes
);
7895 halveImage_uint(cmpts
,width
,height
,usersImage
,dstImage
,
7896 elementSize
,rowSize
,groupSize
,myswapBytes
);
7901 halveImage3D(cmpts
,extractSint
,shoveSint
,
7903 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7904 imageSize
,myswapBytes
);
7907 halveImage_int(cmpts
,width
,height
,usersImage
,dstImage
,
7908 elementSize
,rowSize
,groupSize
,myswapBytes
);
7913 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
7915 usersImage
,dstImage
,elementSize
,groupSize
,rowSize
,
7916 imageSize
,myswapBytes
);
7919 halveImage_float(cmpts
,width
,height
,usersImage
,dstImage
,
7920 elementSize
,rowSize
,groupSize
,myswapBytes
);
7923 case GL_UNSIGNED_BYTE_3_3_2
:
7924 assert(format
== GL_RGB
);
7925 halveImagePackedPixel3D(3,extract332
,shove332
,
7926 width
,height
,depth
,usersImage
,dstImage
,
7927 elementSize
,rowSize
,imageSize
,myswapBytes
);
7929 case GL_UNSIGNED_BYTE_2_3_3_REV
:
7930 assert(format
== GL_RGB
);
7931 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
7932 width
,height
,depth
,usersImage
,dstImage
,
7933 elementSize
,rowSize
,imageSize
,myswapBytes
);
7935 case GL_UNSIGNED_SHORT_5_6_5
:
7936 halveImagePackedPixel3D(3,extract565
,shove565
,
7937 width
,height
,depth
,usersImage
,dstImage
,
7938 elementSize
,rowSize
,imageSize
,myswapBytes
);
7940 case GL_UNSIGNED_SHORT_5_6_5_REV
:
7941 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
7942 width
,height
,depth
,usersImage
,dstImage
,
7943 elementSize
,rowSize
,imageSize
,myswapBytes
);
7945 case GL_UNSIGNED_SHORT_4_4_4_4
:
7946 halveImagePackedPixel3D(4,extract4444
,shove4444
,
7947 width
,height
,depth
,usersImage
,dstImage
,
7948 elementSize
,rowSize
,imageSize
,myswapBytes
);
7950 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
7951 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
7952 width
,height
,depth
,usersImage
,dstImage
,
7953 elementSize
,rowSize
,imageSize
,myswapBytes
);
7955 case GL_UNSIGNED_SHORT_5_5_5_1
:
7956 halveImagePackedPixel3D(4,extract5551
,shove5551
,
7957 width
,height
,depth
,usersImage
,dstImage
,
7958 elementSize
,rowSize
,imageSize
,myswapBytes
);
7960 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
7961 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
7962 width
,height
,depth
,usersImage
,dstImage
,
7963 elementSize
,rowSize
,imageSize
,myswapBytes
);
7965 case GL_UNSIGNED_INT_8_8_8_8
:
7966 halveImagePackedPixel3D(4,extract8888
,shove8888
,
7967 width
,height
,depth
,usersImage
,dstImage
,
7968 elementSize
,rowSize
,imageSize
,myswapBytes
);
7970 case GL_UNSIGNED_INT_8_8_8_8_REV
:
7971 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
7972 width
,height
,depth
,usersImage
,dstImage
,
7973 elementSize
,rowSize
,imageSize
,myswapBytes
);
7975 case GL_UNSIGNED_INT_10_10_10_2
:
7976 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
7977 width
,height
,depth
,usersImage
,dstImage
,
7978 elementSize
,rowSize
,imageSize
,myswapBytes
);
7980 case GL_UNSIGNED_INT_2_10_10_10_REV
:
7981 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
7982 width
,height
,depth
,usersImage
,dstImage
,
7983 elementSize
,rowSize
,imageSize
,myswapBytes
);
7990 newHeight
= height
/2;
7993 if (newWidth
< 1) newWidth
= 1;
7994 if (newHeight
< 1) newHeight
= 1;
7995 if (newDepth
< 1) newDepth
= 1;
7998 rowSize
= newWidth
* groupSize
;
7999 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8000 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8001 /* Swap srcImage and dstImage */
8002 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8004 case GL_UNSIGNED_BYTE
:
8005 dstImage
= (GLubyte
*)malloc(memReq
);
8008 dstImage
= (GLbyte
*)malloc(memReq
);
8010 case GL_UNSIGNED_SHORT
:
8011 dstImage
= (GLushort
*)malloc(memReq
);
8014 dstImage
= (GLshort
*)malloc(memReq
);
8016 case GL_UNSIGNED_INT
:
8017 dstImage
= (GLuint
*)malloc(memReq
);
8020 dstImage
= (GLint
*)malloc(memReq
);
8023 dstImage
= (GLfloat
*)malloc(memReq
);
8025 case GL_UNSIGNED_BYTE_3_3_2
:
8026 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8027 dstImage
= (GLubyte
*)malloc(memReq
);
8029 case GL_UNSIGNED_SHORT_5_6_5
:
8030 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8031 case GL_UNSIGNED_SHORT_4_4_4_4
:
8032 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8033 case GL_UNSIGNED_SHORT_5_5_5_1
:
8034 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8035 dstImage
= (GLushort
*)malloc(memReq
);
8037 case GL_UNSIGNED_INT_8_8_8_8
:
8038 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8039 case GL_UNSIGNED_INT_10_10_10_2
:
8040 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8041 dstImage
= (GLuint
*)malloc(memReq
);
8044 return GLU_INVALID_ENUM
; /* assertion */
8046 if (dstImage
== NULL
) {
8047 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8048 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8049 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8050 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8051 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8052 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8053 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8054 return GLU_OUT_OF_MEMORY
;
8056 /* level userLevel+1 is in srcImage; level userLevel already saved */
8057 level
= userLevel
+1;
8058 } else {/* user's image is *not* nice power-of-2 sized square */
8059 memReq
= imageSize3D(newWidth
, newHeight
, newDepth
, format
, type
);
8061 case GL_UNSIGNED_BYTE
:
8062 dstImage
= (GLubyte
*)malloc(memReq
);
8065 dstImage
= (GLbyte
*)malloc(memReq
);
8067 case GL_UNSIGNED_SHORT
:
8068 dstImage
= (GLushort
*)malloc(memReq
);
8071 dstImage
= (GLshort
*)malloc(memReq
);
8073 case GL_UNSIGNED_INT
:
8074 dstImage
= (GLuint
*)malloc(memReq
);
8077 dstImage
= (GLint
*)malloc(memReq
);
8080 dstImage
= (GLfloat
*)malloc(memReq
);
8082 case GL_UNSIGNED_BYTE_3_3_2
:
8083 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8084 dstImage
= (GLubyte
*)malloc(memReq
);
8086 case GL_UNSIGNED_SHORT_5_6_5
:
8087 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8088 case GL_UNSIGNED_SHORT_4_4_4_4
:
8089 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8090 case GL_UNSIGNED_SHORT_5_5_5_1
:
8091 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8092 dstImage
= (GLushort
*)malloc(memReq
);
8094 case GL_UNSIGNED_INT_8_8_8_8
:
8095 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8096 case GL_UNSIGNED_INT_10_10_10_2
:
8097 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8098 dstImage
= (GLuint
*)malloc(memReq
);
8101 return GLU_INVALID_ENUM
; /* assertion */
8104 if (dstImage
== NULL
) {
8105 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8106 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8107 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8108 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8109 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8110 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8111 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8112 return GLU_OUT_OF_MEMORY
;
8114 /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
8115 width,height,depth,newWidth,newHeight,newDepth);*/
8117 gluScaleImage3D(format
, width
, height
, depth
, type
, usersImage
,
8118 newWidth
, newHeight
, newDepth
, type
, dstImage
);
8121 rowSize
= newWidth
* groupSize
;
8122 imageSize
= rowSize
* newHeight
; /* 3dstuff */
8123 /* Swap dstImage and srcImage */
8124 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8126 if(levels
!= 0) { /* use as little memory as possible */
8128 int nextWidth
= newWidth
/2;
8129 int nextHeight
= newHeight
/2;
8130 int nextDepth
= newDepth
/2;
8131 if (nextWidth
< 1) nextWidth
= 1;
8132 if (nextHeight
< 1) nextHeight
= 1;
8133 if (nextDepth
< 1) nextDepth
= 1;
8135 memReq
= imageSize3D(nextWidth
, nextHeight
, nextDepth
, format
, type
);
8138 case GL_UNSIGNED_BYTE
:
8139 dstImage
= (GLubyte
*)malloc(memReq
);
8142 dstImage
= (GLbyte
*)malloc(memReq
);
8144 case GL_UNSIGNED_SHORT
:
8145 dstImage
= (GLushort
*)malloc(memReq
);
8148 dstImage
= (GLshort
*)malloc(memReq
);
8150 case GL_UNSIGNED_INT
:
8151 dstImage
= (GLuint
*)malloc(memReq
);
8154 dstImage
= (GLint
*)malloc(memReq
);
8157 dstImage
= (GLfloat
*)malloc(memReq
);
8159 case GL_UNSIGNED_BYTE_3_3_2
:
8160 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8161 dstImage
= (GLubyte
*)malloc(memReq
);
8163 case GL_UNSIGNED_SHORT_5_6_5
:
8164 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8165 case GL_UNSIGNED_SHORT_4_4_4_4
:
8166 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8167 case GL_UNSIGNED_SHORT_5_5_5_1
:
8168 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8169 dstImage
= (GLushort
*)malloc(memReq
);
8171 case GL_UNSIGNED_INT_8_8_8_8
:
8172 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8173 case GL_UNSIGNED_INT_10_10_10_2
:
8174 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8175 dstImage
= (GLuint
*)malloc(memReq
);
8178 return GLU_INVALID_ENUM
; /* assertion */
8180 if (dstImage
== NULL
) {
8181 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8182 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8183 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8184 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8185 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8186 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8187 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8188 return GLU_OUT_OF_MEMORY
;
8191 /* level userLevel is in srcImage; nothing saved yet */
8195 glPixelStorei(GL_UNPACK_SWAP_BYTES
, GL_FALSE
);
8196 if (baseLevel
<= level
&& level
<= maxLevel
) {
8197 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
, newDepth
,
8198 0,format
, type
, (void *)srcImage
);
8200 level
++; /* update current level for the loop */
8201 for (; level
<= levels
; level
++) {
8203 case GL_UNSIGNED_BYTE
:
8205 halveImage3D(cmpts
,extractUbyte
,shoveUbyte
,
8206 newWidth
,newHeight
,newDepth
,
8207 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8208 imageSize
,myswapBytes
);
8211 halveImage_ubyte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8212 elementSize
,rowSize
,groupSize
);
8217 halveImage3D(cmpts
,extractSbyte
,shoveSbyte
,
8218 newWidth
,newHeight
,newDepth
,
8219 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8220 imageSize
,myswapBytes
);
8223 halveImage_byte(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8224 elementSize
,rowSize
,groupSize
);
8227 case GL_UNSIGNED_SHORT
:
8229 halveImage3D(cmpts
,extractUshort
,shoveUshort
,
8230 newWidth
,newHeight
,newDepth
,
8231 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8232 imageSize
,myswapBytes
);
8235 halveImage_ushort(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8236 elementSize
,rowSize
,groupSize
,myswapBytes
);
8241 halveImage3D(cmpts
,extractSshort
,shoveSshort
,
8242 newWidth
,newHeight
,newDepth
,
8243 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8244 imageSize
,myswapBytes
);
8247 halveImage_short(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8248 elementSize
,rowSize
,groupSize
,myswapBytes
);
8251 case GL_UNSIGNED_INT
:
8253 halveImage3D(cmpts
,extractUint
,shoveUint
,
8254 newWidth
,newHeight
,newDepth
,
8255 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8256 imageSize
,myswapBytes
);
8259 halveImage_uint(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8260 elementSize
,rowSize
,groupSize
,myswapBytes
);
8265 halveImage3D(cmpts
,extractSint
,shoveSint
,
8266 newWidth
,newHeight
,newDepth
,
8267 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8268 imageSize
,myswapBytes
);
8271 halveImage_int(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8272 elementSize
,rowSize
,groupSize
,myswapBytes
);
8277 halveImage3D(cmpts
,extractFloat
,shoveFloat
,
8278 newWidth
,newHeight
,newDepth
,
8279 srcImage
,dstImage
,elementSize
,groupSize
,rowSize
,
8280 imageSize
,myswapBytes
);
8283 halveImage_float(cmpts
,newWidth
,newHeight
,srcImage
,dstImage
,
8284 elementSize
,rowSize
,groupSize
,myswapBytes
);
8287 case GL_UNSIGNED_BYTE_3_3_2
:
8288 halveImagePackedPixel3D(3,extract332
,shove332
,
8289 newWidth
,newHeight
,newDepth
,
8290 srcImage
,dstImage
,elementSize
,rowSize
,
8291 imageSize
,myswapBytes
);
8293 case GL_UNSIGNED_BYTE_2_3_3_REV
:
8294 halveImagePackedPixel3D(3,extract233rev
,shove233rev
,
8295 newWidth
,newHeight
,newDepth
,
8296 srcImage
,dstImage
,elementSize
,rowSize
,
8297 imageSize
,myswapBytes
);
8299 case GL_UNSIGNED_SHORT_5_6_5
:
8300 halveImagePackedPixel3D(3,extract565
,shove565
,
8301 newWidth
,newHeight
,newDepth
,
8302 srcImage
,dstImage
,elementSize
,rowSize
,
8303 imageSize
,myswapBytes
);
8305 case GL_UNSIGNED_SHORT_5_6_5_REV
:
8306 halveImagePackedPixel3D(3,extract565rev
,shove565rev
,
8307 newWidth
,newHeight
,newDepth
,
8308 srcImage
,dstImage
,elementSize
,rowSize
,
8309 imageSize
,myswapBytes
);
8311 case GL_UNSIGNED_SHORT_4_4_4_4
:
8312 halveImagePackedPixel3D(4,extract4444
,shove4444
,
8313 newWidth
,newHeight
,newDepth
,
8314 srcImage
,dstImage
,elementSize
,rowSize
,
8315 imageSize
,myswapBytes
);
8317 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
8318 halveImagePackedPixel3D(4,extract4444rev
,shove4444rev
,
8319 newWidth
,newHeight
,newDepth
,
8320 srcImage
,dstImage
,elementSize
,rowSize
,
8321 imageSize
,myswapBytes
);
8323 case GL_UNSIGNED_SHORT_5_5_5_1
:
8324 halveImagePackedPixel3D(4,extract5551
,shove5551
,
8325 newWidth
,newHeight
,newDepth
,
8326 srcImage
,dstImage
,elementSize
,rowSize
,
8327 imageSize
,myswapBytes
);
8329 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
8330 halveImagePackedPixel3D(4,extract1555rev
,shove1555rev
,
8331 newWidth
,newHeight
,newDepth
,
8332 srcImage
,dstImage
,elementSize
,rowSize
,
8333 imageSize
,myswapBytes
);
8335 case GL_UNSIGNED_INT_8_8_8_8
:
8336 halveImagePackedPixel3D(4,extract8888
,shove8888
,
8337 newWidth
,newHeight
,newDepth
,
8338 srcImage
,dstImage
,elementSize
,rowSize
,
8339 imageSize
,myswapBytes
);
8341 case GL_UNSIGNED_INT_8_8_8_8_REV
:
8342 halveImagePackedPixel3D(4,extract8888rev
,shove8888rev
,
8343 newWidth
,newHeight
,newDepth
,
8344 srcImage
,dstImage
,elementSize
,rowSize
,
8345 imageSize
,myswapBytes
);
8347 case GL_UNSIGNED_INT_10_10_10_2
:
8348 halveImagePackedPixel3D(4,extract1010102
,shove1010102
,
8349 newWidth
,newHeight
,newDepth
,
8350 srcImage
,dstImage
,elementSize
,rowSize
,
8351 imageSize
,myswapBytes
);
8353 case GL_UNSIGNED_INT_2_10_10_10_REV
:
8354 halveImagePackedPixel3D(4,extract2101010rev
,shove2101010rev
,
8355 newWidth
,newHeight
,newDepth
,
8356 srcImage
,dstImage
,elementSize
,rowSize
,
8357 imageSize
,myswapBytes
);
8364 __GLU_SWAP_IMAGE(srcImage
,dstImage
);
8366 if (newWidth
> 1) { newWidth
/= 2; rowSize
/= 2;}
8367 if (newHeight
> 1) { newHeight
/= 2; imageSize
= rowSize
* newHeight
; }
8368 if (newDepth
> 1) newDepth
/= 2;
8370 /* call tex image with srcImage untouched since it's not padded */
8371 if (baseLevel
<= level
&& level
<= maxLevel
) {
8372 gluTexImage3D(target
, level
, internalFormat
, newWidth
, newHeight
,
8373 newDepth
,0, format
, type
, (void *) srcImage
);
8377 glPixelStorei(GL_UNPACK_ALIGNMENT
, psm
.unpack_alignment
);
8378 glPixelStorei(GL_UNPACK_SKIP_ROWS
, psm
.unpack_skip_rows
);
8379 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, psm
.unpack_skip_pixels
);
8380 glPixelStorei(GL_UNPACK_ROW_LENGTH
, psm
.unpack_row_length
);
8381 glPixelStorei(GL_UNPACK_SWAP_BYTES
, psm
.unpack_swap_bytes
);
8382 glPixelStorei(GL_UNPACK_SKIP_IMAGES
, psm
.unpack_skip_images
);
8383 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT
, psm
.unpack_image_height
);
8385 free(srcImage
); /*if you get to here, a srcImage has always been malloc'ed*/
8386 if (dstImage
) { /* if it's non-rectangular and only 1 level */
8390 } /* gluBuild3DMipmapLevelsCore() */
8393 gluBuild3DMipmapLevels(GLenum target
, GLint internalFormat
,
8394 GLsizei width
, GLsizei height
, GLsizei depth
,
8395 GLenum format
, GLenum type
,
8396 GLint userLevel
, GLint baseLevel
, GLint maxLevel
,
8401 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8402 if (rc
!= 0) return rc
;
8404 if (width
< 1 || height
< 1 || depth
< 1) {
8405 return GLU_INVALID_VALUE
;
8408 if(type
== GL_BITMAP
) {
8409 return GLU_INVALID_ENUM
;
8412 levels
= computeLog(width
);
8413 level
= computeLog(height
);
8414 if (level
> levels
) levels
=level
;
8415 level
= computeLog(depth
);
8416 if (level
> levels
) levels
=level
;
8419 if (!isLegalLevels(userLevel
,baseLevel
,maxLevel
,levels
))
8420 return GLU_INVALID_VALUE
;
8422 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8423 width
, height
, depth
,
8424 width
, height
, depth
,
8426 userLevel
, baseLevel
, maxLevel
,
8428 } /* gluBuild3DMipmapLevels() */
8431 gluBuild3DMipmaps(GLenum target
, GLint internalFormat
,
8432 GLsizei width
, GLsizei height
, GLsizei depth
,
8433 GLenum format
, GLenum type
, const void *data
)
8435 GLint widthPowerOf2
, heightPowerOf2
, depthPowerOf2
;
8438 int rc
= checkMipmapArgs(internalFormat
,format
,type
);
8439 if (rc
!= 0) return rc
;
8441 if (width
< 1 || height
< 1 || depth
< 1) {
8442 return GLU_INVALID_VALUE
;
8445 if(type
== GL_BITMAP
) {
8446 return GLU_INVALID_ENUM
;
8449 closestFit3D(target
,width
,height
,depth
,internalFormat
,format
,type
,
8450 &widthPowerOf2
,&heightPowerOf2
,&depthPowerOf2
);
8452 levels
= computeLog(widthPowerOf2
);
8453 level
= computeLog(heightPowerOf2
);
8454 if (level
> levels
) levels
=level
;
8455 level
= computeLog(depthPowerOf2
);
8456 if (level
> levels
) levels
=level
;
8458 return gluBuild3DMipmapLevelsCore(target
, internalFormat
,
8459 width
, height
, depth
,
8460 widthPowerOf2
, heightPowerOf2
,
8462 format
, type
, 0, 0, levels
,
8464 } /* gluBuild3DMipmaps() */
8466 static GLdouble
extractUbyte(int isSwap
, const void *ubyte
)
8468 isSwap
= isSwap
; /* turn off warnings */
8470 assert(*((const GLubyte
*)ubyte
) <= 255);
8472 return (GLdouble
)(*((const GLubyte
*)ubyte
));
8473 } /* extractUbyte() */
8475 static void shoveUbyte(GLdouble value
, int index
, void *data
)
8477 assert(0.0 <= value
&& value
< 256.0);
8479 ((GLubyte
*)data
)[index
]= (GLubyte
)value
;
8480 } /* shoveUbyte() */
8482 static GLdouble
extractSbyte(int isSwap
, const void *sbyte
)
8484 isSwap
= isSwap
; /* turn off warnings */
8486 assert(*((const GLbyte
*)sbyte
) <= 127);
8488 return (GLdouble
)(*((const GLbyte
*)sbyte
));
8489 } /* extractSbyte() */
8491 static void shoveSbyte(GLdouble value
, int index
, void *data
)
8493 ((GLbyte
*)data
)[index
]= (GLbyte
)value
;
8494 } /* shoveSbyte() */
8496 static GLdouble
extractUshort(int isSwap
, const void *uitem
)
8501 ushort
= __GLU_SWAP_2_BYTES(uitem
);
8504 ushort
= *(const GLushort
*)uitem
;
8507 assert(ushort
<= 65535);
8509 return (GLdouble
)ushort
;
8510 } /* extractUshort() */
8512 static void shoveUshort(GLdouble value
, int index
, void *data
)
8514 assert(0.0 <= value
&& value
< 65536.0);
8516 ((GLushort
*)data
)[index
]= (GLushort
)value
;
8517 } /* shoveUshort() */
8519 static GLdouble
extractSshort(int isSwap
, const void *sitem
)
8524 sshort
= __GLU_SWAP_2_BYTES(sitem
);
8527 sshort
= *(const GLshort
*)sitem
;
8530 assert(sshort
<= 32767);
8532 return (GLdouble
)sshort
;
8533 } /* extractSshort() */
8535 static void shoveSshort(GLdouble value
, int index
, void *data
)
8537 assert(0.0 <= value
&& value
< 32768.0);
8539 ((GLshort
*)data
)[index
]= (GLshort
)value
;
8540 } /* shoveSshort() */
8542 static GLdouble
extractUint(int isSwap
, const void *uitem
)
8547 uint
= __GLU_SWAP_4_BYTES(uitem
);
8550 uint
= *(const GLuint
*)uitem
;
8553 assert(uint
<= 0xffffffff);
8555 return (GLdouble
)uint
;
8556 } /* extractUint() */
8558 static void shoveUint(GLdouble value
, int index
, void *data
)
8560 assert(0.0 <= value
&& value
<= (GLdouble
) UINT_MAX
);
8562 ((GLuint
*)data
)[index
]= (GLuint
)value
;
8565 static GLdouble
extractSint(int isSwap
, const void *sitem
)
8570 sint
= __GLU_SWAP_4_BYTES(sitem
);
8573 sint
= *(const GLint
*)sitem
;
8576 assert(sint
<= 0x7fffffff);
8578 return (GLdouble
)sint
;
8579 } /* extractSint() */
8581 static void shoveSint(GLdouble value
, int index
, void *data
)
8583 assert(0.0 <= value
&& value
<= (GLdouble
) INT_MAX
);
8585 ((GLint
*)data
)[index
]= (GLint
)value
;
8588 static GLdouble
extractFloat(int isSwap
, const void *item
)
8593 ffloat
= __GLU_SWAP_4_BYTES(item
);
8596 ffloat
= *(const GLfloat
*)item
;
8599 assert(ffloat
<= 1.0);
8601 return (GLdouble
)ffloat
;
8602 } /* extractFloat() */
8604 static void shoveFloat(GLdouble value
, int index
, void *data
)
8606 assert(0.0 <= value
&& value
<= 1.0);
8608 ((GLfloat
*)data
)[index
]= value
;
8609 } /* shoveFloat() */
8611 static void halveImageSlice(int components
,
8612 GLdouble (*extract
)(int, const void *),
8613 void (*shove
)(GLdouble
, int, void *),
8614 GLint width
, GLint height
, GLint depth
,
8615 const void *dataIn
, void *dataOut
,
8616 GLint elementSizeInBytes
,
8617 GLint groupSizeInBytes
,
8618 GLint rowSizeInBytes
,
8619 GLint imageSizeInBytes
,
8623 int halfWidth
= width
/ 2;
8624 int halfHeight
= height
/ 2;
8625 int halfDepth
= depth
/ 2;
8626 const char *src
= (const char *)dataIn
;
8627 int padBytes
= rowSizeInBytes
- (width
* groupSizeInBytes
);
8630 assert((width
== 1 || height
== 1) && depth
>= 2);
8632 if (width
== height
) { /* a 1-pixel column viewed from top */
8633 /* printf("1-column\n");*/
8634 assert(width
== 1 && height
== 1);
8637 for (ii
= 0; ii
< halfDepth
; ii
++) {
8640 for (cc
= 0; cc
< components
; cc
++) {
8642 double extractTotals
[BOX2
][4];
8645 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8646 extractTotals
[1][cc
]= (*extract
)(isSwap
,(src
+imageSizeInBytes
));
8648 /* average 2 pixels since only a column */
8650 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
8651 * totals[RED]/= 2.0;
8653 for (kk
= 0; kk
< BOX2
; kk
++) {
8654 totals
[cc
]+= extractTotals
[kk
][cc
];
8656 totals
[cc
]/= (double)BOX2
;
8658 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8660 src
+= elementSizeInBytes
;
8663 /* skip over to next group of 2 */
8664 src
+= rowSizeInBytes
;
8667 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8668 assert(outIndex
== halfDepth
* components
);
8670 else if (height
== 1) { /* horizontal slice viewed from top */
8671 /* printf("horizontal slice\n"); */
8674 for (ii
= 0; ii
< halfDepth
; ii
++) {
8675 for (jj
= 0; jj
< halfWidth
; jj
++) {
8678 for (cc
= 0; cc
< components
; cc
++) {
8681 double extractTotals
[BOX4
][4];
8683 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8684 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8685 (src
+groupSizeInBytes
));
8686 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8687 (src
+imageSizeInBytes
));
8688 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8689 (src
+imageSizeInBytes
+groupSizeInBytes
));
8691 /* grab 4 pixels to average */
8693 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8694 * extractTotals[2][RED]+extractTotals[3][RED];
8695 * totals[RED]/= 4.0;
8697 for (kk
= 0; kk
< BOX4
; kk
++) {
8698 totals
[cc
]+= extractTotals
[kk
][cc
];
8700 totals
[cc
]/= (double)BOX4
;
8702 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8705 src
+= elementSizeInBytes
;
8708 /* skip over to next horizontal square of 4 */
8709 src
+= groupSizeInBytes
;
8713 src
+= rowSizeInBytes
;
8716 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8717 assert(outIndex
== halfWidth
* halfDepth
* components
);
8719 else if (width
== 1) { /* vertical slice viewed from top */
8720 /* printf("vertical slice\n"); */
8721 assert(height
!= 1);
8723 for (ii
= 0; ii
< halfDepth
; ii
++) {
8724 for (jj
= 0; jj
< halfHeight
; jj
++) {
8727 for (cc
= 0; cc
< components
; cc
++) {
8730 double extractTotals
[BOX4
][4];
8732 extractTotals
[0][cc
]=(*extract
)(isSwap
,src
);
8733 extractTotals
[1][cc
]=(*extract
)(isSwap
,
8734 (src
+rowSizeInBytes
));
8735 extractTotals
[2][cc
]=(*extract
)(isSwap
,
8736 (src
+imageSizeInBytes
));
8737 extractTotals
[3][cc
]=(*extract
)(isSwap
,
8738 (src
+imageSizeInBytes
+rowSizeInBytes
));
8740 /* grab 4 pixels to average */
8742 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8743 * extractTotals[2][RED]+extractTotals[3][RED];
8744 * totals[RED]/= 4.0;
8746 for (kk
= 0; kk
< BOX4
; kk
++) {
8747 totals
[cc
]+= extractTotals
[kk
][cc
];
8749 totals
[cc
]/= (double)BOX4
;
8751 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8754 src
+= elementSizeInBytes
;
8758 /* skip over to next vertical square of 4 */
8759 src
+= rowSizeInBytes
;
8762 src
+= imageSizeInBytes
;
8765 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8766 assert(outIndex
== halfHeight
* halfDepth
* components
);
8769 } /* halveImageSlice() */
8771 static void halveImage3D(int components
,
8772 GLdouble (*extract
)(int, const void *),
8773 void (*shove
)(GLdouble
, int, void *),
8774 GLint width
, GLint height
, GLint depth
,
8775 const void *dataIn
, void *dataOut
,
8776 GLint elementSizeInBytes
,
8777 GLint groupSizeInBytes
,
8778 GLint rowSizeInBytes
,
8779 GLint imageSizeInBytes
,
8784 /* a horizontal/vertical/one-column slice viewed from top */
8785 if (width
== 1 || height
== 1) {
8788 halveImageSlice(components
,extract
,shove
, width
, height
, depth
,
8789 dataIn
, dataOut
, elementSizeInBytes
, groupSizeInBytes
,
8790 rowSizeInBytes
, imageSizeInBytes
, isSwap
);
8796 int halfWidth
= width
/ 2;
8797 int halfHeight
= height
/ 2;
8798 int halfDepth
= depth
/ 2;
8799 const char *src
= (const char *) dataIn
;
8800 int padBytes
= rowSizeInBytes
- (width
*groupSizeInBytes
);
8803 for (dd
= 0; dd
< halfDepth
; dd
++) {
8804 for (ii
= 0; ii
< halfHeight
; ii
++) {
8805 for (jj
= 0; jj
< halfWidth
; jj
++) {
8808 for (cc
= 0; cc
< components
; cc
++) {
8811 double totals
[4]; /* 4 is maximum components */
8812 double extractTotals
[BOX8
][4]; /* 4 is maximum components */
8814 extractTotals
[0][cc
]= (*extract
)(isSwap
,src
);
8815 extractTotals
[1][cc
]= (*extract
)(isSwap
,
8816 (src
+groupSizeInBytes
));
8817 extractTotals
[2][cc
]= (*extract
)(isSwap
,
8818 (src
+rowSizeInBytes
));
8819 extractTotals
[3][cc
]= (*extract
)(isSwap
,
8820 (src
+rowSizeInBytes
+groupSizeInBytes
));
8822 extractTotals
[4][cc
]= (*extract
)(isSwap
,
8823 (src
+imageSizeInBytes
));
8825 extractTotals
[5][cc
]= (*extract
)(isSwap
,
8826 (src
+groupSizeInBytes
+imageSizeInBytes
));
8827 extractTotals
[6][cc
]= (*extract
)(isSwap
,
8828 (src
+rowSizeInBytes
+imageSizeInBytes
));
8829 extractTotals
[7][cc
]= (*extract
)(isSwap
,
8830 (src
+rowSizeInBytes
+groupSizeInBytes
+imageSizeInBytes
));
8834 /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
8835 * extractTotals[2][RED]+extractTotals[3][RED]+
8836 * extractTotals[4][RED]+extractTotals[5][RED]+
8837 * extractTotals[6][RED]+extractTotals[7][RED];
8838 * totals[RED]/= 8.0;
8840 for (kk
= 0; kk
< BOX8
; kk
++) {
8841 totals
[cc
]+= extractTotals
[kk
][cc
];
8843 totals
[cc
]/= (double)BOX8
;
8845 (*shove
)(totals
[cc
],outIndex
,dataOut
);
8849 src
+= elementSizeInBytes
; /* go to next component */
8852 /* skip over to next square of 4 */
8853 src
+= groupSizeInBytes
;
8855 /* skip past pad bytes, if any, to get to next row */
8858 /* src is at beginning of a row here, but it's the second row of
8859 * the square block of 4 pixels that we just worked on so we
8860 * need to go one more row.
8868 src
+= rowSizeInBytes
;
8871 src
+= imageSizeInBytes
;
8874 /* both pointers must reach one byte after the end */
8875 assert(src
== &((const char *)dataIn
)[rowSizeInBytes
*height
*depth
]);
8876 assert(outIndex
== halfWidth
* halfHeight
* halfDepth
* components
);
8878 } /* halveImage3D() */